Assembly (x86-64, AArch64, RISC-V) Module 17
32-bit Arm: A32, Thumb-2, CPSR and IRQ/FIQ interview questions
Interview questions on “32-bit Arm: A32, Thumb-2, CPSR and IRQ/FIQ”: 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 jobs do r13, r14 and r15 have on a 32-bit Arm core?
Answered in the lesson 32-bit Arm: registers, CPSR and processor modes
-
Fresher to mid
Why does FIQ mode have its own r8 to r12 when IRQ mode does not?
Answered in the lesson 32-bit Arm: registers, CPSR and processor modes
-
Fresher to mid
What does the barrel shifter add to an A32 data-processing instruction, and what does it cost?
Answered in the lesson A32 data processing and the barrel shifter
-
Fresher to mid
In A32, what does the ! at the end of ldr r0, [r1, #4]! do, and how does ldr r0, [r1], #4 differ?
Answered in the lesson A32 branches, load-store and stack instructions
Questions with model answers
What each question tests, the first step of a good answer and the follow-ups to expect.
-
Fresher to senior
A bare-metal A32 program stops taking timer interrupts after the first one. Halted in a debugger, it shows CPSR = 0x600001D2 while the pc is inside the main loop, which should run in Supervisor mode with IRQs enabled. What does the value tell you, what bug would you suspect first, and how would you confirm it?
- What it tests
- Whether the candidate decodes the mode and mask bits exactly, links them to the way the handler left, and confirms the diagnosis from registers and code instead of guessing.
- First step
- Decode before you guess. The low bits 0x1D2 say IRQ mode with A, I and F set, so the main loop is running as if it were still inside the interrupt handler, with IRQs masked. Then ask which instruction could have brought the pc back to the loop without putting the CPSR back, and read the handler's last instruction and the SPSR of IRQ mode.
- Follow-ups
-
- Which other values in the debugger confirm the diagnosis, and what should each one show?
- What must the handler's last instruction do that an ordinary function return does not?
- The same symptom shows CPSR = 0x6000001F instead. How does your diagnosis change?
- How would you make this bug fail loudly in the next build?
From the lesson 32-bit Arm: registers, CPSR and processor modes
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 4 minutes
-
Mid to staff
A small A32 kernel runs each task in User mode and switches tasks from its timer IRQ handler. Which registers make up a task's saved state, which mode's copies are they, and how does privileged code read and write a task's User-mode sp and lr?
- What it tests
- Whether the candidate can turn the banking rules into a complete saved state, knows which copies the handler sees, and names a correct way to reach another mode's registers.
- First step
- List what the task can observe: every register its instructions name and every field of its CPSR. Then go through that list from inside IRQ mode and mark which names reach the task's own copies and which reach IRQ mode's. The ones that reach IRQ mode's copies are the hard part of the design.
- Follow-ups
-
- Why are r8 to r12 part of the saved state here, and would they be in a switch made from the FIQ handler?
- Where does the handler keep the state while it decides, and how much stack does that need?
- What changes if tasks give up the processor with an svc instead of being interrupted?
- How would you test the switch on a model before it runs on a board?
From the lesson 32-bit Arm: registers, CPSR and processor modes
Model answer, Pro.In the answer:
- Model answer
- Common mistakes
- Rubric
- Variants
- about 5 minutes
-
Mid to senior
A hand-written A32 routine keeps a 64-bit event counter in two registers and adds each batch's count to it. A colleague later added a flag-setting status test between the two instructions of the addition. Now the counter sometimes comes out exactly 2^32 short, but only for some status masks. How do you find the cause and fix it?
- What it tests
- Whether the candidate knows where C comes from after each kind of S instruction, can explain why only some masks break the chain, and fixes the order instead of the mask.
- First step
- Write down the flags after every instruction from the low-word add to the high-word add, for a case whose low words carry, and see which instruction writes C between them.
- Follow-ups
-
- Why do some masks break it and others not?
- Would tst instead of ands help?
- Which fix holds for every mask, and how do you prove it?
- Which other instructions could do the same damage?
From the lesson A32 data processing and the barrel shifter
Model answer, Pro.In the answer:
- Model answer
- Common mistakes
- Rubric
- Variants
- about 4 minutes
-
Mid to senior
Firmware must build for an older ARMv5TE core and for an Armv7-A core from the same assembly source. It loads masks, small counts and a few 32-bit configuration words. How do you write those loads, what does each choice cost on each core, and what can go wrong?
- What it tests
- Whether the candidate knows which constants fit one instruction, what the assembler does with the rest on each architecture, and the size, speed and reach costs of each way.
- First step
- Sort the constants by what can encode them: one instruction with a rotated byte or its complement, a 16-bit value, or a full 32-bit word. Then check which of those instructions each architecture has.
- Follow-ups
-
- What does the assembler do with ldr r0, =value on each core?
- How many bytes and memory reads does each way cost?
- Where must the literal pool go, and what happens in a long function?
- Why not use adr for an address?
From the lesson A32 data processing and the barrel shifter
Model answer, Pro.In the answer:
- Model answer
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Fresher to senior
A lab asks for x times 5, 7, 9, 15, 10 and 100 on a 32-bit Arm core without using MUL wherever one or two instructions can do it. Which instructions do you write, when is MUL still the better choice, and how do you check the results?
- What it tests
- Whether the candidate can turn constant multipliers into shift-and-add or reverse-subtract instructions, knows what MUL costs, and checks the results including the cases that overflow 32 bits.
- First step
- Write each constant as a sum or a difference of powers of two. A constant of the form 2^k + 1 or 2^k - 1 is one instruction with a shifted second operand.
- Follow-ups
-
- Which constants need two instructions, and which are better left to MUL?
- What does MUL cost on a classic core, and why does it depend on the operand?
- What happens when the product does not fit in 32 bits?
- What does a compiler do with the same multiplications?
From the lesson A32 data processing and the barrel shifter
Model answer, Pro.In the answer:
- Model answer
- Common mistakes
- Rubric
- Variants
- about 4 minutes
-
Mid to senior
You are tuning a hot A32 loop for an older Arm core with no branch predictor. Inside it, an if guards a block of instructions. How do you decide between condition suffixes and a branch around the block, and what numbers would you put on each choice?
- What it tests
- Whether the candidate prices both versions from the core's cycle timings, using the block's length and how often the condition holds, instead of assuming one form always wins.
- First step
- Count both versions for each outcome of the condition: instructions fetched, instructions skipped and branches taken. Then give each a cost from the core's published cycle timings, and average by how often the condition holds.
- Follow-ups
-
- Where is the break-even when the condition holds half the time?
- How does a branch predictor change the answer?
- What does each version cost in code size?
- When would you keep the branch even though it is slower?
From the lesson A32 branches, load-store and stack instructions
Model answer, Pro.In the answer:
- Model answer
- Common mistakes
- Rubric
- Variants
- about 4 minutes
-
Mid to senior
A hand-written A32 routine saves registers with stmia sp!, {r4-r7} and restores them with ldmfd sp!, {r4-r7}. Its own test passes, yet in the full program the caller's local variables change and the restored registers hold wrong values. What is wrong, and how do you fix it and show that the fix works?
- What it tests
- Whether the candidate can work out the words a block transfer touches from its address mode, see whose data the store overwrites, and pair each store mode with the load that undoes it.
- First step
- Write down the four addresses the store touches and where it leaves sp, then do the same for the load, starting from that sp, and compare both with the memory the caller owns.
- Follow-ups
-
- Which memory does the store overwrite, and why does the routine's own test miss it?
- What should the pair be on the stack the procedure call standard uses?
- Where does sp end up after the faulty pair?
- How would you prove the fix on a model or a board?
From the lesson A32 branches, load-store and stack instructions
Model answer, Pro.In the answer:
- Model answer
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Mid to staff
A hand-written A32 function called from C pushes {r4, r5, lr}, calls a C library routine and returns with pop {r4, r5, pc}. A colleague says it breaks the calling convention, although all of its tests succeed. Which rule do they mean, what can go wrong, and what do you change?
- What it tests
- Whether the candidate knows what AAPCS32 requires of the stack at a call and of the registers a function may change, and can show the problem with numbers rather than by rule of thumb.
- First step
- Work out sp at the inner call: what the caller guarantees on entry, minus the bytes the push stores. Then compare it with what the standard requires at a public interface.
- Follow-ups
-
- Which registers may the function change without saving them?
- Why do the tests not show the problem?
- What two changes would fix it, and which would you choose?
- How would you prove the fix?
From the lesson A32 branches, load-store and stack instructions
Model answer, Pro.In the answer:
- Model answer
- Common mistakes
- Rubric
- Variants
- about 4 minutes
-
Mid to senior
Firmware for a classic Arm core reuses a data abort handler's last line,
subs pc, lr, #8, to end a new IRQ handler. With the timer interrupt on, a checksum loop now and then reports a total that is too large by one byte's value. What is happening, and how would you prove it?- What it tests
- Whether the candidate can turn a wrong return offset into its effect on the interrupted code, and can make an intermittent interrupt bug repeat on demand.
- First step
- Write down what LR holds when an IRQ is taken and where the handler's last line sends the core, then find which instruction of the checksum loop that address points at.
- Follow-ups
-
- Which instructions of the loop make the error visible, and which hide it?
- How would you make the interrupt land on the same instruction in every run?
- What would the same line do at the end of an FIQ handler and of a prefetch abort handler?
- Which return should the IRQ handler use, and when is subs pc, lr, #8 the right one?
From the lesson Exceptions, IRQ and FIQ on classic Arm
Model answer, Pro.In the answer:
- Model answer
- Common mistakes
- Rubric
- Variants
- about 4 minutes
-
Mid to staff
A driver needs exactly five interrupts from a periodic timer. Its IRQ handler writes the timer's clear register, logs the tick, and on the fifth tick writes 0 to the timer's enable register. On the board a sixth interrupt appears now and then. Explain the cause and the fix.
- What it tests
- Whether the candidate can reason about what a device does between two of the handler's writes to it, and turn that into a fix and a repeatable test.
- First step
- List the handler's writes to the timer in order and, for each gap between two of them, ask what the timer can do in that gap and what state it leaves behind.
- Follow-ups
-
- Why does the sixth interrupt appear only now and then, not on every run?
- Which order of the handler's writes fixes it, and why?
- What changes when the handler takes longer than one timer period?
- How would you turn the failure into a test that fails every time?
From the lesson Exceptions, IRQ and FIQ on classic Arm
Model answer, Pro.In the answer:
- Model answer
- Common mistakes
- Rubric
- Variants
- about 4 minutes
-
Senior to staff
An ARM7TDMI at 20 MHz with zero-wait-state memory serves two sources: a sensor whose value must be read within 2 µs of its request, and a UART that tolerates 40 µs. Which source goes on FIQ, how long may the FIQ handler run, and what does that choice cost the UART?
- What it tests
- Whether the candidate can build a latency budget from a manual's cycle counts and weigh what the choice of line costs the other source.
- First step
- Turn both deadlines into cycles at 20 MHz, 40 for the sensor and 800 for the UART, then take the manual's worst-case FIQ latency off the 40 to see how many cycles the handler has left before its read.
- Follow-ups
-
- Where does the manual's worst-case FIQ figure come from, and what would raise it?
- How many cycles may the FIQ handler run before the UART's deadline is at risk?
- Why not put the UART on FIQ as well?
- How would you check the budget on the real board?
From the lesson Exceptions, IRQ and FIQ on classic Arm
Model answer, Pro.In the answer:
- Model answer
- Common mistakes
- Rubric
- Variants
- about 4 minutes
-
Mid to senior
Cortex-M3 firmware fills a table of callbacks at start-up with
(uint32_t)&handler + 1, "to set the Thumb bit". The first call through the table ends in a HardFault. Explain what went wrong, how you would prove it from the image and the fault registers, and how you would fix it.- What it tests
- Whether the candidate knows how bit 0 of a branch target and the linker's symbol values interact, and confirms a cause from the image and the fault status registers instead of guessing.
- First step
- Print the word the table holds and the symbol's value in the image's symbol table, and compare bit 0 of the two. Then read the fault status registers and the frame the core stacked for the HardFault: together they say which fault came first and where.
- Follow-ups
-
- Which bits of which registers show the cause, and why does a HardFault report it?
- How do you find the call that made the jump?
- What would the same table do in A32 code on an Armv7-A core?
- How would you write the table so the mistake cannot come back?
From the lesson Thumb, Thumb-2 and the Cortex-M exception model
Model answer, Pro.In the answer:
- Model answer
- Common mistakes
- Rubric
- Variants
- about 5 minutes
-
Senior to staff
Your team writes the first-stage boot ROM of a chip with an Armv7-A core. The ROM is 16 KB of mask ROM that cannot change after tape-out, and the current A32 build is 20,480 bytes. Would you rebuild it as T32, and what would you check before the ROM image is final?
- What it tests
- Whether the candidate measures a size change instead of trusting a rule of thumb, knows which parts of an image do not shrink, and plans for the instruction set the core uses at reset.
- First step
- Build the ROM's own sources both ways with the same compiler and options and compare the code sections, then add up what no instruction set changes: tables, keys, strings, the vector table and padding. Only then decide whether 16 KB is within reach.
- Follow-ups
-
- How much smaller do you expect the T32 build to be, and why not plan with one published figure?
- Which instruction set does the core start in after reset, and what does that mean for the vector table?
- Is there any code you would keep in A32?
- What could the change cost in boot time, and how would you measure it?
From the lesson Thumb, Thumb-2 and the Cortex-M exception model
Model answer, Pro.In the answer:
- Model answer
- Common mistakes
- Rubric
- Variants
- about 4 minutes
-
Mid to senior
A Cortex-M3 SysTick handler written in assembly worked until someone added
bl log_tick, a call to a C function. Now the first SysTick never ends: the core stays in Handler mode, running the handler's last instructions over and over. What went wrong, how would you confirm it, and what must the handler save now?- What it tests
- Whether the candidate knows what lr holds inside a Cortex-M handler and what overwrites it, separates what the core stacks from what a handler must save itself, and keeps the stack aligned at a call.
- First step
- Halt the core while it loops and read the pc, lr, IPSR and the words at sp, then disassemble the handler around the pc. Compare lr with the value it held at the handler's first instruction, and list the registers the body writes beside the eight the core stacked.
- Follow-ups
-
- Why does the handler loop instead of returning or faulting?
- Which registers must the fixed handler push, and why an even number of them?
- Would the same handler written in C have had this bug?
- What else stops running while it loops, and what still runs?
From the lesson Thumb, Thumb-2 and the Cortex-M exception model
Model answer, Pro.In the answer:
- Model answer
- Common mistakes
- Rubric
- Variants
- about 5 minutes
-
Fresher to mid
A lab program adds 200 unsigned 16-bit sensor readings into a 32-bit total on a 32-bit Arm core. It matches a spreadsheet's total on most data sets, but on one set it comes out exactly 196,608 short. How would you find the cause, and how would you show that the fix works?
- What it tests
- Whether the candidate turns the size of an error into its cause, knows how a 16-bit value becomes a 32-bit one, and builds inputs that make the fault appear every time.
- First step
- Write the shortfall in hex before reading any code: 196,608 is 0x30000, an exact multiple of 65,536. An error that comes in whole units of 2^16 rarely comes from the additions themselves, so look first at how each reading is widened from 16 to 32 bits, and at what the failing set's readings have that the others lack.
- Follow-ups
-
- Which readings would you put in a test set so that this fault cannot hide?
- How many 16-bit readings can a 32-bit total hold before the total itself overflows?
- What changes if the sensor reports signed values that can fall below zero?
From the lesson 32-bit Arm lab programs and exam practice
Model answer, Pro.In the answer:
- Model answer
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Mid to senior
You must check 60 students' A32 programs for the lab "find the largest and the smallest of 32 words" automatically, on a simulator. What would your checker run, what would it compare and report, and which data sets would you give every program?
- What it tests
- Whether the candidate checks the end state a program promised rather than what it prints, picks data sets that each break a specific wrong program, and plans for programs that never stop.
- First step
- Write the contract down first: where each answer must be when the program reaches its final branch to itself, and whether it is read as a signed or an unsigned number. Then plan several data sets, each meant to make one kind of wrong program give a wrong answer, and an instruction limit for programs that never stop.
- Follow-ups
-
- Which data set separates a signed comparison from an unsigned one?
- What should the checker report for a program that never reaches its final branch?
- How do you keep a program from matching by storing answers it never computed?
- What would you show a student whose program fails on one data set?
From the lesson 32-bit Arm lab programs and exam practice
Model answer, Pro.In the answer:
- Model answer
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Fresher to senior
A student's A32 lab run ends with pc = 0x00000010, CPSR = 0x000001D7 and r14 of Abort mode = 0x00000034, and the result word in memory still holds 0. The student says the program just stopped early. What do the three values tell you, and what do you check next?
- What it tests
- Whether the candidate decodes the mode field of a CPSR value, recognises a vector address, and uses an exception's link register offset to find the instruction that failed.
- First step
- Decode each value before guessing: the mode that the CPSR's low five bits name, which entry of the vector table the PC sits at, and what the link register of that mode records for this kind of exception. Then read the instruction those values point to, and the registers it used.
- Follow-ups
-
- Which instruction failed, and what would you look at in it?
- Why did the run stop at that address instead of carrying on?
- What would the same three values look like after an undefined instruction?
- How would you change the lab's start-up code so that the next failure reports itself?
From the lesson 32-bit Arm lab programs and exam practice
Model answer, Pro.In the answer:
- Model answer
- Common mistakes
- Rubric
- Variants
- about 3 minutes
All Assembly (x86-64, AArch64, RISC-V) interview questions · The Assembly (x86-64, AArch64, RISC-V) track