G27
Self-checkedTier 1 13 min readcoa.addressing-modes

Addressing modes

The ways an instruction names its operands: immediate, direct, indirect, register, register indirect, displacement, indexed, PC-relative and auto-increment or decrement, with the effective-address rule, the number of memory references and the typical use of each.

Why it exists

An instruction has to say where its operands are. Spending a whole memory address on every operand would make instructions huge, and fixing operand locations at compile time would forbid arrays, pointers and recursion. Addressing modes are the compact rules an instruction uses to say "the operand is a constant", "the operand is in this register", "the operand is at this address plus the value of that register". Every high-level construct has a mode behind it: a variable, a pointer dereference, an array element, a structure field, a local variable on the stack, a loop step. GATE asks for the effective address or the value an instruction loads under a given mode, the number of memory references, and which mode suits which job.

Prerequisites

You need operand fields and instruction classes from ISA design, and the instruction cycle, in particular that the PC already points to the next instruction when the operand is computed.

Precise definitions

Effective address (EA). The address of the memory word that holds the operand, after the addressing rule has been applied. For modes that name a register or a constant there is no EA.

The modes (names vary between books; these are the ones used here):

ModeAssembly styleOperandEffective addressMemory references for the operand
Immediate#20the constant 20none0
Direct (absolute)20M[20]M[20]201
Indirect (memory indirect)@20M[M[20]]M[M[20]]M[20]M[20]2
RegisterR2the contents of R2none0
Register indirect(R2)M[R2]M[R2]R21
Displacement (base register)4(R2)M[R2+4]M[R2 + 4]R2 + 41
Indexed20(R2)M[20+R2]M[20 + R2]20 + R21
PC-relative9(PC)M[PC+9]M[PC + 9]PC + 91
Auto-increment(R2)+M[R2]M[R2], then R2 growsR2 (before)1
Auto-decrement-(R2)R2 shrinks, then M[R2]M[R2]R2 (after)1

Memory references are for the operand only; add 1 for the instruction fetch. A modification (auto-increment or decrement) changes the register by the size of the operand (1 for a word-addressed machine, 4 for a 4-byte int on a byte-addressed one).

What each is for.

  • Immediate: constants such as x = 5; fastest (no memory access) but the constant must fit in the field.
  • Direct: static or global variables at a fixed address; the address field must be as wide as the address space.
  • Indirect: pointers stored in memory; two memory references; allows the target address to change without changing the code.
  • Register: the fastest operands; the compiler keeps hot variables here.
  • Register indirect: a pointer in a register (*p): one reference, short instructions.
  • Displacement (base + offset): a record field, or a local variable at a fixed offset from a frame pointer; the register holds the base, the instruction holds a small constant. The same arithmetic is also used for base-register relocation: a program written with addresses starting at 0 is loaded anywhere by putting the load address in the base register.
  • Indexed: an array element: the instruction holds the array's start address and the register holds the index (or the other way round, which is the same sum). Some ISAs add a scale: EA=base+index×scale+displacementEA = \text{base} + \text{index} \times \text{scale} + \text{displacement}.
  • PC-relative: branch targets and data near the code; no absolute address in the instruction, so the code works wherever it is loaded (position independent). Remember PC already points to the next instruction.
  • Auto-increment and auto-decrement: walk through an array (one instruction uses the element and steps the pointer) and implement a stack (auto-decrement to push, auto-increment to pop, or the reverse).
  • Implied and stack: operands are implicit (accumulator, top of stack); no operand field at all.

Cost. More complex modes cut the number of instructions but cost more memory references, more adders in the datapath, and make instructions longer or harder to pipeline. Load-store ISAs keep only a few simple modes (register, immediate, displacement), and CISC ISAs have many.

How it works

One operand field, the number 20, is interpreted by each of the ten modes in turn, with the machine in the same state each time: PC = 11 (the instruction was at 10 and has been fetched), R2 = 24 and the memory words shown at the right. Step through and watch the effective address (EA), the memory read (MDR) and the result in R1.

One operand field, ten addressing modes: step 1

Machine run, not typed
setup(fetch done)
PC
11
R1
0
R2
24
EA
0
MDR
0
addrdecimalmeaning
01424
017123
018124
01C128
02C144

Step 1

The instruction LOAD R1, <operand> has just been fetched from address 10, so PC = 11 already points at the next instruction. R2 holds 24 and memory has the values shown. The same operand field, 20, is now interpreted by ten different addressing modes. In every case the question is: what number ends up in R1?

1 / 41
computed by script: a simulation of the machine, one register transfer per step. python3 scripts/gen-coa-traces.py

The results, with the number of memory reads for the operand: immediate 20 (0), direct 24 (1), indirect 124 (2), register 24 (0), register indirect 124 (1), base plus displacement 4 gives 128 (1), indexed gives 144 (1), PC-relative with offset 9 gives 24 (1), auto-increment 124 and R2 becomes 25, auto-decrement 123 and R2 becomes 23. Every mode is a different way to reach, or not reach, memory.

Worked examples

EX 1The same arithmetic in C

Easy

Array indexing, pointers, structure fields and pointer increments in C compile to exactly these modes.

#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
 
struct rec { int id; int score; short tag; };
 
int main(void) {
    int a[8] = { 10, 11, 12, 13, 14, 15, 16, 17 };
    /* indexed: effective address = base + index * element size */
    char *base = (char *)a;
    int i = 5;
    char *ea = base + i * (int)sizeof(int);
    printf("a[5]: EA - base = %td bytes, value %d\n", ea - base, *(int *)ea);
    /* register indirect: a pointer in a register */
    int *p = &a[2];
    printf("*p = %d (pointer holds the address of a[2], %td bytes past the start)\n", *p, (char *)p - base);
    /* auto-increment: use, then advance by the element size */
    int *q = a;
    int first = *q++;
    int second = *q++;
    printf("*q++ twice: %d then %d, q advanced %td bytes\n", first, second, (char *)q - base);
    /* auto-decrement: step back first, then use (a push/pop style stack) */
    int *s = a + 4;
    int top = *--s;
    printf("*--s = %d, s moved back %zu bytes\n", top, sizeof(int));
    /* base + displacement: a structure member is the structure's address plus a constant */
    struct rec r = { 7, 90, 3 };
    char *rb = (char *)&r;
    printf("r.score at base + %zu = %d; r.tag at base + %zu = %d\n", offsetof(struct rec, score), *(int *)(rb + offsetof(struct rec, score)), offsetof(struct rec, tag), *(short *)(rb + offsetof(struct rec, tag)));
    /* indirect: a pointer stored in memory */
    int *ptr_in_memory = &a[6];
    int **pp = &ptr_in_memory;
    printf("**pp = %d (two memory reads: the pointer, then the data)\n", **pp);
    return 0;
}
a[5]: EA - base = 20 bytes, value 15
*p = 12 (pointer holds the address of a[2], 8 bytes past the start)
*q++ twice: 10 then 11, q advanced 8 bytes
*--s = 13, s moved back 4 bytes
r.score at base + 4 = 90; r.tag at base + 8 = 3
**pp = 16 (two memory reads: the pointer, then the data)

Reading it. a[5] is indexed addressing: the EA is the array's start plus 5×4=205 \times 4 = 20 bytes. *p is register indirect. *q++ is auto-increment (the value is used, then q advances by the element size, 4 bytes). *--s is auto-decrement (step back, then use). r.score and r.tag are base plus displacement, with the displacements 4 and 8. **pp is memory indirect: one read for the pointer and one for the data.

EX 2Value under each mode (a second state)

Easy

State: R3 = 100, R4 = 4, PC = 2000 after the fetch, operand field = 100; memory: M[99]=499M[99] = 499, M[100]=500M[100] = 500, M[104]=504M[104] = 504, M[108]=508M[108] = 508, M[500]=77M[500] = 77, M[2012]=900M[2012] = 900.

ModeOperand loadedEAOperand references
immediate #100100none0
direct 1005001001
indirect @100M[500]=77M[500] = 775002
register R3100none0
register indirect (R3)5001001
displacement 8(R3)5081081
indexed 100(R4)5041041
PC-relative 12(PC)90020121
auto-increment (R3)+500, then R3 = 1011001
auto-decrement -(R3)499 (R3 = 99 first)991

All values are computed by the checking script from the stated state.

EX 3Array access and relocation

Medium

Array. An array of 4-byte integers starts at 2000. Element 7 is at 2000+4×7=20282000 + 4 \times 7 = 2028. With indexed addressing the instruction holds 2000 and the register holds the byte offset 28 (or 2000 in the register and a scaled index 7 with scale 4). Relocation. A program compiled assuming it starts at address 0 has an operand at address 120. If it is loaded at 5000, the base register holds 5000 and the displacement 120 gives 5000+120=51205000 + 120 = 5120. The program's code does not change.

EX 4Which mode?

Medium

A constant loop count: immediate. A global counter at a fixed address: direct. A linked-list node pointer held in a register: register indirect, and the field node->next at offset 8: displacement 8(R). Walking through an array with a pointer: auto-increment. A local variable of a function, at 12 bytes from the frame pointer: displacement -12(FP). A branch 40 instructions ahead: PC-relative. Pushing onto a stack that grows downward: auto-decrement.

EX 5Count the memory references of an instruction

GATE level

Assumed model: 2-address ADD X, Y computes X←X+YX \leftarrow X + Y and every memory operand is read once, the destination is also written. For ADD @A, B with the destination indirect (the instruction holds the address of a pointer to the destination) and the source BB direct: 1 (fetch) + 1 (read the pointer at A) + 1 (read the destination operand) + 1 (read B) + 1 (write the result) = 5 memory references. The same instruction with both operands in registers has only the 1 fetch. Always list: fetch, then for each operand its address-forming references, then its data reference, then the write.

EX 6PC-relative target

GATE level

A branch instruction at address 1000 is 2 bytes long and its offset field is +30+30 (bytes). PC after the fetch is 1002, so the target is 1002+30=10321002 + 30 = 1032. If the machine's offsets count instructions of 2 bytes each, the target is 1002+2×30=10621002 + 2 \times 30 = 1062. The question states which. The reach of an nn-bit signed offset is −2n−1-2^{n-1} to 2n−1−12^{n-1} - 1 units from the next instruction.

Cheat box

Cheat box

  • Immediate: operand in the instruction. Direct: M[A]M[A]. Indirect: M[M[A]]M[M[A]] (2 reads). Register: in R. Register indirect: M[R]M[R].
  • Displacement: M[R+d]M[R + d]. Indexed: M[A+R]M[A + R]. PC-relative: M[PC+d]M[PC + d] with PC = next instruction.
  • Auto-increment: use M[R]M[R], then R←R+sizeR \leftarrow R + \text{size}. Auto-decrement: R←R−sizeR \leftarrow R - \text{size}, then use M[R]M[R].
  • Memory references for the operand: immediate 0, register 0, direct 1, register indirect 1, displacement 1, indirect 2 (add 1 for the fetch).
  • Uses: array = indexed, pointer = register indirect, struct field and local variable = displacement, branch = PC-relative, relocation = base register, stack = auto-decrement and auto-increment.
  • Load-store ISAs keep few modes; CISC has many.

Traps and GATE patterns

Connections

The fields that hold the register number, the displacement and the mode bits are the topic of instruction formats. Frame-pointer displacement addressing is how a function reaches its arguments and locals (stack frames). The extra read of an indirect operand is one more micro-operation in the instruction cycle. In C, array elements correspond to indexed mode (arrays) and pointer dereferences to register indirect (pointers).

PYQs

15 previous year questions from your book. I re-solved each one myself (10 by running or simulating, 5 by reasoning only); the book's key is shown next to my answer. All PYQs

GATE 2026 · MCQQ2 · page 474 of the book
Match each addressing mode in List I with a
data element or an element of a data structure
(in a high-level language) in List II.
List I
 P. Immediate
 Q. Indirect
 R. Base with index
 S. Base with offset/displacement
List II
1. Element of an array
2. Pointer
3. Element of a record
4. Constant
  • (a)P-4, Q-3, R-1, S-2
  • (b)P-4, Q-2, R-1, S-3
  • (c)P-1, Q-4, R-3, S-2
  • (d)P-2, Q-3, R-1, S-4
GATE 2023 · MCQ · 2 marksQ9 · page 475 of the book
Consider the given C-code and its corresponding
assembly code, with a few operands U1-U4 being
unknown. Some useful information as well as the
semantics of each unique assembly instruction is
annotated as inline comments in the code. The
memory is byte-addressable.

;assembly code (; indicates comments)
;r1-r5 are 32-bit integer registers
//C-code
;initialize r1=0, r2=10
;initialize r3, r4 with base address of a, b
L01: jeq r1, r2, end ;if(r1==r2) goto end
L02: lw, r5, 0(r4) ;r5 <- Memory[r4+0]
int a[10], b[10], i;
L03: sh1, r5, r5, U1 ;r5 <- r5 << U1
// int is 32 bit
L04: sw, r5, 0(r3) ;Memory[r3+0] <- r5
for(i=0; i<10; i++)
L05: add, r3, r3, U2 ;r3 <- r3+U2
a[i] = b[i] * 8;
L06: add, r4, r4, U3
L07: add, r1, r1, 1
L08: jmp U4 ;goto U4
L09: end
Which one of the following options is a CORRECT
replacement for operands in the position (U1, U2,
U3, U4) in the above assembly code?
  • (a)(8, 4, 1, L02)
  • (b)(3, 4, 4, L01)
  • (c)(8, 1, 1, L02)
  • (d)(3, 1, 1, L01) Computer Organization and Architecture
GATE 2021 · Set 1 · NAT · 2 marksQ10 · page 476 of the book
Consider the following instruction sequence
where registers R1, R2 and R3 are general
purpose and MEMORY [X] denotes the content
at the memory location X .

Instruction
Semantics
Instruction
Size
(bytes)
MOV
R1,(5000)
R1 ←
MEMORY[5000]
4
MOV
R2,(R3)
R2
←MEMORY[R3]
4
ADDR2,
R1
R2 ← R1 + R2
2
MOV
(R3), R2
MEMORY[R3]←
R2
4
INC R3
R3 ← R3 + 1
2
DEC R1
R1 ← R1 - 1
2
BNZ 1004
Branch if not zero
to the given
absolute address
2
HALT
Stop
1

Assume that the content of the memory location
5000 is 10 , and the content of the register R3 is
3000 . The content of each of the memory
locations from 3000 to 3010 is 50 . The
instruction sequence starts from the memory
location 1000. All the numbers are in decimal
format. Assume that the memory is byte
addressable.
After the execution of the program, the content
of memory location 3010 is
GATE 2017 · NATQ14 · page 477 of the book
Consider a RISC machine where each instruction is
exactly 4 bytes long. Conditional and unconditional
branch instructions use the PC-relative addressing
mode, with the offset specified in bytes to the target
location of the branch instruction.
Furthermore, the offset is always with respect to the
address of the next instruction in the program
sequence.
Consider the following instruction sequence:

If the target of the branch instruction is i, then the
decimal value of the Offset is
.
GATE 2017 · MCQ · 1 markQ15 · page 477 of the book
Consider the C struct defined below:
struct data {
int marks [100];
char grade:
int cnumber;
l:
struct data student:

The base address of student is available in register
R1. The field student.grade can be accessed
efficiently using:
  • (a)Post-increment addressing mode, (R1)+
  • (b)Pre-decrement addressing mode, -(R1)
  • (c)Register direct addressing mode, R1
  • (d)Index addressing mode, X(R1), where X is an offset represented in 2's complement 16 -bit representation
year not read yetQ21 · page 478 of the book
Consider a hypothetical processor with an
instruction of type LW R1, 20(R2), which during
execution reads a 32-bit word from memory and
stores it in a 32-bit register R1. The effective
address of the memory location is obtained by the
addition of a constant 20 and the contents of
register R2. Which of the following best reflects
the addressing mode implemented by this
instruction for operand in memory?
  • (a)Immediate Addressing
  • (b)Register Addressing
  • (c)Register Indirect Scaled Addressing
  • (d)Base or Indexed Addressing
year not read yetQ22 · page 478 of the book
Which of the following is/are true of the auto-
increment addressing mode?
I. It is useful in creating self-relocating code
II. If it is included in an Instruction Set Architecture,
then an additional ALU is required for effective
address calculation
III. The amount of increment depends on the size of
the data item accessed
  • (a)I only
  • (b)Il only
  • (c)III only
  • (d)II and III only
year not read yetQ24 · page 478 of the book
Assume that EA = (X)+ is the effective address
equal to the contents of location X, with X
incremented by one word length after the
effective address is calculated; EA = -(X) is the
effective address equal to the contents of location
X, with X decremented by one word length before
the effective address is calculated; EA = (X)- is
the effective address equal to the contents of
location X, with X decremented by one word
length after the effective address is calculated.
The format of the instruction is (opcode, source,
destination), which means (destination ← source
op destination). Using X as a stack pointer, which
of the following instructions can pop the top two
elements from the stack, perform the addition
operation and push the result back to the stack.
GATE MCQ – 2008 MCQ (1-MARKS)
GATE MCQ – 2011 MCQ (1-MARKS)
Computer Organization and Architecture
  • (a)ADD (X)-, (X)
  • (b)ADD (X), (X)-
  • (c)ADD -(X), (X)+
  • (d)ADD -(X), (X)
GATE 2007 · MCQ · 2 marksQ25 · page 479 of the book
Consider the following program segment. Here
R1, R2 and R3 are the general purpose registers.

Instruction
Operation
Instruction
Size (no.
of words)

MOV
R1,(3000)
R1 ← M3000]
2
LOOP:
MOV
R2,(R3)
R2←M[R3]
1

ADD R2,R1
R2 ← R1 + R2
1

MOV
(R3),R2
M[R3] ←R2
1

INC R3
R3←R3+1
1

DEC R1
R1 ← R1 - 1
1

BNZLOOP
Branch on not zero
2

HALT
Stop
1

Assume that the content of memory
location 3000 is 10 and the content of the
register R3 is 2000. The content of each of
the memory locations
from 2000 to 2010 is 100. The program is
loaded from the memory location 1000. All
the numbers are in decimal.
Assume that the memory is word addressable. The
number of memory references for accessing the
data in executing the program completely is
  • (a)10
  • (b)11
  • (c)20
  • (d)21
GATE 2007 · MCQ · 2 marksQ26 · page 479 of the book
Consider the following program segment. Here R1,
R2 and R3 are the general purpose registers.

Instruction
Operation
Instruction
Size (no.
of words)
MOV
R1,(3000)
R1 ← M3000]
2
LOOP:
MOV
R2,(R3)
R2←M[R3]
1
ADD R2,R1
R2 ← R1 + R2
1
MOV
(R3),R2
M[R3] ←R2
1
INC R3
R3←R3+1
1
DEC R1
R1 ← R1 - 1
1
BNZLOOP
Branch on not zero
2
HALT
Stop
1

Assume that the content of memory location 3000 is
10 and the content of the register R3 is 2000. The
content of each of the memory locations from 2000 to
2010 is 100. The program is loaded from the memory
location 1000. All the numbers are in decimal.
Assume that the memory is word addressable. After
the execution of this program, the content of memory
location 2010 is:
  • (a)100
  • (b)101
  • (c)102
  • (d)110 Computer Organization and Architecture
GATE 2007 · MCQQ27 · page 480 of the book
Consider the following program segment. Here
R1, R2 and R3 are the general purpose registers.

Instruction
Operation
Instruction
Size
(no. of
words)

MOV
R1,(3000)
R1←M[3000]
2
LOOP:
MOV
R2,(R3)
R2 ← [R3]
1

ADD
R2,R1
R2 ← R1+R2
1

MOV
(R3),R2
M[R3] ←R2
1

INC R3
R3 ← R3+1
1

DEC R1
R1 ← R1-1
1

BNZ
LOOP
Branch on not
zero
2

HALT
Stop
1

Assume that the content of memory location 3000
is 10 and the content of the register R3 is 2000 . The
content of each of the memory locations from 2000
to 2010 is 100 . The program is loaded from the
memory location 1000. All the numbers are in
decimal.
Assume that the memory is byte addressable and
the word size is 32 bits. If an interrupt occurs during
the execution of the instruction "INC R3", what
return address will be pushed on to the stack?
  • (a)1005
  • (b)1020
  • (c)1024
  • (d)1040
GATE 2006 · MCQ · 2 marksQ32 · page 481 of the book
Which of the following statements about relative
addressing mode is FALSE?
  • (a)It enables reduced instruction size
  • (b)It allows indexing of array elements with same instruction
  • (c)It enables easy relocation of data
  • (d)It enables faster address calculations than absolute addressing
GATE 2006 · MCQ · 2 marksQ33 · page 481 of the book
The memory locations 1000, 1001 and 1020 have
data values 18, 1 and 16 respectively before the
following program is executed.

MOVI
Rs, 1
Move immediate
LOAD
Rd, 1000(Rs)
Load from memory
ADDI
Rd, 1000
Add immediate
STOREI
0(Rd), 20
Store immediate

Which of the statements below is TRUE after the
program is executed?
  • (a)Memory location 1000 has value 20
  • (b)Memory location 1020 has value 20
  • (c)Memory location 1021 has value 20
  • (d)Memory location 1001 has value 20
GATE 2005 · MCQ · 2 marksQ34 · page 481 of the book
Consider a three-word machine instruction:
ADD A [R0], @B
The first operand (destination) "A [R0]" uses
indexed addressing mode with R0 as the index
register.
The second operand (source) "@B" uses indirect
addressing mode.
A and B are memory addresses residing at the
second and the third words, respectively.
The first word of the instruction specifies the
opcode, the index register designation, and the
source and destination addressing modes.
Computer Organization and Architecture

During execution of the ADD instruction, the two
operands are added and stored in the destination
(first operand).
The number of memory cycles needed during the
execution cycle of the instruction is:
  • (a)3
  • (b)4
  • (c)5
  • (d)6
GATE 2005 · MCQ · 2 marksQ35 · page 482 of the book
Match List-I with List-II and select the
correct answer using the codes given below
the lists:
List-I
List-II
A.[I] = B[J];
1. Indirect addressing
B. while(*A++);
2. Indexed addressing
C. int temp = *x;
3. Autoincrement
A B C
  • (a)3 2 1
  • (b)1 3 2
  • (c)2 3 1
  • (d)1 2 3

Self-check

Question 1

With R1 = 200, M[200] = 300, M[300] = 400, M[204] = 55, what does LOAD R2, 4(R1) load, and what does LOAD R2, (R1) load?

Show answer

4(R1): EA =200+4=204= 200 + 4 = 204, loads M[204]=55M[204] = 55. (R1) (register indirect): EA =200= 200, loads M[200]=300M[200] = 300.

Question 2

How many memory references does LOAD R1, @50 make, including the fetch?

Show answer

3: the fetch, the read of M[50]M[50] (the pointer) and the read of the operand.

Question 3

R5 = 1000 and the elements are 4-byte integers. What are R5 and the loaded address after LOAD R1, (R5)+ and then LOAD R2, (R5)+?

Show answer

The first load reads address 1000 and leaves R5 = 1004; the second reads 1004 and leaves R5 = 1008.

Question 4

Which addressing mode lets a program run unchanged wherever it is loaded in memory, without any relocation by the operating system?

Show answer

PC-relative addressing (the operands and branch targets are described relative to the PC, so they move with the code); a base register does the same job for data when its value is set at load time.

Revision card

One-screen revision

  • EA rules: direct A; indirect M[A]M[A]; register indirect R; displacement R + d; indexed A + R; PC-relative PC + d (PC = next instruction); auto-inc: R then R+=sizeR \mathrel{+}= \text{size}; auto-dec: R−=sizeR \mathrel{-}= \text{size} then R.
  • Operand memory references: immediate and register 0; most others 1; indirect 2. Add 1 for the fetch.
  • Uses: array = indexed, pointer = register indirect, field/local = displacement, branch = PC-relative, stack = auto-dec/inc.

References

  • ·Hennessy and Patterson, Computer Architecture: A Quantitative Approach, Chapter 1 / Appendix A (memory addressing, addressing modes)
  • ·Hamacher, Vranesic, Zaky, Computer Organization, 5th ed., Chapter 2 Machine Instructions and Programs (addressing modes)
  • ·Morris Mano, Computer System Architecture, 3rd ed., Chapter 8 Central Processing Unit (addressing modes)

Verification

The ten-mode animation is a simulator run in which each mode's effective address, value and register change are computed from the same state; tests/coa-traces.test.ts recomputes the final R1 and R2 of every mode and the number of memory reads. A second register and memory state (used in the examples) is evaluated for all ten modes in scripts/enum-checks/coa_isa.py, including the number of memory references. The C program (npm run verify:c) shows the same address arithmetic with real arrays, pointers and structures. Names of modes differ between books (for example base-register, index and displacement are sometimes used for the same arithmetic); the page uses one set and says so. Textbook chapter titles are from memory. SECOND PASS (2026-11-02, done by the assistant, not a human check): every Self-check question was solved before the printed answer was read and all agreed; the definitions, worked examples, cheat box and traps were read claim by claim and the numbers re-derived by hand (long C programs were not re-read line by line: they are compiled and compared by npm run verify:c, and their printed outputs were checked against the prose). No defect found. Status raised to self-checked; verified needs a textbook or human check.

last verified: never