Method: Use the debugger to get runtime information about assembly programs.
Preparation: Click here to get gdb. Instructions to get gdb.
gdb commands summary. Link to full gdb commands
Files to use: partSums.c, partSums.s, partSumsDriver.c
Hand-in: gdb.txt, decode.txt
1. On your Raspberry Pi open Firefox and go to the lab2a page from the syllabus. Click on the link above to download the gdb debugger, according to the directions.
2. In an xterm, go to your Desktop and create a lab2a directory. cd to lab2a.
3. In Firefox, go to the lab2a page and download the three files to use to the lab2a directory.
4. Look over the partSums.c code and the partSums.s code in emacs. This code calculates the partial sums for the array, placing them back into the array.
5. Compile the code with debugger information by typing: gcc-6 -g partSumsDriver.c partSums.s. Then start the debugger on the program by typing: gdb a.out.
6. To list the program in the debugger, type list (or l) twice, each one lists another 10 lines of the c program with line numbers. The assembly program will not be listed. You may want to stretch your xterm window longer and wider to show things more fully.
7. Set break points in the c program at the line number just before the call to partSums: br linenumber. Also set the debugger to log everything you do by typing: set logging on. All the output you see will be saved in a file gdb.txt.
6. Type run to run the program to the breakpoint, then type si to single step through the assembly code. Each si will show the next instruction to execute.
7. When the assembly instruction showing is sub, get the address of that instruction by typing: info line. Then print out the memory for 11 lines from there
by typing: x/11xw address. Type address in hex like 0xabc000, just as the info line gave it to you. Be sure to tuse the start address for the instruction. You should then see 11 hex words from memory that are the machine instructions for 11 lines of assembly code. We will analyze these later.
8. Set a breakpoint at the address by typing: br *address. Be sure to include the "*" and use the address as in step 7.
9. Display the current contents of the registers by typing: info registers. Which registers are used for parameters? Find the parameter that is the base address of the array. Then print out memory from that address to show the doublewords in memory by typing: x/10dg address, where address was found in the appropriate register (should be something like 0xfffff...). You should see the values that were in the array set up in partSumsDriver.c.
10. Single step in assembly (use si) to the next instruction, cbz. Use info registers again and check the value in the register used in the cbz instruction. Should the code branch or not?
11. Continue to the next breakpoint by typing: cont (or c). Then check how the registers have changed, by using info registers and how the data memory has changed by typing the same x/10dg address as in step 9. Are the values in memory what you expect? Single step (si) to cbz and check the register value as in step 10. Do we branch?
12. Repeat step 11.
13. You may continue (cont) a few times without printing out the registers and data memory. Then check the registers and data memory.
14. Continue until you expect to take the cbz branch. Check the registers and data memory. Is the array what you expect?
15. Then single step to see if you are correct. Note the value in register X30 (it should not change during the process). Single step until you are back in the main function. You should see the address of the current assembly instruction displayed along with the c instruction that it is part of. Is this what you expect? Use info registers to display the registers. Where do you find the value (the final sum) returned by the function? Finally, type: c to continue and the c-code will print out the array. (Note: if you continue at the wrong time and do not single step back into the c-code, you can start again and after setting the breakpoint at sub, cont enough tomes to get back to the end, show the registers and data memory and single step (si) until back in the c-code.)
16. You may do this on the Rapberry Pi, or you may mail the gdb.txt file to yourself and do it on your regular computer. Near the beginning of the gdb.txt file find the listing of program memory from the sub instruction onward. You should see four hex numbers per line. Copy these to a new file, call it decode.txt, and arrange them one per line. For each of these hex numbers do the following on each line:
a. Write out the 32 bit binary machine instruction. Look at the leftmost 11 bit and translate back into hex (3 bits then 4 bits and 4 bits).
b. Using the green card, find this hex opcode in the instruction listing, and write the assembly instruction.
c. Then, using the formats given in class and at the lower right of the green card, separate the fields and indicate the registers used and the immediate values, completing this instruction. (Note: do not try to figure our the immediate for the lsl instruction, it is coded in a weird way.)
d. You have just "disassembled" the machine code back to the assembly code.
14. Hand in your gdb.txt file and your decode.txt file by emailing them to the instructor.