Assembly (x86-64, AArch64, RISC-V) Module 4
Moving data: registers, memory and addresses interview questions
Interview questions on “Moving data: registers, memory and addresses”: warm-ups, then what each harder question tests and how a good answer starts.
Warm-up questions
Short questions with short answers, each answered in full.
-
Fresher to mid
What is an immediate, and why can't every instruction carry a full 64-bit one?
-
Fresher to mid
What does it mean that AArch64 and RISC-V are "load/store architectures", and how does x86-64 differ?
-
Fresher to mid
Why is modern code position-independent, and how does it reach a global without knowing its address?
A position-independent executable or shared library can be loaded at any base address, which lets address-space layout randomisation place it unpredictably and lets a shared library be mapped wherever there is room. Because the final address of a global is not fixed until load time, the code cannot hard-code it; instead it computes the address from the program counter. The distance from the current instruction to the data is known at link time, even though the absolute address is not. x86-64 uses a RIP-relative lea or memory operand; AArch64 uses adrp for the page base and add for the offset; RISC-V uses auipc for the upper bits and addi for the lower. The linker fills in the PC-relative displacement, so the same bytes work wherever the program lands.
From the lesson Static data and PC-relative addresses
-
Fresher to mid
What is an addressing mode, and why does
a[i].ytake one x86-64 operand but three RISC-V instructions?Answered in the lesson Addressing modes for arrays and structs
Questions with model answers
What each question tests, the first step of a good answer and the follow-ups to expect.
-
Mid to senior
A colleague says "x86-64 can put any constant in a register in one instruction, so immediate limits don't matter there." Where is that right, where is it wrong, and how does it change the code you write?
- What it tests
- Separating mov r64, imm64 from every other instruction's 32-bit immediate; naming the code-size and dependency cost; showing when you must load-then-operate instead of using an immediate directly.
- First step
- Grant the one case (mov r64, imm64 does carry a full 64-bit constant in ten bytes) and then name the limit: every other instruction, add, and, cmp, takes a 32-bit immediate sign-extended to 64 bits.
- Follow-ups
-
- How would you add 0x1_0000_0000 to rax, given add takes only a 32-bit immediate?
- Why might a compiler prefer
xor eax, eaxor a 32-bitmovover a 10-byte movabs? - Does the 32-bit immediate being sign-extended ever surprise you with a value you did not intend?
From the lesson Moving values and loading constants
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 senior
A RISC-V routine hand-writes
lui a0, 0x80000expecting a0 to hold 0x80000000, and a later comparison behaves as if a0 were negative. Explain what went wrong and give two fixes.- What it tests
- Explaining that lui sign-extends bit 31 on RV64; computing the actual value in a0; giving the li fix and a mask/shift fix; knowing why li avoids the trap.
- First step
- State the RV64 rule: lui treats its 20-bit field as signed and sign-extends bit 31, so 0x80000 << 12 becomes 0xFFFFFFFF80000000, a negative 64-bit value, not the positive 0x80000000 expected.
- Follow-ups
-
- What exact 64-bit value is in a0 after
lui a0, 0x80000on RV64? - Why does
li a0, 0x80000000not hit the same trap? - When would RV32 code with the same lui behave differently from RV64?
- What exact 64-bit value is in a0 after
From the lesson Moving values and loading constants
Model answer, Pro.In the answer:
- Model answer
- Common mistakes
- Rubric
- Variants
- about 2 minutes
-
Mid to senior
A service reads a sensor byte into a register and the value is sometimes a huge number near 2^64 instead of a small count. The byte load is the suspect. Walk through the bug and the fix.
- What it tests
- Identifying a signed load of unsigned data; computing the wrong value (0xFF to -1 to 0xFFFF...); matching the load to the C type; naming the ldrb/lbu vs ldrsb/lb pairs.
- First step
- Suspect a sign-extending load of an unsigned byte: ldrsb or lb on a value like 0xFF yields -1 (0xFFFFFFFFFFFFFFFF), not 255. The fix is a zero-extending load, ldrb or lbu.
- Follow-ups
-
- What value does 0xFF become under ldrsb versus ldrb?
- Which load would you pick for a C
signed charof -1, and why? - How could a unit test have caught this without the real sensor?
From the lesson Loads and stores of every width
Model answer, Pro.In the answer:
- Model answer
- Common mistakes
- Rubric
- Variants
- about 2 minutes
-
Senior to staff
Why would an ISA designer forbid memory operands in arithmetic (a load/store design) when x86-64 shows they are convenient? Argue both sides and say what it means for a compiler.
- What it tests
- Naming regular encoding, pipelining and explicit scheduling for load/store; naming density and instruction count for memory operands; connecting to register allocation and the micro-op split on x86-64.
- First step
- Frame it as regularity versus density: load/store makes every memory access a separate, uniformly encoded instruction the scheduler can reorder, while a memory operand is compact but hides a load inside an arithmetic op.
- Follow-ups
-
- How does x86-64 actually execute
add rax, [rdi]internally? - What does the load/store style ask of the register allocator?
- Why do AArch64 ldp/stp exist if the design keeps instructions simple?
- How does x86-64 actually execute
From the lesson Loads and stores of every width
Model answer, Pro.In the answer:
- Model answer
- Common mistakes
- Rubric
- Variants
- about 2 minutes
-
Mid to senior
Compare how x86-64, AArch64 and RISC-V form the address of a global variable in position-independent code. Why does one ISA need a single instruction and two need a pair?
- What it tests
- Naming lea [rip + x], adrp/add with @PAGE/@PAGEOFF, auipc/addi; explaining the fixed-width reason for the pair; connecting to the relocations each emits.
- First step
- Contrast the encodings: x86-64's variable-length lea holds a 32-bit RIP-relative displacement in one instruction, while AArch64 and RISC-V are fixed 32-bit, so a full address needs an upper part (adrp/auipc) and a lower part (add/addi).
- Follow-ups
-
- What do @PAGE and @PAGEOFF mean in the AArch64 pair?
- Why does RISC-V split the offset as a 20-bit high and a 12-bit low part?
- How does linker relaxation change the RISC-V pair?
From the lesson Static data and PC-relative addresses
Model answer, Pro.In the answer:
- Model answer
- Common mistakes
- Rubric
- Variants
- about 2 minutes
-
Fresher to mid
A program declares a 100 MB array of zeros and its executable is only a few kilobytes. A teammate is sure the file should be 100 MB. Explain who is right and why.
- What it tests
- Explaining .bss records size but stores no bytes; the loader zeroes pages at run time; contrasting with .data; noting that a non-zero initialiser would change the answer.
- First step
- The small file is correct: a zero-initialised array goes in .bss, which records only a size, and the loader allocates and zeroes the pages at start. .data, by contrast, would store every byte in the file.
- Follow-ups
-
- What changes if the array is initialised to non-zero values?
- Where does the memory actually come from at run time, and when?
- How would you confirm the section from the object with a tool?
From the lesson Static data and PC-relative addresses
Model answer, Pro.In the answer:
- Model answer
- Common mistakes
- Rubric
- Variants
- about 2 minutes
-
Mid to senior
Reading optimised x86-64, you see
leaused where no memory is accessed, sometimes instead of a multiply or a chain of adds. Why do compilers do this, and what are the limits?- What it tests
- Explaining lea computes base+index*scale+displacement into a register without a load; the scale 1/2/4/8 limit; three-operand non-destructive form; when a real imul or shift is still needed.
- First step
- Say what lea is: it runs the addressing-mode arithmetic (a scale by 1, 2, 4 or 8 plus up to two adds) and writes the result to a register without touching memory, giving a compact non-destructive multiply-and-add.
- Follow-ups
-
- How would you compute rax = rdi*5 with a single lea?
- Why can lea not multiply by 7 directly, and what do you do instead?
- Does lea set flags the way add does?
From the lesson Addressing modes for arrays and structs
Model answer, Pro.In the answer:
- Model answer
- Common mistakes
- Rubric
- Variants
- about 2 minutes
-
Mid to senior
On RISC-V an array-of-structs loop has extra instructions per iteration compared with x86-64. A teammate asks you to justify or remove them. What do you say?
- What it tests
- Explaining RISC-V's single base+offset mode forces explicit slli and add; naming the Zba sh3add shortcut and its availability; weighing regularity against instruction count.
- First step
- Explain the extra instructions are not waste: RISC-V has only offset(base), so scaling the index (slli) and adding the base (add) must be explicit; with the Zba extension a single sh3add replaces both.
- Follow-ups
-
- How do you check whether the target CPU supports Zba before using sh3add?
- Would hoisting the address computation out of the loop help here?
- What does this regularity buy RISC-V in decoding and verification?
From the lesson Addressing modes for arrays and structs
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