Assembly (x86-64, AArch64, RISC-V) Module 3
How a CPU runs your program interview questions
Interview questions on how a CPU runs your program: short warm-ups, then what each harder question tests, the first step of a good answer and its follow-ups.
Warm-up questions
Short questions with short answers, each answered in full.
-
Fresher to mid
What does the program counter do, and what happens to it when a branch is taken?
The program counter holds the address of the next instruction to fetch: rip on x86-64, pc on AArch64 and RISC-V. After each fetch the processor advances it by the instruction's length, so a straight-line RISC-V program steps forward 4 bytes at a time. A branch is an instruction whose job is to write the program counter: a taken conditional branch, an unconditional jump, a call and a return all set it to a new address, and the next fetch reads from there. That one mechanism is behind loops, if/else and function calls. No ordinary instruction may name the program counter as an operand, so you reach a nearby address through PC-relative forms such as lea [rip+..], adr and auipc instead.
From the lesson Fetch, decode, execute: the program counter
-
Fresher to mid
On x86-64, why does writing eax clear the top 32 bits of rax, while writing al leaves the rest of rax unchanged?
They are two separate rules, both in Intel's manual. A 32-bit operation (writing eax, ebx and so on) zero-extends its result into the full 64-bit register, clearing bits 63:32. An 8-bit or 16-bit operation (writing al or ax) writes only those low bits and leaves the rest of the register alone. So rax holding 0xDEADBEEFCAFEF00D becomes 0xDEADBEEFCAFEF011 after mov al, 0x11, but 0x0000000033333333 after mov eax, 0x33333333. The practical effect is a classic bug: build a 64-bit value in rax, then tweak the low half with a 32-bit op such as add eax, ecx, and the top half is gone. Use the 64-bit names when the value is 64 bits. AArch64 made the simpler choice: only x0 and w0, and a w0 write always clears the top half.
From the lesson Registers on x86-64, AArch64 and RISC-V
-
Fresher to mid
What is a virtual address, and why does every process get its own address space?
A virtual address is the address a program uses; the memory-management unit translates it to a physical address through page tables, a page at a time. Each process has its own page tables, so its virtual addresses are private: two processes can both use 0x400000 and map to different physical memory, and neither can touch the other's pages. That buys protection (permissions are per page, so code is executable but not writable and the unmapped page at address 0 makes a null dereference fault at once), isolation (a crash in one process cannot corrupt another), and flexibility (the kernel can place regions anywhere, back them on demand, swap them, and randomise their addresses with ASLR). The program is built position-independent so its PC-relative code runs wherever it lands.
From the lesson Memory and a process's address space
-
Fresher to mid
What is the difference between a fixed-length and a variable-length instruction encoding, and what does each buy?
Answered in the lesson Instruction encoding: fixed and variable
Questions with model answers
What each question tests, the first step of a good answer and the follow-ups to expect.
-
Mid to senior
Why do none of these ISAs let an ordinary instruction write the program counter, and how does PC-relative addressing let the same code run at any load address?
- What it tests
- Separating control-flow safety from position independence; naming the PC-relative forms; connecting them to ASLR and PIE rather than treating them as unrelated.
- First step
- Say the restriction keeps control flow in branches, jumps, calls and returns, so arithmetic cannot become a jump by accident. Then say PC-relative forms (lea [rip+..], adr/adrp, auipc) encode a distance from the current instruction, so the code resolves correctly wherever it loads.
- Follow-ups
-
- How does this connect to position-independent executables and ASLR?
- On x86-64, what does the linker actually fill into the four displacement bytes of a RIP-relative lea?
- RISC-V auipc gives the high 20 bits; how is the low 12 formed, and why two instructions?
From the lesson Fetch, decode, execute: the program counter
Model answer, Pro. Model answers open with any pass; prices are in the notice on this page.Opening the model answers with your pass…
Model answers open with any MySmartCoPilot pass.
- Pro pass · 1 week₹79$2.99
- 30 days₹179$5.99
- 1 year₹1,699$45
One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.
Passes can’t be bought right now, so the model answers can’t be opened at the moment. If you have a pass, enter your licence key.
It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).
In the answer:
- Model answer
- Common mistakes
- Rubric
- Variants
- about 2 minutes
-
Mid to staff
A modern core fetches ahead, predicts branches and executes out of order, yet the fetch-decode-execute model says one instruction at a time. Reconcile the two and say when the difference matters.
- What it tests
- Distinguishing the architectural contract from the microarchitecture; naming what is preserved (in-order result) versus changed (timing); giving a concrete case where the gap is visible.
- First step
- State that the core guarantees the architectural result matches in-order execution: it commits results in program order even though it computes them early and out of order. The parallelism changes timing, not what the program computes.
- Follow-ups
-
- Give a measurable case where the gap shows up (a dependency chain versus independent work).
- What is a branch misprediction costing, in terms of this model?
- How does this relate to reading assembly for correctness versus for performance?
From the lesson Fetch, decode, execute: the program counter
Model answer, Pro.In the answer:
- Model answer
- Common mistakes
- Rubric
- Variants
- about 2 minutes
-
Mid to senior
A 64-bit counter in hand-written x86-64 assembly keeps losing its high 32 bits after an update. Walk through how you would find and fix the bug, and say what the AArch64 port must watch for.
- What it tests
- Naming the 32-bit zero-extension rule as the cause; reading the disassembly to spot a 32-bit op on the counter; knowing AArch64 w-writes zero-extend too, so the same care applies.
- First step
- Suspect a 32-bit operation on the counter: an add eax, ... or mov eax, ... where rax was meant. Disassemble and look for 32-bit register names on the counter's register; switch them to the 64-bit names.
- Follow-ups
-
- Why does the zero-extension rule exist at all (hint: false dependencies)?
- Would the same bug appear on AArch64, and if so in which instructions?
- How would the track's register-integrity harness catch a related callee-saved bug?
From the lesson Registers on x86-64, AArch64 and RISC-V
Model answer, Pro.In the answer:
- Model answer
- Common mistakes
- Rubric
- Variants
- about 2 minutes
-
Mid to senior
A function written in assembly returns correct results alone but corrupts its caller after a call. How do reserved and callee-saved registers explain this, and how would you prevent it?
- What it tests
- Distinguishing caller-saved from callee-saved; naming the platform-reserved registers (x18, gp, tp); describing a prologue/epilogue that saves and restores; using the register-integrity harness.
- First step
- Suspect the function clobbers a callee-saved register (rbx, x19..x28, s0..s11) or a reserved one (x18 on AArch64, gp/tp on RISC-V) without saving it. Add a prologue that saves the callee-saved registers it uses and an epilogue that restores them.
- Follow-ups
-
- Which registers are callee-saved under System V, AAPCS64 and the RISC-V psABI?
- Why is x18 special, and what breaks if you use it on Apple or Windows?
- How does filling callee-saved registers with known values before a call catch this?
From the lesson Registers on x86-64, AArch64 and RISC-V
Model answer, Pro.In the answer:
- Model answer
- Common mistakes
- Rubric
- Variants
- about 2 minutes
-
Mid to senior
Code that aligns buffers to a hard-coded 4096-byte page works on a Linux x86-64 server but misbehaves on an Apple-silicon Mac. Explain the cause and the fix.
- What it tests
- Naming the 16 KiB page on Apple silicon (and 4/16/64 KiB builds on Linux arm64); reading the page size at run time; explaining what mmap rounding and alignment get wrong with a stale constant.
- First step
- Say the page size is not a fixed 4096: Apple silicon uses 16384. Replace the constant with a run-time query, sysconf(_SC_PAGESIZE), AT_PAGESZ from the auxiliary vector, or getpagesize(), and align and round with that.
- Follow-ups
-
- Why does a one-byte mmap still cost a whole page, and how big is that page on Apple silicon?
- Which run-time sources give the page size on Linux and on macOS?
- Round 100000 bytes up to whole pages at 4 KiB and at 16 KiB; why do the page counts differ?
From the lesson Memory and a process's address space
Model answer, Pro.In the answer:
- Model answer
- Common mistakes
- Rubric
- Variants
- about 2 minutes
-
Mid to staff
Explain, defensively, what ASLR and position-independent executables protect against, what they rely on to work, and what they do not fix.
- What it tests
- Framing ASLR as raising the cost of relying on fixed addresses; connecting it to PC-relative PIE code; being honest that it does not fix memory-safety bugs; no exploitation steps.
- First step
- Say ASLR randomises where regions load so an attacker cannot depend on a fixed address; it works because the program is position-independent (PC-relative code), so it runs at any address. Add that it raises cost, it does not remove the underlying bug.
- Follow-ups
-
- Why must the executable be position-independent for ASLR to randomise its code?
- What limits ASLR (entropy, leaks, partial randomisation) in general terms?
- How does this connect to example outputs that print addresses as 0x…?
From the lesson Memory and a process's address space
Model answer, Pro.In the answer:
- Model answer
- Common mistakes
- Rubric
- Variants
- about 2 minutes
-
Mid to senior
Given the 32-bit word 0x05d00893, decode it to an assembly instruction by hand, explaining your method, and say why the same by-hand approach is harder on x86-64.
- What it tests
- Reading the opcode to pick the format, then the fields; getting addi a7, zero, 93 (li a7, 93); explaining that x86-64's variable length and prefixes/ModRM make length and fields position-dependent.
- First step
- Take the low 7 bits as the opcode (0010011 = OP-IMM, an I-type), then read rd[11:7], funct3[14:12], rs1[19:15] and the 12-bit imm[31:20]. That gives addi a7, zero, 93, which is li a7, 93.
- Follow-ups
-
- How would you decode a compressed (2-byte) RISC-V instruction such as 4529?
- Why can you not read x86-64 fields at fixed bit positions the way you can on RISC-V?
- What role does the ModRM byte play when you decode an x86-64 instruction by hand?
From the lesson Instruction encoding: fixed and variable
Model answer, Pro.In the answer:
- Model answer
- Common mistakes
- Rubric
- Variants
- about 2 minutes
-
Senior to staff
You are advising on the instruction encoding for a new ISA. Argue the trade-offs between a fixed-length and a variable-length design, and where a compressed extension fits.
- What it tests
- Weighing decoder complexity and parallel fetch against code density and cache pressure; naming the large-constant and branch-range cost of fixed width; placing a C-style extension as a density compromise.
- First step
- Frame it as decoder simplicity and parallel fetch (fixed) versus code density and instruction-cache footprint (variable). Then note fixed width costs extra instructions for large constants and far branches, which a compressed extension partly recovers.
- Follow-ups
-
- How does fixed width help a wide superscalar front end specifically?
- What does code density buy in the instruction cache, and when does it matter most?
- Why might RISC-V keep a fixed base and add an optional C extension rather than going fully variable?
From the lesson Instruction encoding: fixed and variable
Model answer, Pro.In the answer:
- Model answer
- Common mistakes
- Rubric
- Variants
- about 2 minutes
All Assembly (x86-64, AArch64, RISC-V) interview questions · The Assembly (x86-64, AArch64, RISC-V) track