Assembly language and addressing modes
| English | Chinese | Pinyin |
|---|---|---|
| assembler | 汇编器 | huì biān qì |
| mnemonic | 助记符 | zhù jì fú |
| instruction set | 指令集 | zhǐ lìng jí |
| machine code | 机器码 | jī qì mǎ |
| assembly language | 汇编语言 | huì biān yǔ yán |
| operand | 操作数 | cāo zuò shù |
| opcode | 操作码 | cāo zuò mǎ |
| symbol table | 符号表 | fú hào biǎo |
| label | 标签 | biāo qiān |
| forward references | 前向引用 | qián xiàng yǐn yòng |
| addressing mode | 寻址方式 | xún zhǐ fāng shì |
| immediate addressing | 立即寻址 | lì jí xún zhǐ |
| direct addressing | 直接寻址 | zhí jiē xún zhǐ |
| indirect addressing | 间接寻址 | jiàn jiē xún zhǐ |
| indexed addressing | 变址寻址 | biàn zhǐ xún zhǐ |
| relative addressing | 相对寻址 | xiāng duì xún zhǐ |
Thirty-one instructions on a row of switches
- In 1949 the EDSAC computer in Cambridge started up from 31 instructions set on switches, written by David Wheeler and called the "initial orders".
- Their whole job was to read letters such as A and S from paper tape and turn them into the numbers the machine actually understood: the first assembler 汇编器.
- Programmers have written mnemonics instead of bit patterns ever since, and the exam's own instruction set is a direct descendant.
- This lesson is about that translation, tracing a program by hand, and the five ways an instruction can say where its data is.
Machine code and assembly language
- The processor runs machine code 机器码: bit patterns, specific to one architecture, each one an operation code and an operand.
- Assembly language 汇编语言 is the readable form. Each instruction is written with a mnemonic 助记符 such as
LDD,ADDorJMP, and each assembly instruction becomes exactly one machine-code instruction. - The assembler translates it. The relationship is one to one, which is what makes assembly different from a high-level language, where one statement becomes many instructions.

Each mnemonic becomes one opcode; each symbolic address becomes a number
Assembly language is:
Assembly uses mnemonics and maps one-to-one to machine code; an assembler translates it.
The two-pass assembler
- Pass 1 reads the source and builds a symbol table 符号表: every time a label 标签 such as
LOOP:appears, its address is recorded. No code is produced. - Pass 2 reads the source again and generates the code, replacing each mnemonic by its opcode 操作码 and each symbolic address by the number from the symbol table.
- Two passes are needed because of forward references 前向引用:
JMP LOOPmay appear before the lineLOOP:has been seen, so its address is not known on the first pass.
What does pass 1 of a two-pass assembler do?
Pass 1 records where each label is (the symbol table); pass 2 then generates code, using the table to resolve label references.
Put the two-pass assembler's work in order.
Pass 1 finds all the labels first, so pass 2 can resolve even a jump to a label defined later.
Why does the assembler need two passes?
A jump may target a label that appears later in the source; pass 1 finds all labels first so pass 2 can resolve them.
Worked example: applying the two passes
- The program starts at address 100.
100 LDD COUNT
101 LOOP: DEC ACC
102 CMP #0
103 JPN LOOP
104 END
105 COUNT: 5
- Pass 1 counts the address of each line and records the labels:
LOOP= 101,COUNT= 105. Nothing else is written. - Pass 2 translates line by line.
LDD COUNTbecomes the opcode forLDDwith operand 操作数 105;JPN LOOPbecomes the opcode forJPNwith operand 101. Without pass 1, the first line could not have been translated.
How a two-pass assembler works
Step through it. The assembler reads your code twice: pass 1 just finds where every label lives, so pass 2 can fill in the addresses — that is how a jump to a label defined later still works.
In the worked example, pass 1 records the label LOOP with the address ____ in the symbol table.
The program starts at 100, so the second line, LOOP: DEC ACC, occupies 101. COUNT, on the sixth line, is 105.
The instruction set
- Cambridge's instruction set 指令集 has one general-purpose register, the accumulator ACC, and an index register IX. An operand
#nis denary,Bnbinary,&nhexadecimal, and<address>a location number or a label. - Data movement:
LDM #n,LDD <address>,LDI <address>,LDX <address>,LDR #n,MOV IX,STO <address>. Input and output:IN,OUT. - Arithmetic:
ADD,SUB,INC,DEC. Compare:CMP,CMI. Jumps:JMPunconditional,JPEandJPNconditional. Bit manipulation:AND,OR,XOR,LSL,LSR. ThenEND. - "Instructions are grouped": name the groups and give one instruction from each.
Which of these are groups in the instruction set? Select all that apply.
Data movement, input/output, arithmetic, compare, conditional and unconditional jumps, and bit manipulation. A spreadsheet is application software, far above this level.
Worked example: tracing a program
- Draw a table with a column for the ACC and for every memory location the program uses, then update it line by line until
END.
100 LDM #0
101 STO TOTAL
102 LDD TOTAL
103 ADD #5
104 STO TOTAL
105 LDD COUNT
106 DEC ACC
107 STO COUNT
108 CMP #0
109 JPN 102
110 END
111 TOTAL: 0
112 COUNT: 3
- Pass 1 of the loop: ACC 0 → 5 (TOTAL = 5), COUNT 3 → 2, compare not equal, jump. Pass 2: TOTAL = 10, COUNT = 1, jump. Pass 3: TOTAL = 15, COUNT = 0, compare equal, no jump,
END. - Final values: TOTAL = 15, COUNT = 0, ACC = 0. Write a new row only when a value changes, and never skip the compare.
In the traced program, what is the value of TOTAL when END is reached?
The loop adds 5 to TOTAL once for each of the three passes: 5, 10, 15.
Addressing modes
- The addressing mode 寻址方式 says how the processor finds the operand.
| Mode | Where the operand is | Example |
|---|---|---|
| immediate addressing 立即寻址 | the value is in the instruction itself | LDM #10 loads 10 |
| direct addressing 直接寻址 | the instruction holds an address; use the value stored there | LDD 200 loads the contents of 200 |
| indirect addressing 间接寻址 | the address holds another address, which holds the data | LDI 200 |
| indexed addressing 变址寻址 | effective address = the address given + the index register | LDX 200 with IX |
| relative addressing 相对寻址 | the address is an offset from the current instruction | jumps |

The same operand field, four different meanings
In immediate addressing (e.g. LDM #10), the operand is:
Immediate addressing uses the literal value in the instruction (here, 10).
Match each addressing mode to its meaning.
Immediate = value; direct = address of the value; indirect = address of an address; indexed = base + index.
Worked example: one operand, four answers
- Memory: location 200 holds 300, location 300 holds 7, location 202 holds 9. The index register IX holds 2.
LDM #200puts 200 in the ACC: immediate, the number itself.LDD 200puts 300 in the ACC: direct, the contents of 200.LDI 200puts 7 in the ACC: indirect, the contents of the address found at 200.LDX 200adds IX to 200 and loads the contents of 202: 9. Same operand written four ways, four different values.
Why indexed addressing exists
- An array is a run of consecutive locations.
LDX 200with IX = 0, 1, 2, … reads element 0, 1, 2, … without changing the instruction. - The loop pattern:
LDR #0to zero the index,LDX ARRAYto fetch an element, do something,INC IX, compare with the length,JPNback. - Direct addressing would need a separate instruction for every element; indexed addressing needs one.
Indexed addressing is most useful for:
The effective address is base address + index register, so increasing the index walks through an array.
Compare and jump
CMP #norCMP <address>compares the ACC with a value and sets the flag. It does not change the ACC.JPE <address>jumps if the last compare found the values equal;JPN <address>jumps if they were not equal;JMP <address>always jumps.- An
IFin a high-level language becomes aCMPfollowed by a conditional jump; a loop becomes a compare and a jump back to a label.
CMP #0 changes the value held in the accumulator.
A compare only sets the flag that the next conditional jump reads. The ACC is unchanged, which is why the trace shows no new ACC value on a CMP line.
Marks that slip away
LDM #10loads the number 10;LDD 10loads the contents of location 10. The#is the whole difference.#is denary,Bis binary,&is hexadecimal.AND &0FandAND B00001111are the same mask;AND #15is too.CMPleaves the ACC alone; it only sets the flag.JPNjumps when the values are not equal.- Pass 1 of the assembler writes no code. Its output is the symbol table, and forward references are the reason it exists.
You've got it
- machine code is bit patterns; assembly is mnemonics, one to one, translated by an assembler
- two passes: pass 1 builds the symbol table of label addresses, pass 2 generates code; needed for forward references
- trace with a table of ACC and every location, one row per change; CMP sets the flag, JPE/JPN read it
- addressing: immediate
#nthe value · direct the contents of the address · indirect the address of the address · indexed address + IX (arrays) · relative an offset