Chapter 11 Quiz: The Stack and Function Calls


Question 1. What does push rax actually do at the hardware level?

(A) RAX = [RSP]; RSP += 8 (B) RSP -= 8; [RSP] = RAX (C) [RSP] = RAX; RSP -= 8 (D) RAX = [RSP]; RSP -= 8


Question 2. In the System V AMD64 ABI, which register receives the 4th integer argument to a function?

(A) R8 (B) RCX (C) RDX (D) R9


Question 3. Which of the following registers must a function preserve (callee-saved) according to the System V AMD64 ABI?

(A) RAX, RCX, RDX (B) RBX, RBP, R12, R13, R14, R15 (C) RSI, RDI, R8, R9, R10, R11 (D) All general-purpose registers


Question 4. After call my_func, what is on top of the stack?

(A) The value of RAX before the call (B) The value of RBP before the call (C) The address of the instruction immediately following the call instruction (D) The first argument to my_func


Question 5. The LEAVE instruction is equivalent to:

(A) pop rbp; ret (B) mov rsp, rbp; pop rbp (C) pop rbp; mov rsp, rbp (D) sub rsp, rbp; pop rbp


Question 6. In the standard function prologue (push rbp; mov rbp, rsp; sub rsp, 32), local variables are accessed as:

(A) [rsp + N] where N is a positive offset (B) [rbp - N] where N is a positive offset (C) [rbp + N] where N is a positive offset (D) [rsp - N] where N is a positive offset


Question 7. The 16-byte stack alignment requirement before a call instruction exists because:

(A) The processor enforces 16-byte alignment for all memory accesses (B) SSE/SIMD instructions require 16-byte aligned memory operands, and function locals may need to be 16-byte aligned (C) The CALL instruction can only push to 16-byte aligned addresses (D) The return address must be 16-byte aligned


Question 8. What is the value of [rbp + 8] inside a normally-called function?

(A) The caller's RBP (B) The first function argument (C) The return address (D) The function's first local variable


Question 9. A function uses R12 internally. According to the System V ABI, what must the function do?

(A) Nothing — R12 is caller-saved and can be freely modified (B) Save R12 at function entry (e.g., push r12) and restore it before returning (C) Pass R12's value as a hidden argument (D) Zero R12 before using it


Question 10. In the System V ABI, what does AL contain when calling a variadic function like printf?

(A) The number of integer arguments (B) The number of XMM (floating-point) arguments (C) The size of the format string (D) The function's return type code


Question 11. A function has this prologue:

push rbp
mov  rbp, rsp
push rbx
push r12
sub  rsp, 16

What is RSP modulo 16 at the point of a nested call? Assume RSP was ≡ 8 (mod 16) at function entry (just after the CALL that invoked this function).

(A) 0 (correctly aligned) (B) 8 (misaligned) (C) 4 (misaligned) (D) Cannot be determined without knowing the initial RSP


Question 12. ret is equivalent to:

(A) pop rip (conceptually — RIP is not directly accessible) (B) jmp [rbp + 8] (C) pop rcx; jmp rcx (D) jmp [rsp]; add rsp, 8


Question 13. Which of the following is the correct way to access a function's 7th argument (beyond the 6 register arguments) inside the function?

(A) [rbp - 8] — first local variable slot (B) [rbp + 8] — that's the return address (C) [rbp + 16] — first stack argument (D) [rsp + 8] — first stack argument (without frame pointer)


Question 14. What is a "leaf function"?

(A) A function that uses only leaf node data structures (B) A function at the top of the call hierarchy (the main entry point) (C) A function that calls no other functions (D) A function with no local variables


Question 15. After a function returns with ret, what value does RSP have compared to its value just before the call instruction that invoked this function?

(A) RSP is 8 bytes lower (the return address was never popped) (B) RSP is exactly the same as before the call (C) RSP is 8 bytes higher (from the PUSH of RBP) (D) RSP may differ depending on how many registers were pushed


Question 16. (2 points) Write the NASM code to call long foo(long a, long b, long c) with arguments 100, 200, 300, and store the result in R13 (a callee-saved register). You are inside a function with a valid stack frame. Show the complete call sequence including any alignment fix if needed.


Question 17. Why does GCC use -fomit-frame-pointer by default at optimization levels O1 and above?

(A) It makes stack overflows impossible (B) RBP becomes available as a general-purpose register, saving 2 instructions (push + pop) per function call (C) It prevents buffer overflow exploits (D) It reduces binary size by eliminating LEAVE instructions


Question 18. The stack canary defense against buffer overflows:

(A) Prevents all types of stack overflow vulnerabilities (B) Places a random value between local variables and the saved RBP/return address, checked before ret (C) Makes the stack non-executable (D) Randomizes the location of local variables on the stack


Question 19. A function has sub rsp, 24 in its prologue. Is the stack 16-byte aligned for a nested call immediately after this? (Assume the standard prologue: push rbp; mov rbp, rsp; sub rsp, 24)

(A) Yes — 24 is a multiple of 8 (B) No — 24 is not a multiple of 16; need sub rsp, 32 (C) Yes — the push rbp already handled alignment (D) It depends on the caller's alignment


Question 20. The System V AMD64 ABI specifies that for functions returning a 128-bit integer, the result is returned in:

(A) XMM0 (128-bit SSE register) (B) RAX only (the upper 64 bits are discarded) (C) RDX:RAX (RDX = high 64 bits, RAX = low 64 bits) (D) RAX:RBX (by convention for the 128-bit case)