Assembly language and addressing modes · 汇编语言与寻址模式
| English | 中文 | Pinyin · 拼音 |
|---|---|---|
| assembler/əˈsemblə/ | 汇编器 | huì biān qì |
| mnemonic/nɪˈmɒnɪk/ | 助记符 | zhù jì fú |
| instruction set/ɪnˈstrʌkʃn set/ | 指令集 | zhǐ lìng jí |
| machine code/məˈʃiːn kəʊd/ | 机器码 | jī qì mǎ |
| assembly language/əˈsemblɪ ˈlæŋɡwɪdʒ/ | 汇编语言 | huì biān yǔ yán |
| operand/ˈɒpərænd/ | 操作数 | cāo zuò shù |
| opcode/ˈɒpkəʊd/ | 操作码 | cāo zuò mǎ |
| symbol table/ˈsɪmbl ˈteɪbl/ | 符号表 | fú hào biǎo |
| label/ˈleɪbl/ | 标签 | biāo qiān |
| forward references/ˈfɔːwəd ˈrefrənsɪz/ | 前向引用 | qián xiàng yǐn yòng |
| addressing mode/əˈdresɪŋ məʊd/ | 寻址方式 | xún zhǐ fāng shì |
| immediate addressing/ɪˈmiːdɪət əˈdresɪŋ/ | 立即寻址 | lì jí xún zhǐ |
| direct addressing/daɪˈrekt əˈdresɪŋ/ | 直接寻址 | zhí jiē xún zhǐ |
| indirect addressing/ɪndaɪˈrekt əˈdresɪŋ/ | 间接寻址 | jiàn jiē xún zhǐ |
| indexed addressing/ˈɪndekst əˈdresɪŋ/ | 变址寻址 | biàn zhǐ xún zhǐ |
| relative addressing/ˈrelətɪv əˈdresɪŋ/ | 相对寻址 | 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.
一排开关上的三十一条指令
- 1949 年,剑桥的 EDSAC 计算机从拨在开关上的 31 条指令启动,这些指令由 David Wheeler 编写,称为"初始命令"。
- 它们的全部工作是从纸带上读取 A 和 S 这样的字母,并把它们变成机器真正理解的数字:第一个汇编器(assembler)。
- 从那以后程序员就一直用助记符代替比特模式来写程序,考试自己的指令集正是它的直系后代。
- 这一课讲这种翻译、手工跟踪一个程序,以及一条指令表明它的数据在哪里的五种方式。
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
机器码和汇编语言
- 处理器运行机器码(machine code):比特模式,专属于一种体系结构,每条都是一个操作码加一个操作数。
- 汇编语言(assembly language)是可读的形式。每条指令用
LDD、ADD或JMP这样的助记符(mnemonic)书写,每条汇编指令变成恰好一条机器码指令。 - 汇编器翻译它。这种关系是一对一的,这正是汇编与高级语言的不同之处——高级语言的一条语句会变成许多条指令。

每个助记符变成一个操作码;每个符号地址变成一个数字
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.
两遍汇编器
- 第一遍读源程序并建立符号表(symbol table):每当出现
LOOP:这样的标签(label),就记下它的地址。不产生代码。 - 第二遍再读一次源程序并生成代码,把每个助记符换成它的操作码(opcode),把每个符号地址换成符号表里的数字。
- 需要两遍是因为前向引用(forward references):
JMP LOOP可能在看到LOOP:那一行之前就出现,所以第一遍时它的地址还不知道。
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.
- 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.
例题:应用两遍过程
- 程序从地址 100 开始。
100 LDD COUNT
101 LOOP: DEC ACC
102 CMP #0
103 JPN LOOP
104 END
105 COUNT: 5
- 第一遍数出每一行的地址并记录标签:
LOOP= 101,COUNT= 105。其他什么都不写。 - 第二遍逐行翻译。
LDD COUNT变成LDD的操作码加操作数(operand)105;JPN LOOP变成JPN的操作码加操作数 101。没有第一遍,第一行就无法翻译。
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. · 在例题中,第一遍在符号表里为标签 LOOP 记录的地址是 ____。
The program starts at 100, so the second line, LOOP: DEC ACC, occupies 101. COUNT, on the sixth line, is 105. · 程序从 100 开始,所以第二行 LOOP: DEC ACC 占 101。第六行的 COUNT 是 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.
指令集
- 剑桥的指令集(instruction set)有一个通用寄存器——累加器 ACC——和一个变址寄存器 IX。操作数
#n是十进制,Bn是二进制,&n是十六进制,<address>是单元编号或标签。 - 数据传送:
LDM #n、LDD <address>、LDI <address>、LDX <address>、LDR #n、MOV IX、STO <address>。输入输出:IN、OUT。 - 算术:
ADD、SUB、INC、DEC。比较:CMP、CMI。跳转:JMP无条件,JPE和JPN有条件。位操作:AND、OR、XOR、LSL、LSR。然后END。 - "指令是分组的":说出各组的名字,并各举一条指令。
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.
- 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.
例题:跟踪一个程序
- 画一张表,ACC 一列,程序用到的每个存储单元各一列,然后逐行更新直到
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
- 循环第 1 轮:ACC 0 → 5(TOTAL = 5),COUNT 3 → 2,比较不相等,跳转。第 2 轮:TOTAL = 10,COUNT = 1,跳转。第 3 轮:TOTAL = 15,COUNT = 0,比较相等,不跳转,
END。 - 最终值:TOTAL = 15,COUNT = 0,ACC = 0。只在值改变时写新的一行,而且永远不要跳过比较。
In the traced program, what is the value of TOTAL when END is reached? · 在跟踪的程序中,到达 END 时 TOTAL 的值是多少?
The loop adds 5 to TOTAL once for each of the three passes: 5, 10, 15. · 循环三轮,每轮给 TOTAL 加 5: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
寻址方式
- 寻址方式(addressing mode)说明处理器怎样找到操作数。
| 方式 | 操作数在哪里 | 例子 |
|---|---|---|
| 立即寻址(immediate addressing) | 值就在指令本身里 | LDM #10 加载 10 |
| 直接寻址(direct addressing) | 指令里有一个地址;用存在那里的值 | LDD 200 加载 200 的内容 |
| 间接寻址(indirect addressing) | 该地址里存着另一个地址,那里才是数据 | LDI 200 |
| 变址寻址(indexed addressing) | 有效地址 = 给出的地址 + 变址寄存器 | LDX 200 加上 IX |
| 相对寻址(relative addressing) | 地址是相对当前指令的偏移 | 跳转 |

同一个操作数字段,四种不同的含义
In immediate addressing (e.g. LDM #10), the operand is: · 在立即寻址(例如 LDM #10)中,操作数是:
Immediate addressing uses the literal value in the instruction (here, 10). · 立即寻址使用指令中的字面值(这里是 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.
例题:一个操作数,四个答案
- 存储器:单元 200 存着 300,单元 300 存着 7,单元 202 存着 9。变址寄存器 IX 存着 2。
LDM #200把 200 放进 ACC:立即,就是这个数本身。LDD 200把 300 放进 ACC:直接,200 的内容。LDI 200把 7 放进 ACC:间接,在 200 找到的那个地址的内容。LDX 200把 IX 加到 200 上并加载 202 的内容:9。同一个操作数四种写法,四个不同的值。
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.
变址寻址为什么存在
- 数组是一串连续的单元。
LDX 200配 IX = 0、1、2……依次读元素 0、1、2……而不用改指令。 - 循环模式:
LDR #0把索引清零,LDX ARRAY取一个元素,做点什么,INC IX,与长度比较,JPN跳回去。 - 直接寻址需要为每个元素写一条单独的指令;变址寻址只需要一条。
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 #n或CMP <address>把 ACC 与一个值比较并设置标志。它不改变 ACC。JPE <address>在上次比较相等时跳转;JPN <address>在不相等时跳转;JMP <address>总是跳转。- 高级语言里的
IF变成一条CMP加一条条件跳转;循环变成一次比较加一条跳回标签的跳转。
CMP #0 changes the value held in the accumulator. · CMP #0 会改变累加器中保存的值。
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. · 比较只设置下一条条件跳转要读的标志。ACC 不变,这就是为什么跟踪表在 CMP 行上没有新的 ACC 值。
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.
容易丢掉的分
LDM #10加载数字 10;LDD 10加载单元 10 的内容。#就是全部区别。#是十进制,B是二进制,&是十六进制。AND &0F和AND B00001111是同一个掩码;AND #15也是。CMP不动 ACC;它只设置标志。JPN在值不相等时跳转。- 汇编器的第一遍不写代码。它的输出是符号表,前向引用是它存在的理由。
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
你掌握了
- 机器码是比特模式;汇编是助记符,一对一,由汇编器翻译
- 两遍:第一遍建立标签地址的符号表,第二遍生成代码;为前向引用而需要
- 用 ACC 和每个单元的表跟踪,每次改变一行;CMP 设置标志,JPE/JPN 读它
- 寻址:立即
#n值本身 · 直接 地址的内容 · 间接 地址的地址 · 变址 地址 + IX(数组)· 相对 一个偏移