1. At the start of the main function, both %edi and %rsi are saved in the invocation record. Why is the 32 bit version of the di register and the 64 bit version of the si register saved? Why not 32 or 64 bit versions of both? Answer: The di register has the first parameter, int argc, and int is 32 bits. The si register has the second parameter, char **argc, and a pointer is 64 bits. 2. What does the instruction "cmpl $0x1,-0x14(%rbp)" do? What registers or memory does this instruction change? Answer: The cmp instruction only affects the condition code registers, ZF, CF, OF, and SF. 3. What registers or memory are consulted by the "jg 777 " instruction to determine whether the jump should be taken or not? Answer: The jg instruction looks at ZF, OF, and SF. 4. What is the condition, using C notation, evaluated by the two instructions in question 2 and 3, that causes a jump to the end of the if statement if true? Answer: argc>1 (which is equivalent to argc>=2, or !(argc<2) since argc is an int) 5. In the instruction "jmp 7d9 ", what registers or memory are consulted to determine if the jump should be taken or not? Answer: The jump is always taken... nothing is consulted. 6. At offset 804, the instruction "jmp 881 " is an unconditional jump. Why does the C compiler jump over the body of the loop (the instructions between offset 806 and 87e) when first entering the loop? Answer: In C, the condition is tested before the first execution of the body of the loop. The compiler put the condition test at instructions with offsets 881 and 885. 7. If the condition "w>1" is true at offset 885, what value does the instruction at 885 put in the %rip register? (Express your answer as an offset, since the actual address depends on where the UNIX loader puts your instructions in memory.) Answer: 806 8. What C code is implemented with the instruction at offset 89b, "movl $0x1f,-0x4(%rbp)" Answer: i=31; // The initialization statement in the for statement from line 36 9. At offset 8ac, the instruction "sar %cl,%edx" performs a shift arithmetic right on the value in %edx. Why did the compiler choose an arithmetic instead of a logical shift instruction? Answer: The "n" variable is a signed integer, and "sar" propagates the sign bit. Note: I didn't look closely enough at the X86 expansion, and didn't realize how complicated the code was. In fact, the GCC compiler has performed an "optimization". The C code has the expression (n&1<>i)&1. If the ith bit of n is zero, the result is the same... all zeroes. But if the ith bit of n is a one, the result is actually different; the original expression results in a 1 in the ith position, but the "optimized" expression will have a 1 in the rightmost bit position. However, the test and jump instructions that follow don't care where the 1 is, so the "optimized" expression yields the same results as the original. I have no clue why GCC chose to make this optimization. Since this was more complicated than expected, don't take more than one point off for the combination of questions 9 and 10. 10. The "test %eax,%eax" instruction at offset 8b3 is followed by the "jump equal", "je 8be " instruction at offset 8b5. What condition (expressed in C notation) is being checked by these two lines of code? Answer: (n&1<