Hello, dear friend, you can consult us at any time if you have any questions, add WeChat: daixieit


ECS 50: Programming Assignment #3

Winter Quarter 2022


1 Changelog

You should always refer to the latest version of this document.

● v.1: Initial version.


2 General Submission Details

Partnering on this assignment is prohibited. If you have not already, you should read the section on academic misconduct in the syllabus.

This assignment is due the night of Sunday, 02/06. Gradescope will say 12:30 AM on Monday, 02/07, due to the “grace period”(as described in the syllabus). Be careful about relying on the grace period for extra time; this could be risky.


3 Purpose of This Assignment

● To increase your comfortability with writing basic programs, including conditional statements, iterative statements,

and loops, in x86-64 assembly code.

* This content is protected and may not be shared, uploaded, or distributed.



4 Reference Environment

The autograder, which is talked about at the end of this document, will compile and run your code in a Linux environment, specifically Ubuntu 18.  That means that you should make sure your code compiles and behaves properly in a sufficiently similar environment. The CSIF is one such environment. Each student should have remote access to the CSIF, and I expect that in-person access to the CSIF (which is in the basement of Kemper Hall) will be restored once lectures are back in person.  (I talk more about the CSIF in the syllabus.)

Do not assume that because your code compiles on an  insufficiently  similar environment  (e.g.   directly on your Mac laptop), it will compile on the Linux environment used by the CSIF.


5 Programming Problems

5.1 Restrictions

In this assignment, all code must be x86-64 assembly code.  You must write this assembly code yourself. That is, you cannot write C/C++ code and then use gcc  -S or g++  -S to compile that C/C++ code into assembly code to submit; we will not accept that, and we will easily be able to tell if you submitted compiler-generated assembly code.

5.2 Tips

You may find it helpful to write a solution to each part using a high-level programming language such as C and then – without using the  -S flag of gcc  or any tool-generated assembly code – come up with the corresponding assembly code. This is not something that I would always recommend on future assignments, but it might help for getting started with assembly code.

Where possible, you should minimize accesses to memory.  I will not check that you did this, but it is good form to minimize memory accesses and make optimal use of registers (because this speeds up your program), and you may have exam questions that require an understanding of how to make optimal use of registers in assembly code.

Don’t be afraid to make extensive use of comments.  With assembly code in particular, it is easy to forget what line of code was doing what. If you end up writing a comment for every line of code, that really isn’t a bad thing either; I personally write a comment for at least every few lines.

Oh, and if you haven’t already, you should become comfortable with some sort of debugger, such as gdb . You already don’t have easy access to print statements while debugging assembly code, and if you think you can get by on making random changes to your code in order to fix your bugs, then you’re going to have a lot of fun on these remaining assignments.

5.3 Use of Registers

It usually does not matter which registers you choose to use.  However, there are situations in which you must choose specific registers or avoid certain ones.

One of those situations is when you call printf().  When you call printf() , the first six arguments go in the RDI, RSI, RDX, RCX, R8, and R9 registers. If your printf() call does not need six arguments, then do not use all six of the registers. For instance, if your printf()  call would only have two arguments (if written out in C), then you would just use the RDI and RSI registers.  Before you call printf(), make sure that the RAX register is set to 0, or else you will get a seemingly inexplicable crash when you call printf() .

printf() may modify the following registers without restoring them: RAX, RCX, RDX, RSI, RDI, R8 through R11. Thus, after you call printf() , you should expect the values in these registers to not be the same as they were before the call.

Lastly, do  not modify RBP or RSP. You’ll learn why soon.  Modifying these registers could mess up function calls, i.e. calling printf() .

5.4 File Organization

You will submit three files for this assignment:

● sum_within_range.s

● count_matches.s

● maxes.s

Each file is associated with an input file that contains the global variables, in order to make it easy for the autograder to change the values of the global variables.  For instance, associated with sum_within_range.s is input_sum_within_range.s. You’ll see what I mean when you look at the directions/examples for each specific part. Do not paste the provided global variables into the les you submit. For example, do not paste the contents of input_sum_within_range.s into your sum_within_range.s le. You are allowed to add your own global variables, e.g. for the printf() format strings.

5.5 General Remarks about the Problems

Do not worry about input validation / reacting to improper inputs in this assignment.

In this assignment, any use of the term “integer” refers to a 32-bit signed integer.

5.6 Part #1: Sum Within Range

File: sum_within_range.s

Write a program that iterates through an array of integers called arr and calculates the sum of all integers in the array that are between (inclusive) a lower boundary (given by the variable low) and an upper boundary (given by high).  (You may assume that low is always less than or equal to high.)  The program should print the sum out at the end.  The length of the array is given by the arrlen variable.

There will always be at least one value in the array that is between the lower boundary and the upper boundary.

Below is an example of how your program should behave. input_sum_within_range.s is provided on Canvas. In this example, the values in the array that are between low and high are 7, 12, and 5, and the sum of these values is 24.

1    $   cat   i n p u t _ s um _ w i t h i n _ r a n g e . s

2     . data

3

4     . global   arr ,   arrlen ,   low ,   high

5    arr :

6                    . long   7 ,   -8 ,   12 ,   5 ,   100 ,   4

7    arrlen :

8                    . long   6

9    low :

10                    . long   5

11    high :

12                    . long   15

13    $   gcc   -no - pie   - Wall   - Werror   s um _ w i t h i n _ r a n g e . s   i n p u t _ s um _ w i t h i n _ r a n g e . s   -o   s um _ w i t h i n _ r a n g e

14    $   ./ s um _ w i t h i n _ r a n g e

15    Sum :   24

5.7 Part #2: Count Matches

File: count_matches.s

In this program, you will deal with two arrays of integers (arr1 and arr2 , with their lengths given by arr1Len and arr2Len , respectively) and an integer target .

Your program should count/print the number of occurrences of target in each of the first and second arrays.

Below is an example of how your program should behave.  input_count_matches.s is provided on Canvas. In this example, 20 occurs three times in the first array and twice in the second array.

1    $   cat   i n p u t _ c o u n t _m a t c h e s . s                                                                                                                                                                                                  2     . data                                                                                                                                                                                                                                                        3

4     . global   arr1 ,   arr1Len ,   arr2 ,   arr2Len ,   target

5    arr1 :

6                    . long   10 ,   20 ,   30 ,   20 ,   40 ,   10 ,   20

7    arr1Len :

8                    . long   7

9    arr2 :

10                    . long   15 ,   20 ,   33 ,   15 ,   19 ,   20

11    arr2Len :

12                    . long   6

13    target :

14                    . long   20

15    $   gcc   -no - pie   - Wall   - Werror   co u nt _ma tc h es . s   i n p u t _ c o u n t _m a t c h e s . s   -o   c oun t_mat ches

16    $   ./ cou n t_m at ch e s

17    Number   of   matches   in   the   first   array :   3

18    Number   of   matches   in   the   second   array :   2

5.8 Part #3: Maxes

File: maxes.s

Write a program that iterates through an array of integers called arr and calculates/prints the max of all integers at odd indices and the max of all integers at even indices.

You may assume that the length of the array is always at least 2 and that all integers in the array are positive.

I imagine that some students will want to use an approach here that involves the modulo/remainder operator.  We will not go over how to do this during lecture, so you would have to look up how to do that.

Below is an example of how your program should behave. input_maxes.s is provided on Canvas. In this example, 20 is the max among the values that are at the even indices (5, 8, 20, 5), and 25 is the max among the values that are at the odd indices (14, 18, 25, 13).

1    $   cat   input_maxes . s