CSCI 2021 Project 3: Assembly Coding and Debugging
Hello, dear friend, you can consult us at any time if you have any questions, add WeChat: daixieit
CSCI 2021 Project 3 : Assembly Coding and Debugging
Due : 1 1 :59pm Wed 22-Mar-2023 on Gradescope
Approximately 3.0-4.0% of total grade
Projects are ind iv idual work : no collaboration with other students is allowed. Seek help from course staff if you get stuck for too long.
CODE/TEST DISTRIBUTION : p3-code.z ip
VIDEO OVERVIEW : https ://youtu.be/b iLVZb4VzU8
CHANGELOG :
Wed Mar 15 09 :55 :4 1 AM CDT 2023
The Manual Inspection Criteria for Problem 1 has been adjusted so that each function
implementation has 10 points of credit for a total of 60 points for Problem 1. Fr i Mar 3 1 1 :02 : 18 PM CST 2023
Fixed a typo in the code outline for clock_updat_asm.s which included a wrong function name. Added an overview video.
Table of Contents
3. Problem 1 : Clock Display Assembly Functions
3.2. General Cautions when coding Assembly
3.4. Structure of clock_update_asm.s
3.8. Grading Criteria for Problem 1
4. Problem 2 : The Binary Bomb
4.3. Machines on which bombs run
4.5. Scoring and Scoreboard (40%)
4.6. WARNING on Downloading Multiple Bombs
This project will feel somewhat familiar in that it is nearly identical to the preceding project : there is a coding problem and a puzzle-solving problem. The major change is that everything is at the assembly level :
Problem 1 re-works the LCD Clock functions from the previous project in x86-64 Assembly rather than C
Problem 2 involves analyzing a binary executable to provide it with the correct input to "defuse" the executable much like the previous project's Puzzlebox problem
Working with assembly will get you a much more acquainted with the low-level details of the x86-64 platform and give you a greater appreciation for "high-level" languages (like C).
Download the code pack linked at the top of the page. Unzip this which will create a project folder. Create new files in this folder. Ultimately you will re-zip this folder to submit it.
File State Notes
Makefile |
Provided |
Problem 1 Build file |
clock.h |
Provided |
Problem 1 header file |
clock_main.c |
Provided |
Problem 1 main() function |
clock_sim.c |
Provided |
Problem 1 clock simulator functions |
clock_update_asm.s |
CREATE |
Problem 1 Assembly functions, re-code C in x86-64, ma in f ile to ed it for problem 1 |
clock_update.c |
CREATE |
Problem 1 C functions, COPY from Project 2 or see a staff member to discuss |
test_clock_update.c |
Testing |
Problem 1 testing program for clock_update_asm.c |
test_clock_update.org |
Testing |
Problem 1 testing data file |
test_hybrid.org |
Testing |
Problem 1 testing data file for mixed C/Assembly |
testy |
Testing |
Problem 1 test running script |
bomb_download.sh |
Provided |
Problem 2 script used to download a bomb from the server |
bombNN.zip |
Download |
Problem 2 Debugging problem, download from server or use bomb_download.sh |
bombNN/ |
Directory |
Created by unzip bombNN.zip and contains the below files |
bombNN/bomb.c |
Unpack |
Problem 2 main() for bomb |
bombNN/bomb |
Unpack |
Problem 2 Executable to debug : this is the important one |
bombNN/README |
Unpack |
Problem 2 Describes "owner" of the bomb |
input.txt |
Edit |
Problem 2 Input for bomb, fill this in to defuse stages |
3 Problem 1 : Clock Display Assembly Functions
The functions in this problem are identical to a previous project in which code to support an LCD clock display was written. These functions are :
int set_tod_from_ports (tod_t *tod)
Retrieves value TIME_OF_DAY_PORT and converts this to number of seconds from the beginning of the day with rounding via bit shifts and masking. Then sets the fields of the struct pointed
to by tod to have the correct hours, minutes, seconds, and AM/PM indication. int set_d isplay_from_tod (tod_t tod, int *d isplay)
Given a tod_t struct, reset and alter the bits pointed to by display to cause a proper clock display.
int clock_update ()
Update global CLOCK_DISPLAY_PORT using the TIME_OF_DAY_PORT. Call the previous two functions.
The big change in this iteration will be that the funct ions must be wr itten in x86-64 assembly code. As C functions each of these is short, up to 85 lines maximum. The assembly versions will be somewhat longer as each C line typically needs 1-4 lines of assembly code to implement fully. Coding these functions in assembly give you real experience writing working assembly code and working with it in combination with C.
The code setup and tests are mostly ident ical for this problem as for the previous C version of the problem. Refer to original Clock LCD Display Problem description for a broad overview of the simulator and files associated with it.
As discussed in class, one can generate assembly code from C code with appropriate compiler flags. This can be useful for getting oriented and as a beginning to the code your assembly versions of the functions. However, this exercise is about writing assembly yourself to gain a deeper understanding of it.
Code that is clearly comp iler-generated w ith no hand cod ing w ill rece ive 0 cred it.
No credit will be given on manual inspection
Penalties will be assessed for Automated Tests which lower credit to 0
Do not let that dissuade you from looking at compiler-generated assembly code from you C solution to the functions. Make sure that you take the following steps which are part of the manual inspection criteria.
Base your Assembly code on your C code
The files to be submitted for this problem include
clock_update.c : C version of the functions
clock_update_asm.s : Assembly version of the functions
Graders may examine these for a correspondence between to the algorithm used in the C version to the Assembly version. Compiler generated assembly often does significant re-arrangements of assembly code with many intermediate labels that hand-written code will not have.
If you were not able to complete the C funct ions for the Project 2 or were not conf ident in your solut ions, see a course staff member who w ill help you get them up and runn ing qu ickly.
Annotate your Assembly Thoroughly
Comment your assembly code A LOT. While good C code can be quite self-explanatory with descriptive variable names and clear control structures, assembly is rarely so easy to understand. Include clear commentary on your assembly. This should include
Subdividing functions into smaller blocks with comments describing what the blocks accomplish. Descriptions of which "variables" from the C side are held in which registers.
Descriptions of most assembly lines and their effect on the variables held in the registers. Descriptions of any data such as bitmasks stored in the assembly code.
Use informative label names like .ROUNDING_UP to convey further meaning about what goals certain positions in code are accomplishing.
Use D iv is ion
While it is a slow instruction that is cumbersome to set up, using idivX division instruction is the most human-readable means to compute several results needed in the required functions. Compiler generated code uses many tricks to avoid integer division so a lack of idivX instructions along this line will be a clear sign little effort has been put into the assembly code.
3.2 General Cautions when coding Assembly
1. Get your editor set up to make coding assembly easier. If you are using VS Code, the following video will show you how to install an extension to do syntax highlighting and block comment/uncomment operations in assembly : https://youtu.be/AgmXUFOEgIw
2. Be disciplined about your register use : comment what "variables" are in which registers as it is up to you to keep track. The #1 advice from past students to future students is "Comment the Crap out of your assembly code" on this project.
3. Be Careful with constants : forgetting a $ in constants will lead to a bare, absolute memory address which will likely segfault your program. Contrast :
# rax = 0
# rax = *(0) : segfault
# bare 0 is memory address 0 - out of bounds
Running your programs, assembly code included, in Valgrind can help to identify these problems. In Valgrind output, look for a line number in the assembly code which has absolute memory addresses or a register that has an invalid address.
4. Recognize that in x86-64 function parameters are passed in registers for up to 6 arguments. These are arranged as follows
1. rdi / edi / di (arg 1)
2. rsi / esi / si (arg 2)
3. rdx / edx / dx (arg 3)
4. rcx / ecx / cx (arg 4)
5. r8 / r8d / r8w (arg 5)
6. r9 / r9d / r9w (arg 6)
and the specific register corresponds to how argument sizes (64 bit args in rdi, 32 bit in edi, etc). The functions you will write have few arguments so they will all be in registers.
5. Use registers sparingly. The following registers (64-bit names) are "scratch" registers or "caller save." Functions may alter them freely (though some may contain function arguments).
rax rcx rdx rdi rsi r8 r9 r10 r11 # Caller save registers
No special actions need to be taken at the end of the function regarding these registers except that rax should contain the function return value.
Remaining registers are "callee save" : if used, their original values must be restored before returning from the function.
rbx rbp r12 r13 r14 r15 # Callee save registers |
This is typically done by pushing the callee registers to be used on the stack, using them, them popping them off the stack in reverse order. Avoid this if you can (and you probably can in our case).
6. Be careful to adjust the stack pointer using pushX/popX or subq/addq . Keep in mind the stack must be aligned to 16-byte boundaries for function calls to work correctly. Above all, don't treat rsp as a general purpose register.
For reference, here is a picture that appears in the lecture slides that summarizes the names and special uses for the registers in x86-64.
2023-03-18