1. Due Date
Due by 11:59 pm, Tuesday, October 21, 2025
You will work with your assigned partner on this lab: Lab 5 Partners
Please review our guidelines for working with partners: working with partners, etiquette and expectations.
2. Lab 5 Overview and Goals
In this lab we will gain expereince writing assembly code.
2.1. Lab Goals
-
Gain experience translating C code to x86_64 Assembly to enhance your understanding of underlying data structure access, and function calls.
-
Understand in more detail the mechanics of C "pass-by-pointer" style parameters and function calls.
2.2. Overview of Lab Requirements
This lab consists of two parts
-
Part 1: Implement the
sum
function in Assembly code (insum.s
) and test and debug it by making calls to it from thesum_prog.c
C program. -
Part 2: Implement the
compare
function in Assembly code (incompare.s
) and test it out in thecompare_prog.c
C program.
3. Lab Starting Point Code
3.1. Getting Your Lab Repo
Both you and your partner should clone your Lab 5 repo into
your cs31/Labs
subdirectory:
-
get your Lab 5 ssh-URL from the CS31 GitHub Organization. The repository to clone is named Lab5-userID1-userID2 where the two user names match that of you and your Lab 5 lab partner.
-
cd into your
cs31/Labs
subdirectory:$ cd ~/cs31/Labs $ pwd
-
clone your repo
$ git clone [the ssh url to your your repo] $ cd Lab5-userID1-userID2
There are more detailed instructions about getting your lab repo from the "Getting Lab Starting Point Code" section of the Using Git for CS31 Labs page. To make changes, follow the directions in the "Sharing Code with your Lab Partner" section of the Using Git for CS31 Labs page.
3.2. Starting Point files
The starting point files for this lab are:
$ ls
Makefile README.adoc compare.s compare_prog.c sum.s sum_prog.c
Details:
-
README.adoc
contains some instructions to you. -
sum.s
,sum_prog.c
: Part 1 files are -
compare.s
,compare_prog.c
-
Makefile:
A Makefile simplifies the process of compiling your program. You do not need to edit this file. We’ll look at these in more detail later in the course, if you are interested, take a look at Section 7 for more information aboutmake`
and makefiles.
4. Part 1: Sum Function
For this part, you will implement a sum
function in x86_64 in sum.s
,
which has the starting point of this function. Then sum.s
is compiled
into a program (sum_prog
) that you can use test your code.
The starting point handles the stack set-up and function return. As a
result, you just need to implement the x86_64 translation of the function
body. See the comments in sum.s
about where on the stack there is space
for local variables, and where the parameter n
is located.
The C function you will implement in x86_64 is:
/* computes the sum of the values 1-n
* n: an int value
* returns: the sum of values from 1-n, or -1 if n is not positive
*/
long sum(long n) {
long i, res;
if( n <= 0 ) {
return -1;
}
res = 0;
for(i=1; i <= n; i++) {
res = res + i;
}
return res;
}
The program sum_prog.c
makes a call to this sum function (do not modify
sum_prog.c
, but you can open it in vim
to see what it is doing).
4.1. Compiling and Running
The files for This part are:
-
The
sum.s
file contains the starting point x86_64 code for the sum function that you will complete for Part 1. Your solution should be implemented in this file. -
sum_prog.c
: a main program for testing your sum implementation, Do not modify this program.
The Makefile
is set up to compile both the x86_64 sum.s
and
sum_prog.c
files into an executable named sum_prog
that you can use
to run and test your x86_64 implementation.
$ make # compiles sum_prog from sum.s and sum_prog.c
$ ./sum_prog
4.2. Sample Output
When run, the sum_prog
reads in user input for the
value n
, that is passed as a parameter to your sum
function, and then prints out the result (you can see
this main control flow in the sum_prog.c
file’s main
function, which you should not modify). Some sample
inputs and outputs of the program are provided below:
$ ./prog
This program computes the sum of 1-N
Enter an value for n: 10
The sum of 1 to 10 is 55
$ ./prog
This program computes the sum of 1-N
Enter an value for n: 50
The sum of 1 to 50 is 1275
4.3. Requirements
-
Your x86_64 implementation of the
sum
function should be added to thesum.s
starting point file. -
Your code should be well-commented.
-
Do not edit
sum_prog.c
, but looking at it invim
might help you understand how yoursum
function is being called. -
Your solution must include a loop. It is well known that the sum of the first
n
positive integers isn*(n+1)/2
, but you can not use that in your answer.
4.4. Tips
-
Write C goto versions of the sum function, the
if
andfor
loop parts in particular, to help you with the translations of those parts. -
Remeber that instructions can access at most one memory location and one register in x86_64, e.g., mov -8(%rbp), %rax is allowed but mov -8(%rbp), -16(%rbp) is not allowed. If you need to do something with two memory locations, you will need to move one of them into a register first.
-
Try adding a little bit of x86_64 code to
sum.s
at a time, then compile and test it out by runningprog
, and add some more. Parts of that you test out do not even have to be parts of the solution, for example:-
First see if you can just return the value of n.
-
Next, see if you can initialize res to 0 and return the value of res.
-
Next, try the if statement, and test passing positive and negative values to see if your function returns -1 when n is not positive.
-
Then try implementing the
for loop
.
-
-
To help debug, trace through the instructions on paper, drawing memory contents and register contents as you go.
-
You can also test out some code snippets using the assembly visualization tool to check if your logic is correct without having to compile and run your entire program.
-
Use Ctrl-C to kill a running program stuck in an infinite loop.
5. Part 2: Compare Function
For this part, you will implement a compare
function in x86_64 in
compare.s
, that conditionally changes the value pointed to by x. Then
compare.s
is compiled into a program (compare_prog
) that you can use
test.
The starting point code handles the stack set-up and function return. As
a result, you just need to implement the x86_64 translation of the
function body. See the comments in compare.s
about where on the stack
there is space for local variables, and where the parameters *x and y are
located.
/* * This function compares two values, and sets the first * to the value of the second if the value of the second * is less than the first. It uses "pass by pointer" * to modify the argument's value in this case. * * x: pointer to long value that may change * y: long value to compare to the value that x points to * returns: no return value (pointer param might modify argument) */ void compare(long *x, long y);
This function takes one long int pointer, x, passed by pointer (the parameter points to the storage location of its argument), and one long int, y, passed by value.
If the <value pointed to by x> is greater than <y>, set the <value pointed by x> to be <y>. Otherwise, it should be unchanged by the call.
The program compare_prog.c
makes a call to this sum function (do not
modify compare_prog.c
, but you can open it in vim
to see what it is
doing).
To write compare.s
, you will have to write out the function definition
for compare() in C, then write its go-to equivalent, followed by the
x86_64 Assembly version.
5.1. Compiling and Running
The files for this part are:
-
The
compare.s
file contains the starting point x86_64 code for the compare function that you will complete for Part 2. Your solution should be implemented in this file. -
compare_ prog.c
: a main program for testing your compare implementation, Do not modify this program.
The Makefile
is set up to compile both the x86_64 compare.s
and
compare_prog.c
files into an executable named compare_prog
that you
can use to run and test your x86_64 implementation.
$ make # compiles compare_prog from compare.s and compare_prog.c
$ ./compare_prog <num1> <num2>
5.2. Sample Output
When run, the compare_prog
takes in two numbers from the
command line (<num1> and <num2>). They are passed as parameters
to the compare
function, <num1> is passed by pointer and <num2>
is passed by value. The program then prints out the values of <num1>
and <num2> before and after the call to compare
(you can see
this main control flow in the compare_prog.c
file’s main
function, which you should not modify). Some sample
inputs and outputs of the program are provided below:
$ ./compare_prog -10 1
Before compare(): a = -10, b = 1
After compare(): a = -10, b = 1
$ ./compare_prog 200 199
Before compare(): a = 200, b = 199
After compare(): a = 199, b = 199
$ ./compare_prog 650 777
Before compare(): a = 650, b = 777
After compare(): a = 650, b = 777
5.3. Requirements
-
Your x86_64 implementation of the
compare
function should be added tocompare.s
starting point file. -
Your code should be well-commented.
-
Do not edit
compare_prog.c
, but looking at it invim
might help you understand how yourcompare
function is being called. -
Your solution must include any one of the conditional or unconditional jump instructions, as needed.
5.4. Tips
-
Write C goto versions of the compare function first to help you with the translations of those parts.
-
The parameter values of x and y are on stored in the registers, x is in %rdi and y is in %rsi. Note that x is a long int pointer and y is a %long int.
-
Remeber that instructions can access at most one memory location and one register in x86_64, e.g., mov -8(%rbp), %rax is allowed but mov -8(%rbp), -16(%rbp) is not allowed. If you need to do something with two memory locations, you will need to move one of them into a register first.
-
Draw a picture of the registers, including where parameter and argument values are and trace through the instruction execution to help you determine what x86_64 instructions you need to use to implement
compare
. -
To help debug, trace through the instructions on paper, drawing memory contents and register contents as you go.
-
You can also test out some code snippets using the assembly visualization tool to check if your logic is correct without having to compile and run your entire program.
-
Use Ctrl-C to kill a running program stuck in an infinite loop.
6. Submit
Please remove any debugging output prior to submitting.
To submit your code, commit your changes locally using git add
and
git commit
. Then run git push
while in your lab directory.
Only one partner needs to run the final git push
, but make sure both
partners have pulled and merged each others changes.
Also, it is good practice to run make clean
before doing a git add and
commit: you do not want to add to the repo any files that are built by gcc
(e.g. executable files). Included in your lab git repo is a .gitignore
file
telling git to ignore these files, so you likely won’t add these types of files
by accident. However, if you have other gcc
generated binaries in your repo,
please be careful about this.
Here are the commands to submit your solution in the sorter.c file (from
one of you or your partner’s ~/cs31/Labs/Lab5-userID1-userID2
subdirectory):
$ make clean
$ git add compare_prog.c sum_prog.c compare.s sum.s
$ git commit -m "correct and well commented Lab5 solution"
$ git push
You could also use this git add
shorthand to add all .c
and .s
:
$ git add *.s *.c
Verify that the results appear (e.g., by viewing the the repository on CS31-f25). You will receive deductions for submitting code that does not run or repos with merge conflicts. Also note that the time stamp of your final submission is used to verify you submitted by the due date, or by the number of late days that you used on this lab, so please do not update your repo after you submit your final version for grading.
If you have difficulty pushing your changes, see the "Troubleshooting" section and "can’t push" sections at the end of the Using Git for CS31 Labs page. And for more information and help with using git, see the git help page.
At this point, you should submit the required TBA[Lab 5 Questionnaire] (each lab partner must do this).
Lab 5 Survey
After submitting your complete Lab 5 solution, you should submit the required TBA[Lab 5 Questionnaire] (each lab partner must do this). Note this link is typically live a day or two before the due date through several days after the due date. Please submit within one week of the lab due date.
7. Handy Resources
General Lab Resources
-
Class EdSTEM page for questions and answers about lab assignment
Assembly Resource
-
Refer to the Week 6 weekly lab page
-
ASM Visualizer (choose
x86_64
ISA) -
Section 3.2 and Section 3.5 of textbook (assembly debugging, print, display, info and x commands)
-
GDB for Assembly (from the gdb Guide). (assembly debugging and x command)
-
Tools for examining phases of compiling and running C programs