Year 12

AQA A level Computer Science [P1] Assembly Language Notes

Assembly Language

— Computer Science · AS Level (9618) · Paper 1 —
★ Exam Tip: Trace tables, relative addressing and the two-pass assembler / symbol table are past-paper favourites (9618 Paper 1). Always read the code line by line and write every change in ACC / memory / IX / OUTPUT.

1. What is Assembly Language?

Definition: Assembly language is a low-level language — a type of programming language we use to directly manipulate hardware, e.g. reading / writing to a specific memory address.

It is one step above machine code — machine code is the series of binary numbers (0 and 1).

Memory = a table of locations

Location / AddressContent
1525
1635
1719
1855
1930
2922
3015
317

Location / Address → the place used to access the memory.

Content → the data / value stored at that location.

e.g.
Location 17 stores the value 19.

(We use this same memory table in all the examples below.)

2. Addressing Modes

What are addressing modes? Methods of accessing memory are known as addressing modes.

The 5 addressing modes① Immediate addressing   ② Direct addressing   ③ Indirect addressing
④ Indexed addressing   ⑤ Relative addressing

Concept of Accumulator (ACC): a place (register) where the results are stored. Every load instruction below ends with a value in ACC.

Instruction format: OPCODE = the instruction  |  OPERAND = the data / address on which the opcode is applied

3. Immediate Addressing — LDM

OPCODEOPERANDAcc LDM# 100 100
LDM #100 → ACC = 100
LDM = Immediate addressing: just load the value which is written next to the LDM instruction (the # means "the number itself").
No memory is accessed.

4. Direct Addressing — LDD

Note: memory will be involved.

LDD <address> = Direct addressing.

  1. Step 1: go to the given address
  2. Step 2: load the value on that address into the Accumulator.
Location / AddressContent
1525
1635
1719
1855
1930
2922
3015
317
OPCODEOPERANDAcc LDD17 19
LDD 17 → go to address 17 → content 19 → ACC = 19

5. Indirect Addressing — LDI

Note: memory will be involved (2 addresses).

LDI <first address> = Indirect addressing.

  1. Step 1: go to the given address — it holds the address of the address
  2. Step 2: go to the second address and load the value in ACC.
Location / AddressContent
1525
1635
1719
1855
1930
2922
3015
317
OPCODEOPERANDAcc LDI17 30
first address = 17
LDI 17address 17 contains 19 → this is the 2nd addressaddress 19 contains 30ACC = 30

6. Indexed Addressing — LDX

Note: calculation is required. There is a special register called the Index Register (IX).

LDX <initial address> = Indexed addressing.

  1. Step 1: add the initial address with IX and create a new address
  2. Step 2: use the new address and load that value in ACC.
new address = operand + [IX]
Location / AddressContent
1525
1635
1719
1855
1930
2922
3015
317
IX9
LDX 10,   IX = 910 + [IX] = 10 + 9new address = 19content of 19 = 30
Board discrepancy (corrected): the board wrote ACC = 22 for this example, but 22 is the content of address 29. With LDX 10 and IX = 9 the new address is 19, whose content is 30. (To get 22 you would need new address 29, e.g. LDX 20 with IX = 9.)
Note: Relative addressing (⑤) was left by the teacher to be discussed with a past-paper example — see Section 9.

7. Instruction Groups

GroupWhat it does
Data movementAccessing the value and loading it in the accumulator
Input and output of dataTakes an input from the user and outputs the character of a binary number (ASCII code)
Arithmetic operationsPerform addition and subtraction
Unconditional and conditional instructionsMove to another instruction (identified by labels / addresses)
Compare instructionsCompare the result to another value

Instruction set (9618 reference table)

Op CodeOperandExplanation
LDM#nImmediate addressing. Load the number n to ACC
LDD<address>Direct addressing. Load the contents of the location at the given address to ACC
LDI<address>Indirect addressing. The address to be used is at the given address. Load the contents of this second address to ACC
LDX<address>Indexed addressing. Form the address from <address> + the contents of the index register. Copy the contents of this calculated address to ACC
LDR#nImmediate addressing. Load the number n to IX
STO<address>Store the contents of ACC at the given address
ADD<address>Add the contents of the given address to the ACC
INC<register>Add 1 to the contents of the register (ACC or IX)
DEC<register>Subtract 1 from the contents of the register (ACC or IX)
JMP<address>Jump to the given address
CMP<address>Compare the contents of ACC with the contents of <address>
CMP#nCompare the contents of ACC with number n
JPE<address>Following a compare instruction, jump to <address> if the compare was True
JPN<address>Following a compare instruction, jump to <address> if the compare was False
INKey in a character and store its ASCII value in ACC
OUTOutput to the screen the character whose ASCII value is stored in ACC
ENDReturn control to the operating system
Remember: JPE = jump if Equal (True). JPN = jump if Not equal (False).

The board marked CMP and JPN in this table as the pair to watch: CMP sets True/False, then JPE / JPN decides whether to jump.

8. Tracing a Program (Past-paper style)

Trace table for this program (instruction addresses 20–36). Memory: 100→65, 101→67, 102→69, 103→69, 104→68, 301→33. IX starts at 0.

AddrInstructionAddrInstruction
20LDM #029OUT
21STO 30030LDD 300
22CMP #031INC ACC
23JPE 2832STO 300
24LDX 10033INC IX
25ADD 30134CMP #2
26OUT35JPN 22
27JMP 3036END
28LDX 100
ASCII code6566676869979899100101
CharacterABCDEabcde
Teacher's CMP / JPN trick: at 34 → CMP #2 with ACC = 2 → "2 = 2" → True → JPN does not jump (it only jumps on False). Circled the ASCII 100 = d and ticked lines 24 & 35.
Instr. addrACC[300]IXOUTPUTWhy
200LDM #0
210STO 300
22, 23ACC 0 = 0 True → JPE jumps to 28
2865LDX: 100 + IX(0) = 100 → 65
29AOUT (65 = A)
300LDD 300
311INC ACC
321STO 300
331INC IX
34, 351 = 2 False → JPN jumps to 22
Instr. addrACC[300]IXOUTPUTWhy
221 = 0 False → JPE does not jump
2467LDX: 100 + IX(1) = 101 → 67
25100ADD 301: 67 + 33 = 100
26dOUT (100 = d)
27JMP 30
301LDD 300
312INC ACC
322STO 300
332INC IX
34, 352 = 2 True → JPN does not jump
36END

Final output: A d

9. Relative Addressing — LDV

Source: Papers Dock · Paper 1 · 9618 · "Relative and Symbolic Addressing" (past-paper example).

LDV #n (op code 1100 0011) — Relative addressing. Move to the address n locations from the address of the current instruction. Load the contents of this address into ACC.
target address = (address of LDV) + n
Op codeOperandBinaryExplanation
LDM#n1100 0001Immediate addressing. Load number n to ACC.
LDD<address>1100 0010Direct addressing. Load the contents of the given address to ACC.
LDV#n1100 0011Relative addressing. Move to the address n locations from the address of the current instruction. Load the contents of this address to ACC.
STO<address>1100 0100Store the contents of ACC at the given address.
DEC1100 0101Decrement the contents of ACC.
OUTCH1100 0111Output the character corresponding to the ASCII character code in ACC.
JNE<address>1110 0110Following a compare instruction, 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.

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

9618 P1 — part (b)trace table · [5]

Complete the trace table for the program below. ASCII: <Space> = 32, 3 = 51, B = 66, C = 67, X = 88. The teacher numbered each line 0–16 (instruction/data position) to count relative distances.

#LabelInstruction#LabelInstruction
0StartProg:LDV #CountDown9Finish:LDM #88
1CMP Num110OUTCH
2JNE CarryOn11END
3JMP Finish12CountDown:15
4CarryOn:OUTCH1332
5LDD CountDown1451
6DEC1567
7STO CountDown16Num1:32
8JMP StartProg

Key idea: the operand of LDV is the value held in CountDown (15 at first), so LDV #15 from address 0 moves to address 15 → 67. Each loop CountDown goes 15 → 14 → 13, so LDV reaches address 15, then 14, then 13 (teacher wrote "LDV #13" for the last).

+15 locations from the LDV instruction (relative!) addr 0 : LDVaddr 15 : 67
relative addressing: count n places from the address of the instruction itself

CMP / jump decisions the teacher wrote:

67 = 32 → False (JNE jumps to CarryOn → prints C)
51 = 32 → False (jumps again → prints 3)
32 = 32 → True (no jump → JMP Finish → LDM #88 → prints X)
ACCCountDownOUTPUTWhy
15initial value
67CLDV → address 15 = 67; ≠ 32 so JNE → OUTCH prints C
15LDD CountDown
1414DEC, STO CountDown
513LDV → address 14 = 51; ≠ 32 → prints "3" (51)
14LDD CountDown
1313DEC, STO CountDown
32LDV → address 13 = 32; = 32 True, no JNE jump
88XJMP Finish → LDM #88 → OUTCH prints X (88)

Output: C 3 X

10. Two-Pass Assembler & Symbol Table

9618 P1 — part (c)two-pass assembler

The program from (b) is translated using a two-pass assembler. It starts with a directive ORG #0100 which tells the assembler to load the first instruction at address 100.

The teacher's advice: read the code line by line and number each line from 100.

AddrLabelInstructionAddrLabelInstruction
100StartProg:LDV #CountDown109Finish:LDM #88
101CMP Num1110OUTCH
102JNE CarryOn111END
103JMP Finish112CountDown:15
104CarryOn:OUTCH11332
105LDD CountDown11451
106DEC11567
107STO CountDown116Num1:32
108JMP StartProg

Teacher's marks: ✗ beside JMP Finish (Finish not defined yet → still UNKNOWN), ✓ beside the Finish: line (label found → fill it in).

Symbol table — order of entries (circled numbers)

Symbolic addressAbsolute address
StartProg ①100 ②
CountDown ③UNKNOWN ④ → 112 ⑬
Num1 ⑤UNKNOWN ⑥ → 116 ⑭
CarryOn ⑦UNKNOWN ⑧ → 104 ⑪
Finish ⑨UNKNOWN ⑩ → 109 ⑫
Why this order? Line 100 StartProg label ①②. Line 100 operand CountDown ③④ (unknown). Line 101 Num1 ⑤⑥. Line 102 CarryOn ⑦⑧. Line 103 Finish ⑨⑩. Line 104 CarryOn label found → fill 104 ⑪. Line 109 Finish found → 109 ⑫. Line 112 CountDown → 112 ⑬. Line 116 Num1 → 116 ⑭. The first eleven entries (up to ⑪) is where the printed question stops "part way through the first pass".
9618 P1 — part (d)explain · [3]

Explain how the assembler made these entries to the symbol table.

  • The assembler scans the assembly language instructions in sequence
  • When it meets a symbolic address it checks to see if 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 symbol table, check if its absolute address is known
  • If the absolute address is known, it is entered in the appropriate cell
  • If the absolute address is not known, then leave it UNKNOWN
9618 P1 — (d)(i)name · [1]

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

Answer: Instruction table (maps each mnemonic → its binary op code; the 2nd pass uses it plus the symbol table to produce machine code)

Quick relation: Pass 1 → build the symbol table (labels → addresses). Pass 2 → use symbol table + instruction table to generate the executable (binary) file.

11. Practice — Relative Address Symbol Table

9618 P1 — part (e)symbol table · [6]

Program translated with a two-pass assembler. The symbol table (symbolic → relative address) shows only the first five entries: StartProg ①, 0 ②, Offset ③, UNKNOWN ④, Value ⑤. Complete the symbol table; use circled labels to show the order of entries.

#LabelInstruction#LabelInstruction
0StartProg:LDV #Offset6STO Offset
1CMP Value7JMP StartProg
2JPE EndProg8EndProg:END
3OUTCH9Offset:10
4LDD Offset10–1350, 65, 89, 32
5INC14Value:32

The board shows this question but the teacher did not write an answer on it.

Worked answer (added for practice — not on the board):
Same method as part (c): scan line by line, add a new symbol as UNKNOWN, fill it in when its label line is reached.
Symbolic addressRelative address
StartProg ①0 ②
Offset ③UNKNOWN ④ → 9 ⑩
Value ⑤UNKNOWN ⑥ → 14 ⑪
EndProg ⑦UNKNOWN ⑧ → 8 ⑨

Order: ⑦⑧ EndProg met at JPE (line 2); ⑨ EndProg: label at line 8 = 8; ⑩ Offset: label at line 9 = 9; ⑪ Value: label at line 14 = 14. (The 6 remaining entries ⑥–⑪ = the [6] marks.)

12. Quick Recap

✓ Addressing modes cheat-sheet
  • LDM #n — immediate: load the number itself (LDM #100 → ACC 100)
  • LDD addr — direct: go to address, load its content (LDD 17 → 19)
  • LDI addr — indirect: address holds another address; load from that (LDI 17 → 19 → 30)
  • LDX addr — indexed: operand + IX = new address, load from it (LDX 10, IX 9 → addr 19 → 30)
  • LDV #n — relative: n locations from the current instruction's address
✓ Key facts
  • Assembly = low-level; one step above machine code (binary)
  • OPCODE = instruction; OPERAND = data / address it works on; ACC = where results are stored
  • CMP then JPE (jump if True) / JPN or JNE (jump if False)
  • Two-pass assembler: pass 1 builds the symbol table, pass 2 (instruction table) builds the executable
  • Trace tables: go line by line, record every ACC / memory / IX / OUTPUT change