Exam-style problems with solutions
Given this code:
What is the value of:
*ptr*(ptr + 1)*(ptr - 1)ptr[1]*ptr: arr + 2 points to
arr[2], so *ptr = 30
*(ptr + 1): Points to arr[3], so
*(ptr + 1) = 40
*(ptr - 1): Points to arr[1], so
*(ptr - 1) = 20
ptr[1]: Same as *(ptr + 1) =
40
Key: ptr + n moves n * sizeof(int) bytes. Array
indexing ptr[n] is syntactic sugar for *(ptr + n).
Draw the stack layout after this code executes:
Key: Parameters saved from registers (rdi=a, rsi=b) to stack. Variables
accessed via [rbp - (slot+1)*8].
What is sizeof(struct Point) and why?
Why? int requires 4-byte alignment. After each
char, 3 padding bytes are added.
Better layout (12 bytes):
This code doesn't swap the values. Why not, and how do you fix it?
swap receives copies of x and y, not the originals. Changes to
a and b don't affect x and y.
This code has a memory leak. Find and fix it:
If some_error_condition() is true, we return without freeing buffer
or closing f!
Better pattern: Use goto cleanup for centralized resource
cleanup.
Is this code safe? Why or why not?
msg is a local array on the stack. When the function returns, that stack space
is invalid. The returned pointer is dangling.
What is the value in rax after this sequence?
Note: imul with one operand multiplies
rax × operand and stores result in rdx:rax.
What does this code return?
Pattern: This is how
if (a < b) return 1; else return 0; compiles.
What's on the stack after this sequence? (Assume rsp starts at 0x1000)
Key: Stack grows downward (push decrements rsp). Pop reads value then increments rsp.
What is the value of rax after this sequence?
Key insight: Writing to a 32-bit register (eax)
zeros the upper 32 bits of the 64-bit register (rax)!
Which of these x86-64 instructions are VALID?
Rule: At most ONE operand can be a memory reference!
What is the signed decimal value of this 8-bit binary: 0b11111101?
Quick trick: MSB (bit 7) contributes -128. Add remaining 1-bits as positive.
Draw the AST for: 1 + 2 * 3 - 4 / 2
Evaluation (post-order):
2 * 3 = 61 + 6 = 74 / 2 = 27 - 2 = 5Result: 5
Draw the AST for: (1 + 2) * (3 - 4)
Evaluation:
1 + 2 = 33 - 4 = -13 * (-1) = -3Result: -3
Draw the AST for: 10 - 5 - 2
Correct evaluation: (10 - 5) - 2 = 5 - 2 =
3
Wrong evaluation: 10 - (5 - 2) = 10 - 3 =
7
Key: Subtraction and division are left-associative!
Trace the stack for these instructions:
Original expression: (5 + 3) * 2 = 16
Trace execution (a=slot 0, b=slot 1):
Original code:
Array of size N has indices 0 to N-1. Use i < N not
i <= N.
What's 2 + 3 * 4?
(2 + 3) * 4 = 202 + (3 * 4) = 14Memorize: * / % before + -. When in doubt, use parentheses.
Signed: jl, jg, jle, jge | Unsigned:
jb, ja, jbe, jae
Always use cqo before idiv to sign-extend
rax into rdx:rax.
Variable at slot 0:
[rbp - 0] = [rbp] (that's saved rbp!)[rbp - 8]Variable at slot N → [rbp - (N+1) * 8]