Contents
Dates.............................................................................................................................................................1
Early: Tuesday, 26-March-2024 at 11:58 PM........................................................................................1
On Time: Thursday, 28-March-2024 at 11:58 PM ................................................................................1
Late Cutoff: Friday, 29-March-2024 at 11:58 PM .................................................................................1
Lab 5: Assembler in Two Functions...............................................................................................................1
The Two Functions and Three Shims............................................................................................................2
Analyze..........................................................................................................................................................3
Middle...........................................................................................................................................................3
Output...........................................................................................................................................................5
For atest:...................................................................................................................................................5
For lab5: ....................................................................................................................................................5
GDB ...............................................................................................................................................................5
Bonus ............................................................................................................................................................6
Register Bonus..........................................................................................................................................6
Main Bonus...............................................................................................................................................6
Register Allocation........................................................................................................................................6
Required Stuff...............................................................................................................................................7
Comments.....................................................................................................................................................7
Readme .........................................................................................................................................................7
Submission....................................................................................................................................................7
Dates
There are no prototypes for assembler labs. It is a very good idea to build a little, test a little as you go.
Early: Tuesday, 26-March-2024 at 11:58 PM
On Time: Thursday, 28-March-2024 at 11:58 PM
Late Cutoff: Friday, 29-March-2024 at 11:58 PM
Lab 5: Assembler in Two Functions
Lab 5 introduces:
• Assembler programming
• Calling functions
• Loops
• Decisions
• Arrays
• Pointers
• Register allocation
• Stack details
The short form of what goes in in lab 5 is: Search an array for a value, return its address (or NULL if not
found). Along the way, track the largest and smallest values. Do this using two functions that you write
and some supporting functions that will be given to you.
The Two Functions and Three Shims
Here are the signatures of the two functions you will write. You will write them in assembler. Your code
will follow all conventions we have gone over. Do not write any C code for this lab. No code that you
write will directly call these two functions.
int *analyze(int value, int count, int array[], int *min_ptr, int *max_ptr);
int *middle( int value, int count, int array[]);
These functions will not be called directly. Instead two “shims” will fit between the caller and the
function called. They have the same signatures as your code. The shims do various forms of error
checking on your behalf.
int *a_shim(int value, int count, int array[], int *min_ptr, int *max_ptr);
int *m_shim( int value, int count, int array[]);
Note the mixture of 32 bit ints and 64 bit pointers. Your assembler code will need to be aware of sizes.
There is also a shim that goes between your code and printf. That shim is called print. Don’t sweat the
signature, you are calling it from assembler code. Do not call printf directly from your assembler code.
Use print just like you use printf.
All of the shims will detect if they were called with the stack meeting the 16-byte boundary rule. They
will print an error if the stack was not correctly aligned. Your code must follow the 16-byte alignment
rule.
These functions are tested by two different make targets. The attest target uses analyze and the lab5
target uses both analyze and middle. Do analyze first.
Analyze
After some initializations, analyze loops through the data in the array. Inside the loop, your code can
only do a single memory touch per location in the array to read the value. Store the current value in a
register. Then make some decisions:
• If the current value is larger than the maximum value, change the current maximum value to the
current value.
• If the current value is smaller than the minimum value, change the current minimum value to
the current value.
• If the current value is the one being sought, record the address so that it can be returned
After the loop is done, store the current min and max values in the correct memory locations. You code
can only touch those locations once each.
The initializations you will need before starting the loop include setting the return value to NULL. That
value clearly wants to be in a register and it is easy to figure out which one. Analyze makes no calls, so
register choices are straightforward. The current min and max values also will be stored in registers.
The middle function protects analyze from being passed an empty array, so you can use a value from the
array to initialize them both. This single additional memory touch is exempt from the rule that you can
only touch memory one time per location. In other words, total memory touches allowed are 1 for the
initialization, n for the reads in the loop, and 2 more to write the min and max. Setting up the stack
frame is not subject to this rule.
Analyze has 5 parameters and numerous things to keep track of whilst it does its work. There are 9
caller saved registers and you might run out of them. This is called register pressure, which can be a
global thing as it is here or a focused thing such as when rdi or rax need to used numerous different
ways in the same function. If you do run out of caller saved registers, resort to as many callee saved
registers as you need to keep everything in register. One bonus point is available if your code comes in
at 8 registers or fewer without resorting to inappropriate trickery like trying to stuff two C ints into the
upper and lower half of a 64 bit register.
Use the atest target in the makefile to test your code. You don’t need to write middle to write analyze.
Note that the array holds 32 bit C ints. Make sure that you address memory correctly.
Middle
The function middle exists mostly to teach you about callee saved registers, stack allocation, and just
what hog printf happens to be. Here is what middle should do, expressed in C code:
Do not transcribe this C code as C code!
The presence of a middle.c file is an indicator of academic misconduct. All mercy rule zeroes will be
reinstated without discussion and you can expect to wind up in front of CoAM. This is also true of
analyze; an analyze.c file will be treated as academic misconduct.
While we are here, the presence of GitHub co-pilot will also reinstate all mercy rule zeros and subject
all of your labs to careful examination with the intent of putting you in front of CoAM. Your lab scores
will be compared against your performance on the midterm and final exam coding problems.
Uninstall it now if you have it installed.
This code gives a clear an unambiguous set of requirements for what the function middle is expected to
do. Decompose the C code and the implications of every single line and use it to guide you as you write
your middle.s file. Doing this is practice for something you will be expected to do on the final exam.
Note that min and max are local variables. So is rval, but it is handled differently. The code takes the
address of min and max and passes that to analyze via a_shim. Registers do not have an address, so you
can’t store them in registers. None of the code ever exposes the address of rval, so it could go into a
register. You know where rval has to wind up by the time ret executes but look carefully before
deciding if it can stay there the whole time.
About this time you might review register allocation and the rules and guidance on what goes where
and why. Along with that a refresher on how we lay out the stack might be in order.
Use the lab5 target in the makefile to test your middle code. You will need a working analyze.
Middle is where you find out if your code follows the 16-byte alignment rule. If need be, you can grow
the stack using subtract. Be sure that you understand where to do this and by how much.
Output
You might get different pointer values.
For atest:
[kirby.249@cse-sl4 instructor]$ atest
Run: looking for -300 in 4 ints
Found -300 at 0x601058
Min is -400, max is -100
Run: looking for 0 in 5 ints
Did not find 0
Min is 16, max is 2048
Run: looking for 0 in 3 ints
Found 0 at 0x7ffdf2f79660
Min is -1, max is 1
For lab5:
[kirby.249@cse-sl4 instructor]$ lab5
lab5: looking for -300 in 4 ints
Middle: Looking for -300 in array of 4 ints
Middle: min is -400, max is -100, pointer is 0x601058
lab5: Found -300 at 0x601058
lab5: looking for 0 in 5 ints
Middle: Looking for 0 in array of 5 ints
Middle: min is 16, max is 2048, pointer is (nil)
lab5: Did not find 0
lab5: looking for 0 in 3 ints
Middle: Looking for 0 in array of 3 ints
Middle: min is -1, max is 1, pointer is 0x7ffc2886bfe0
lab5: Found 0 at 0x7ffc2886bfe0
GDB
The first time atest builds, run it under gdb and step through your code. Invoke tui reg general and
predict how each register will change before you take each step. Watch the values appear (in hex) in
the various registers. Go back to lab 1 and look at all of the gdb commands you were required to use
there and refresh them in your memory.
Probable bugs: Reversing the sense of a condition runs very high on the list!
Probable bugs: Mixing up two register names. This language is hot revenge for all those times you might
have slacked off and picked a less-than-stellar variable name when you had 32 characters at your
disposal.
DO NOT CALL PRINTF TO DEBUG! Trying to debug with printf is negative progress; it makes things
worse.
Imagine a grainy blue hologram: “Help me, GDB. You’re my only hope.”
https://www.youtube.com/watch?v=5cc_h5Ghuj4
We might need more than the ability to see what is in the registers, we might need to be able to
examine memory.
https://ftp.gnu.org/old-gnu/Manuals/gdb/html_node/gdb_55.html
Run gdb on atest. Set a breakpoint. Then issue the run command. Issue the tui reg general
command. Let’s look at memory. To do that, we need an address. The memory we want to examine is
in the stack. RSP and RBP point into the stack but in the case of analyze, so do rcx (min pointer) and r8
(max pointer). Let’s look at the int that rcx currently points to. Use this gdb command:
x/1iw $rcx
It examines 1 integer format “word” (which here means 32 bit) starting at the address in rcx. It will print
the address where it started, a colon, and then the value. The i between the 1 and the w makes sure
that it displays in decimal. Use g for the size “giant” and x for the format to look at an address in hex).
Poking at memory this way lets us see the values that get written at the end of the loop.
Bonus
Register Bonus
One bonus point for bringing in analyze in 8 caller saved registers.
Main Bonus
One bonus point for implementing the main function given in lab5.c in assembler. This takes some
doing. You do not have to implement the function run in assembler to get this point. Note that some of
the arrays are static and one is not. You will need to create main.s for your main function and use the
bonus target in the supplied makefile.
Register Allocation
Register allocation policy is graded.
One of the required functions is leaf-level and the other is not. This guides your register allocation
policy.
You really do want a firm grasp on register allocation before you take the final exam, so work it out here
and in lab 6. Before you write any code, figure out how many “variables” you will need and assign them
to registers of the appropriate type.
Required Stuff
All of your functions must create a stack frame upon entry and tear it down upon exit.
The first usage of any register in a function must have a comment telling what that register means. For
example:
xorq %rax, %rax # rax is both a subscript and return value at the same time.
This is usually near the top of your function. It is your pocket guide to the registers. In your comments
you should refer to the registers not by name but by what they mean.
Comments
Comment your code. Comments should say things that are not obvious from the code. In assembler
you almost always have something to say for every line of code. You could easily have more comment
lines than code lines. Comment what each register holds. Comment about how the operation has a
higher level meaning. Try to avid comments that say the exact same thing as the code – this might get
you points off.
Put your name and the assignment number in your initial comments. Also add the statement that says
that you wrote all of the code in the file (see below). Or you can forget it and get a zero on the lab.
Readme
As always, create a text README file, and submit it with your code. All labs require a readme file.
Include:
• Your name
• Hours worked on the lab
• Short description of any concerns, interesting problems, or discoveries encountered. General
comments about the lab are welcome.
Submission
No surprises here. Your zip file needs:
• A readme file
• All of your .s files
• Makefile, modified to add a zip target and your name
• The supplied files needed to make lab5 and atest build (plus any others for the second bonus)
Be sure that the zip target in the makefile self-tests all executables from the contents of the zip file. Any
zip file that fails to build gets a zero. Any makefile that doesn’t self-test the zip is marked late regardless
of when it was turned in.
Be sure to add this text to ALL of your .s files:
# BY SUBMITTING THIS FILE AS PART OF MY LAB ASSIGNMENT, I CERTIFY THAT
# ALL OF THE CODE FOUND WITHIN THIS FILE WAS CREATED BY ME WITH NO
# ASSISTANCE FROM ANY PERSON OTHER THAN THE INSTRUCTOR OF THIS COURSE
# OR ONE OF OUR UNDERGRADUATE GRADERS. I WROTE THIS CODE BY HAND,
# IT IS NOT MACHINE GENRATED OR TAKEN FROM MACHINE GENERATED CODE.
If you omit a required file, you get zero points.
If you fail to add the above comment you get zero points
If the make command as given generates any warnings or errors you get zero points
Every file you hand edit needs your name in it.
This is one of the easiest labs to get full marks on, don’t blow it.
版权所有:编程辅导网 2021 All Rights Reserved 联系方式:QQ:99515681 微信:codinghelp 电子信箱:99515681@qq.com
免责声明:本站部分内容从网络整理而来,只供参考!如有版权问题可联系本站删除。