LC-3-汇编
以下是LC-3汇编语言操作的全面总结,涵盖指令、伪指令、语法规则及编程示例:
一、汇编程序结构
-
起始与结束
- .ORIG:定义程序起始地址(十六进制),如
.ORIG x3000
。 - .END:标记程序结束,必须位于代码末尾。
- .ORIG:定义程序起始地址(十六进制),如
-
代码与数据段
- 代码从
.ORIG
后开始,数据通常定义在代码段之后或单独区域。
- 代码从
二、伪指令(汇编器指令)
-
.FILL
- 分配一个字并初始化,如
LABEL .FILL x1234
或.FILL 42
(十进制)。
- 分配一个字并初始化,如
-
.BLKW
- 分配连续内存块(块大小由参数指定),如
ARRAY .BLKW 10
(分配10字空间)。
- 分配连续内存块(块大小由参数指定),如
-
.STRINGZ
- 分配以空字符(
\0
)结尾的字符串,如MSG .STRINGZ "Hello"
(占用6字:5字符+1空字符)。
- 分配以空字符(
-
其他伪指令
- .ZERO:填充指定数量的零(部分LC-3汇编器支持)。
- .EQU:定义符号常量(部分汇编器支持,如
SIZE .EQU 10
)。
三、标签与注释
-
标签(Labels)
- 定义符号地址,用于跳转或数据访问,如
LOOP ADD R1, R1, #1
。 - 标签后紧跟指令或伪操作,不单独占行。
- 定义符号地址,用于跳转或数据访问,如
-
注释
- 以分号
;
开始,如ADD R0, R0, #1 ; Increment counter
。
- 以分号
四、数据表示
- 立即数格式:
- 十进制:
#42
- 十六进制:
x2A
- 字符:
'A'
或 ASCII码x41
- 字符串:
.STRINGZ "ABC"
- 十进制:
五、LC-3指令集回顾(15条核心指令)
类别 | 指令 | 格式示例 | 功能 |
---|---|---|---|
运算 | ADD | ADD DR, SR1, SR2 |
加法 |
AND | AND DR, SR1, #5 |
按位与 | |
NOT | NOT DR, SR |
取反 | |
数据移动 | LD | LD DR, LABEL |
PC相对加载 |
LDI | LDI DR, LABEL |
间接加载 | |
LDR | LDR DR, BaseR, #6 |
基址+偏移加载 | |
LEA | LEA DR, LABEL |
加载有效地址 | |
ST | ST SR, LABEL |
PC相对存储 | |
STI | STI SR, LABEL |
间接存储 | |
STR | STR SR, BaseR, #6 |
基址+偏移存储 | |
控制流 | BR | BRnzp LOOP |
条件分支 |
JMP | JMP R6 |
跳转到寄存器地址 | |
JSR/JSRR | JSR SUB 或 JSRR R2 |
跳转子程序(保存PC到R7) | |
TRAP | TRAP x21 |
系统调用(如HALT为TRAP x25 ) |
|
RTI | RTI |
中断返回(特权指令) |
六、系统调用(TRAP指令)
TRAP向量 | 功能 | 输入/输出 |
---|---|---|
x20 |
GETC | 从键盘读取字符到R0 |
x21 |
OUT | 输出R0低8位的字符 |
x22 |
PUTS | 输出R0指向的字符串(以\0结尾) |
x23 |
IN | 输入字符并回显到屏幕 |
x24 |
PUTSP | 输出压缩字符串(每字节一个字符) |
x25 |
HALT | 终止程序 |
七、寻址模式
- 立即数:
ADD R1, R1, #5
- 寄存器:
ADD R1, R2, R3
- PC相对:
LD R0, LABEL
(地址 = PC + 偏移) - 基址+偏移:
LDR R0, R2, #-3
- 间接寻址:
LDI R0, LABEL
(两次内存访问) - 有效地址加载:
LEA R0, LABEL
(直接计算地址)
八、条件码(CC)
- 影响条件码的指令:ADD、AND、NOT、LD、LDI、LDR、LEA。
- 条件分支示例:
九、编程示例
; 示例:计算1+2+…+5并存储结果
.ORIG x3000
AND R0, R0, #0 ; R0 = 0(和)
AND R1, R1, #0 ; R1 = 0(计数器)
ADD R1, R1, #5 ; 循环5次
LOOP
ADD R0, R0, R1 ; 累加
ADD R1, R1, #-1 ; 计数器减1
BRp LOOP ; 若R1>0则继续循环
ST R0, RESULT ; 存储结果
HALT
RESULT .BLKW 1 ; 分配结果存储空间
.END
十、关键注意事项
-
寄存器约定:
R7
用于保存子程序返回地址(JSR/JSRR)。R5
和R6
常用作栈指针或临时变量(需手动管理栈)。
-
内存对齐:LC-3无严格对齐要求,但建议按字(2字节)访问。
-
中断与特权指令:
RTI
仅在特权模式下执行(通常用于操作系统)。
十一、汇编器过程
第一遍(Pass 1)
-
符号解析:
- 遍历代码,记录标签(如
LOOP
)的物理地址到符号表。 - 处理伪指令(如
.BLKW
)以分配内存并更新位置计数器。
- 遍历代码,记录标签(如
-
内存布局:
- 根据
.ORIG
确定起始地址,计算每条指令/数据的占用空间。
- 根据
第二遍(Pass 2)
-
机器码生成:
- 将指令转换为二进制码(如
ADD
→0001
)。 - 解析符号引用:
- PC相对寻址:计算标签与当前PC的偏移量(如
LD R0, LABEL
)。 - 基址+偏移:直接编码寄存器编号和偏移值(如
LDR R0, R2, #3
)。
- PC相对寻址:计算标签与当前PC的偏移量(如
- 将指令转换为二进制码(如
-
伪指令处理:
.STRINGZ
转为ASCII码并追加x0000
,.FILL
直接写入指定值。
十二、链接过程(理论说明)
-
核心任务:
- 合并目标文件:将多个
.obj
文件整合为单一可执行文件。 - 符号重定位:调整跨模块的跳转地址(如
JSR SUB
指向子程序实际地址)。
- 合并目标文件:将多个
-
LC-3实践限制:
- 标准工具链(如
lc3as
)仅支持单文件汇编,需手动合并代码或使用.INCLUDE
。
- 标准工具链(如
以上内容覆盖LC-3汇编语言的全部核心操作,包括指令、伪指令、系统调用及编程范式。通过结合指令集和伪指令,可以高效编写底层程序。