Year 12

AQA A level Computer Science [P1] Relative Symbolic Addressing Notes

Relative & Symbolic Addressing

— Computer Science · A Level (9618) · Paper 1 · Assembly language —
★ Exam Tip: A two-pass assembler question usually asks you to fill a symbol table in order (the circled numbers) and then explain how it was filled. Scan line by line, symbols first, absolute addresses next.

1. The Instruction Set (given in the paper)

The processor has one general purpose register — the Accumulator (ACC) — and an Index Register (IX).

MnemonicOperandBinaryWhat it does
LDM#n1100 0001Immediate addressing — load the number n into ACC
LDD<address>1100 0010Direct addressing — load the contents of the given address into ACC
LDV#n1100 0011Relative addressing — move n locations from the address of the current instruction, load the contents of that address into ACC
STO<address>1100 0100Store the contents of ACC at the given address
DEC—1100 0101Decrement the contents of ACC
OUTCH—1100 0111Output the character whose ASCII code is in ACC
JNE<address>1110 0110After a compare, jump to <address> if the compare was False
JMP<address>1110 0011(Unconditionally) jump to the given address
CMP#n1110 0100Compare the contents of ACC with number n
Watch out: JNE jumps when the compare was False (not equal). If ACC does equal n, JNE does not jump — the next line runs instead.

Three ways to load into ACC

ModeInstructionACC gets…
ImmediateLDM #nthe number n itself
DirectLDD <address>the contents of that address
RelativeLDV #nthe contents of the address n places on from this instruction
Relative: address used = address of the current instruction + n

2. Tracing the Program (part b)

Task: complete the trace table for the assembly program. The teacher first numbered every line 0 – 16 (the address of each line, counting from the first instruction).

AddrLabelInstr.Operand
0StartProg:LDV#CountDown
1CMPNum1
2JNECarryOn
3JMPFinish
4CarryOn:OUTCH
5LDDCountDown
6DEC
7STOCountDown
8JMPStartProg
AddrLabelInstr.Operand
9Finish:LDM#88
10OUTCH
11END
12CountDown:15
1332
1451
1567
16Num1:32
Trick: ASCII codes given — 32 = space, 51 = “3”, 66 = B, 67 = “C”, 88 = “X”.

Key idea — what does LDV #CountDown do?

n = the value stored in CountDown (15, then 14, then 13). LDV sits at address 0, so it loads from address 0 + n.

The data lines 12–15 therefore get “picked” one by one, counting down: 15 → 67, 14 → 51, 13 → 32. On the last pass the teacher wrote LDV #13.

0LDV #CountDown ⋮ CountDown:1215 1332 1451 1567 Num1:1632 pass 1: n = 15 pass 2: n = 14 pass 3: n = 13
address = 0 + n → each pass reaches one location lower in the data block

Pass-by-pass working

Pass 1 (CountDown = 15) LDV: 0 + 15 = 15 ACC = 67 CMP 32: 67 ≠ 32 ⇒ JNE jumps OUTCH ⇒ C LDD CountDown ⇒ ACC = 15 DEC ⇒ ACC = 14 STO ⇒ CountDown = 14
Pass 2 (CountDown = 14) LDV: 0 + 14 = 14 ACC = 51 CMP 32: 51 ≠ 32 ⇒ JNE jumps OUTCH ⇒ 3 LDD CountDown ⇒ ACC = 14 DEC ⇒ ACC = 13 STO ⇒ CountDown = 13
Pass 3 (CountDown = 13) LDV: 0 + 13 = 13 ACC = 32 CMP 32: 32 = 32 ⇒ compare True ⇒ JNE does not jump JMP Finish LDM #88 ⇒ ACC = 88 OUTCH ⇒ X, then END

Completed trace table

ACCCountDownOUTPUT
—15—
67C
15
1414
513
14
1313
32
88X

Blue rows were already printed in the question; green rows are the answers the teacher filled in.

Teacher’s comparisons: 67 ≠ 32 · 51 ≠ 32 · 32 = 32 — the loop stops only when ACC matches Num1 (32). Output of the program: C 3 X.
LDV #CountDown ACC ← 0 + n CMP Num1 (ACC vs 32) ≠ : OUTCH CountDown − 1 = : Finish LDM #88, OUTCH, END ≠ 32 = 32 JMP StartProg (repeat)
the program is a loop: print a character, count down, stop when ACC = 32

3. Two-Pass Assembler & Symbol Table (part c)

The program is translated by a two-pass assembler. It now begins with the directive ORG #0100, which tells the assembler to load the first instruction to address 100.

assemblysource PASS 1symbol table PASS 2+ instruction table executablefile
pass 1 → symbol table · pass 2 → needs a second table (the instruction table) to build the executable

Program with absolute addresses

AddrLabelInstr.Operand
—ORG#0100
100StartProg:LDV#CountDown
101CMPNum1
102JNECarryOn
103JMPFinish
104CarryOn:OUTCH
105LDDCountDown
106DEC
107STOCountDown
108JMPStartProg
AddrLabelInstr.Operand
109Finish:LDM#88
110OUTCH
111END
112CountDown:15
11332
11451
11567
116Num1:32
Board slip corrected: on the board the line JMP StartProg was left without an address, so the numbers from Finish onward came out one too low (Finish 108, CountDown 111, Num1 115). Counting every line, the right values are Finish 109, CountDown 112, Num1 116. StartProg 100 and CarryOn 104 are unaffected.

Filling the symbol table — scan line by line

Teacher’s method: scan line by line; enter the symbols first, then the absolute addresses. The circled numbers show the order of the entries.

Symbolic addressAbsolute address (in order made)
StartProg 1100 2
CountDown 3UNKNOWN 4   112 13
Num1 5UNKNOWN 6   116 14
CarryOn 7UNKNOWN 8   104 11
Finish 9UNKNOWN 10   109 12
Why this order?
  1. StartProg is a label on the first line → ① with its address 100 ②.
  2. CountDown appears as an operand in LDV (③, address not known yet → UNKNOWN ④).
  3. Num1 in CMP → ⑤ UNKNOWN ⑥; CarryOn in JNE → ⑦ UNKNOWN ⑧; Finish in JMP → ⑨ UNKNOWN ⑩.
  4. Later the labels CarryOn: ⑪, Finish: ⑫, CountDown: ⑬, Num1: ⑭ are reached, so UNKNOWN is struck out and the absolute address written in.
  5. Repeat uses (LDD CountDown, STO CountDown, JMP StartProg) are already in the table — nothing new is added.

“Explain how the assembler made these entries.” [3]

Model answer (teacher’s bullets):
  • The assembler scans the assembly language instructions in sequence.
  • When it meets a symbolic address, it checks whether it is already in the symbol table.
  • If not, it adds it to the symbol table in the symbolic address column.
  • If it is already in the table, it checks whether the absolute address is known.
  • If the absolute address is known, it is entered in the appropriate cell.
  • If the absolute address is not known, it leaves it as UNKNOWN.
part (d)(i)1 mark

The assembler must then complete the second pass, building up the executable file. Name the second table needed.

Answer: Instruction table (the lookup of mnemonic → binary op code).

4. Symbol Table with Relative Addresses (part e)

Same idea, but there is no ORG — the table shows relative addresses, counted from the first instruction = 0. The teacher numbered every line 0 – 14.

AddrLabelInstr.Operand
0StartProg:LDV#Offset
1CMPValue
2JPEEndProg
3OUTCH
4LDDOffset
5INC
6STOOffset
7JMPStartProg
8EndProg:END
AddrLabelInstr.Operand
9Offset:10
1050
1165
1289
1332
14Value:32
Note: JPE = jump if the compare was True (equal) — the opposite of JNE.

Completed symbol table [6]

Symbolic addressRelative address (in order made)
StartProg 10 2
Offset 3UNKNOWN 4   9 10
Value 5UNKNOWN 6   14 11
EndProg 7UNKNOWN 8   8 9
Order of entries:
  1. StartProg label ① = 0 ②.
  2. LDV #Offset → Offset ③, UNKNOWN ④. CMP Value → Value ⑤, UNKNOWN ⑥. JPE EndProg → EndProg ⑦, UNKNOWN ⑧.
  3. Labels reached later: EndProg: 8 ⑨, Offset: 9 ⑩, Value: 14 ⑪.
  4. OUTCH, LDD/STO Offset, INC and JMP StartProg add nothing new — symbols already present.

5. Quick Recap

✓ Full Chapter Cheat-Sheet
  • LDM #n immediate (number) · LDD addr direct (contents) · LDV #n relative (address = current + n).
  • JNE jumps if compare is False; JMP always jumps; CMP #n compares ACC with n; OUTCH prints the ASCII char in ACC.
  • Trace: LDV #CountDown uses n = value in CountDown (15 → 14 → 13) → loads 67, 51, 32 → prints C 3 X.
  • Two-pass assembler: pass 1 builds the symbol table; pass 2 builds the executable using the instruction table too.
  • ORG #0100 → first instruction at address 100; no ORG (relative table) → first instruction = 0.
  • Symbol table: scan line by line → new symbol: add it, address UNKNOWN → when its label line is reached: strike UNKNOWN, write the address. Circled numbers = order of entries.
  • 3-mark explanation: scan in sequence · check if symbol already in table · add if not · if present, check absolute address known · enter it if known · leave UNKNOWN if not.