13 KiB
附录三:汇编指令集
一、数据传送指令
1. 通用数据传送指令MOV
格式: MOV dst, src
功能: 将src的内容传送到dst。
支持的传送方式:
| 指令 | 操作 |
|---|---|
| MOV r/m8, r8 | 将8位寄存器传送到8位寄存器/内存 |
| MOV r/m16, r16 | 将16位寄存器传送到16位寄存器/内存 |
| MOV r8, r/m8 | 将8位寄存器/内存传送到8位寄存器 |
| MOV r16, r/m16 | 将16位寄存器/内存传送到16位寄存器 |
| MOV r/m8, i8 | 将8位立即数传送到8位寄存器/内存 |
| MOV r/m16, i16 | 将16位立即数传送到16位寄存器/内存 |
| MOV r8, i8 | 将8位立即数传送到8位寄存器 |
| MOV r16, i16 | 将16位立即数传送到16位寄存器 |
| MOV r/m16, sreg | 将段寄存器传送到16位寄存器/内存 |
| MOV sreg, r/m16 | 将16位寄存器/内存传送到段寄存器 |
注意: 立即数不能作为dst;不允许直接传送到段寄存器;代码段寄存器CS不能作为dst。
2. 堆栈操作指令PUSH和POP
格式:
PUSH src ;将src压入堆栈
POP dst ;从堆栈弹出到dst
功能: PUSH将16位寄存器/内存入栈,POP从堆栈弹出到16位寄存器/内存。
注意: 必须16位操作;不能压入立即数。
3. 交换指令XCHG
格式: XCHG opr1, opr2
功能: 将两个操作数的内容互换。
支持的传送方式:
| 指令 | 操作 |
|---|---|
| XCHG r, r | 两个寄存器互换 |
| XCHG r, m | 寄存器和内存互换 |
4. 查表转换指令XLAT
格式: XLAT
功能: 将AL中的内容转换为内存表格中某一项的值。即AL←[BX+AL]
5. 标志传送指令
| 指令 | 操作 |
|---|---|
| LAHF | 将标志寄存器低8位传送到AH:AH←FLAGS低8位 |
| SAHF | 将AH传送到标志寄存器低8位:FLAGS低8位←AH |
| PUSHF | 将16位标志寄存器压入堆栈:PUSH FLAGS |
| POPF | 从堆栈弹出到16位标志寄存器:POP FLAGS |
6. 地址传送指令
| 指令 | 操作 |
|---|---|
| LEA r16, src | 将src的有效地址传送到16位寄存器 |
| LDS r16, src | 将src的段地址传送到DS,有效地址传送到16位寄存器 |
| LES r16, src | 将src的段地址传送到ES,有效地址传送到16位寄存器 |
7. 输入输出指令
| 指令 | 操作 |
|---|---|
| IN AL, port | 从端口输入一个字节到AL |
| IN AX, port | 从端口输入一个字到AX |
| OUT port, AL | 将AL输出到端口 |
| OUT port, AX | 将AX输出到端口 |
注意: port为8位立即数表示固定端口;DX表示可变端口(0-65535)。
二、算术运算指令
1. 加法指令
(1)ADD指令
格式:ADD dst, src
功能:dst←dst+src
| 指令 | 操作 |
|---|---|
| ADD r/m8, r8 | 8位加法 |
| ADD r/m16, r16 | 16位加法 |
| ADD r8, r/m8 | 8位加法 |
| ADD r16, r/m16 | 16位加法 |
| ADD r/m8, i8 | 8位加立即数 |
| ADD r/m16, i16 | 16位加立即数 |
(2)ADC指令
格式:ADC dst, src
功能:dst←dst+src+CF(带进位加法)
(3)INC指令
格式:INC opr
功能:opr←opr+1(加1)
2. 减法指令
(1)SUB指令
格式:SUB dst, src
功能:dst←dst-src
(2)SBB指令
格式:SBB dst, src
功能:dst←dst-src-CF(带借位减法)
(3)DEC指令
格式:DEC opr
功能:opr←opr-1(减1)
(4)NEG指令
格式:NEG opr
功能:opr←0-opr(求补)
3. 乘法指令
(1)MUL指令
格式:MUL src
功能:
- 8位:AX←AL*src
- 16位:DX:AX←AX*src
(2)IMUL指令
格式:IMUL src
功能:带符号整数乘法
4. 除法指令
(1)DIV指令
格式:DIV src
功能:
- 8位:AL←AX/src(商),AH←AX/src(余数)
- 16位:AX←DX:AX/src(商),DX←DX:AX/src(余数)
(2)IDIV指令
格式:IDIV src
功能:带符号整数除法
5. 十进制调整指令
| 指令 | 操作 |
|---|---|
| DAA | 加法后十进制调整 |
| DAS | 减法后十进制调整 |
| AAA | 加法后ASCII调整 |
| AAS | 减法后ASCII调整 |
| AAM | 乘法后ASCII调整 |
| AAD | 除法前ASCII调整 |
三、逻辑运算和移位指令
1. 逻辑运算指令
| 指令 | 功能 |
|---|---|
| AND dst, src | 逻辑与 |
| OR dst, src | 逻辑或 |
| NOT opr | 逻辑非 |
| XOR dst, src | 逻辑异或 |
| TEST opr1, opr2 | 测试(与但不保存结果) |
2. 移位指令
| 指令 | 功能 |
|---|---|
| SHL opr, cnt | 逻辑左移 |
| SAL opr, cnt | 算术左移 |
| SHR opr, cnt | 逻辑右移 |
| SAR opr, cnt | 算术右移 |
| ROL opr, cnt | 循环左移 |
| ROR opr, cnt | 循环右移 |
| RCL opr, cnt | 带进位循环左移 |
| RCR opr, cnt | 带进位循环右移 |
注意: cnt=1或CL;算术移位保持符号位;循环移位把CF包含在环中。
四、串操作指令
1. 基本字符串指令
| 指令 | 操作 |
|---|---|
| MOVS dst, src | 移动字节/字串 |
| MOVSB | 移动字节串 |
| MOVSW | 移动字串 |
| CMPS dst, src | 比较字节/字串 |
| CMPSB | 比较字节串 |
| CMPSW | 比较字串 |
| SCAS dst | 扫描字节/字串 |
| SCASB | 扫描字节串 |
| SCASW | 扫描字串 |
| LODS src | 装入字节/字串 |
| LODSB | 装入字节串 |
| LODSW | 装入字串 |
| STOS dst | 存储字节/字串 |
| STOSB | 存储字节串 |
| STOSW | 存储字串 |
2. 串操作指令前缀
| 前缀 | 功能 |
|---|---|
| REP | 当CX≠0时重复 |
| REPE/REPZ | 当ZF=1且CX≠0时重复 |
| REPNE/REPNZ | 当ZF=0且CX≠0时重复 |
3. 重复前缀的使用
;将DS:SI处的100个字节传送到ES:DI处
CLD
LEA SI, SOURCE
LEA DI, DEST
MOV CX, 100
REP MOVSB
五、控制转移指令
1. 无条件转移指令
| 指令 | 操作 |
|---|---|
| JMP target | 无条件转移到目标地址 |
| CALL target | 调用过程 |
| RET | 从过程返回 |
| RETN | 从近过程返回 |
| RETF | 从远过程返回 |
2. 条件转移指令
(1)单条件标志转移
| 指令 | 含义 | 测试条件 |
|---|---|---|
| JE/JZ | 等于/为零转移 | ZF=1 |
| JNE/JNZ | 不等于/非零转移 | ZF=0 |
| JC | 进位转移 | CF=1 |
| JNC | 无进位转移 | CF=0 |
| JO | 溢出转移 | OF=1 |
| JNO | 无溢出转移 | OF=0 |
| JS | 符号位为1转移 | SF=1 |
| JNS | 符号位为0转移 | SF=0 |
| JP/JPE | 奇偶性为1转移 | PF=1 |
| JNP/JPO | 奇偶性为0转移 | PF=0 |
(2)无符号数比较转移
| 指令 | 含义 | 测试条件 |
|---|---|---|
| JA/JNBE | 高于/不低于等于转移 | CF=0且ZF=0 |
| JAE/JNB | 高于或等于/不低于转移 | CF=0 |
| JB/JNAE | 低于/不高于等于转移 | CF=1 |
| JBE/JNA | 低于或等于/不高于转移 | CF=1或ZF=1 |
(3)带符号数比较转移
| 指令 | 含义 | 测试条件 |
|---|---|---|
| JG/JNLE | 大于/不小于等于转移 | ZF=0且SF=OF |
| JGE/JNL | 大于或等于/不小于转移 | SF=OF |
| JL/JNGE | 小于/不大于等于转移 | SF≠OF |
| JLE/JNG | 小于或等于/不大于转移 | ZF=1或SF≠OF |
3. 循环控制指令
| 指令 | 操作 | 测试条件 |
|---|---|---|
| LOOP | 循环 | CX≠0 |
| LOOPE/LOOPZ | 相等/为零循环 | ZF=1且CX≠0 |
| LOOPNE/LOOPNZ | 不相等/非零循环 | ZF=0且CX≠0 |
| JCXZ | CX为零转移 | CX=0 |
4. 中断指令
| 指令 | 操作 |
|---|---|
| INT n | 调用中断号n的中断处理程序 |
| INTO | 溢出中断 |
| IRET | 中断返回 |
六、处理器控制指令
1. 标志操作指令
| 指令 | 操作 |
|---|---|
| STC | 进位标志置1:CF←1 |
| CLC | 进位标志清0:CF←0 |
| CMC | 进位标志取反:CF←NOT CF |
| STD | 方向标志置1:DF←1 |
| CLD | 方向标志清0:DF←0 |
| STI | 中断允许标志置1:IF←1 |
| CLI | 中断允许标志清0:IF←0 |
2. 同步与空操作指令
| 指令 | 操作 |
|---|---|
| NOP | 空操作,不执行任何操作 |
| HLT | 暂停,处理器停止并等待中断或复位信号 |
| WAIT | 等待,处理器进入等待状态直到BUSREQ有效 |
| ESC | 换码,用于与协处理器通信 |
| LOCK | 锁定前缀,禁止其他处理器访问共享内存 |
3. 段寄存器传送指令
| 指令 | 操作 |
|---|---|
| LDS r16, mem32 | 将内存中的32位地址装入DS和寄存器 |
| LES r16, mem32 | 将内存中的32位地址装入ES和寄存器 |
| LFS r16, mem32 | 将内存中的32位地址装入FS和寄存器 |
| LGS r16, mem32 | 将内存中的32位地址装入GS和寄存器 |
| LSS r16, mem32 | 将内存中的32位地址装入SS和寄存器 |
4. 转换指令
| 指令 | 操作 |
|---|---|
| CBW | 将AL中的字节扩展为AX(符号扩展) |
| CWD | 将AX中的字扩展为DX:AX(符号扩展) |
| CWDE | 将AX中的字扩展为EAX(符号扩展) |
| CDQ | 将EAX中的双字扩展为EDX:EAX(符号扩展) |
| MOVSX r16, r/m8 | 将8位符号扩展为16位 |
| MOVSX r16, r/m16 | 将16位符号扩展为16位 |
| MOVSX r32, r/m8 | 将8位符号扩展为32位 |
| MOVSX r32, r/m16 | 将16位符号扩展为32位 |
| MOVZX r16, r/m8 | 将8位零扩展为16位 |
| MOVZX r16, r/m16 | 将16位零扩展为16位 |
| MOVZX r32, r/m8 | 将8位零扩展为32位 |
| MOVZX r32, r/m16 | 将16位零扩展为32位 |
七、伪指令
1. 数据定义伪指令
| 伪指令 | 操作 |
|---|---|
| DB | 定义字节,每个操作数占1字节 |
| DW | 定义字,每个操作数占2字节 |
| DD | 定义双字,每个操作数占4字节 |
| DQ | 定义四字,每个操作数占8字节 |
| DT | 定义十字节,每个操作数占10字节 |
2. 段定义伪指令
| 伪指令 | 操作 |
|---|---|
| SEGMENT | 定义段的开始 |
| ENDS | 定义段的结束 |
| PROC | 定义过程的开始 |
| ENDP | 定义过程的结束 |
| ASSUME | 告诉汇编程序段寄存器与段的对应关系 |
3. 程序结束伪指令
| 伪指令 | 操作 |
|---|---|
| END | 表示源程序结束,END后面的标号表示程序入口 |
| END [标号] | 标记源代码结束 |
4. 处理器方式伪指令
| 伪指令 | 操作 |
|---|---|
| .386 | 允许使用80386指令 |
| .386P | 允许使用80386保护模式指令 |
| .8086 | 只允许8086/8088指令(默认) |
5. 简化段定义伪指令
| 伪指令 | 操作 |
|---|---|
| .MODEL | 选择存储模型 |
| .DATA | 定义数据段 |
| .CODE | 定义代码段 |
| .STACK | 定义堆栈段 |
| PROC | 定义过程 |
| ENDP | 过程结束 |
| END | 程序结束 |
八、寄存器与数据类型
1. 通用寄存器
| 8位寄存器 | 16位寄存器 | 32位寄存器 |
|---|---|---|
| AL, AH | AX | EAX |
| BL, BH | BX | EBX |
| CL, CH | CX | ECX |
| DL, DH | DX | EDX |
| - | SP | ESP |
| - | BP | EBP |
| - | SI | ESI |
| - | DI | EDI |
2. 段寄存器
CS:代码段寄存器 DS:数据段寄存器 ES:附加段寄存器 SS:堆栈段寄存器
3. 控制寄存器
IP:指令指针寄存器 FLAGS:标志寄存器
4. 数据类型
| 类型 | 大小 |
|---|---|
| BYTE | 8位 |
| WORD | 16位 |
| DWORD | 32位 |
| QWORD | 64位 |
| TBYTE | 80位 |
九、寻址方式
1. 立即寻址
操作数是立即数,直接包含在指令中。
MOV AX, 1234H
2. 寄存器寻址
操作数在寄存器中。
MOV AX, BX
3. 直接寻址
操作数的偏移地址直接包含在指令中。
MOV AX, [1000H]
MOV AX, VARIABLE
4. 寄存器间接寻址
操作数的偏移地址在基址寄存器或变址寄存器中。
MOV AX, [BX]
MOV AX, [SI]
5. 寄存器相对寻址
操作数地址=基址/变址寄存器+位移量。
MOV AX, [BX+100H]
MOV AX, [SI+10]
6. 基址变址寻址
操作数地址=基址寄存器+变址寄存器。
MOV AX, [BX+SI]
7. 基址变址相对寻址
操作数地址=基址寄存器+变址寄存器+位移量。
MOV AX, [BX+SI+10]
8. 隐含寻址
操作数地址隐含在某个寄存器或存储单元中。
MUL BL ;AL*BL→AX
XLAT ;[BX+AL]→AL
十、常用DOS功能调用
1. 显示字符串(功能号09H)
AH=09H
DS:DX=字符串地址
字符串以'$'结尾,需要回车换行时使用0DH、0AH
2. 输入单个字符(功能号01H)
AH=01H
INT 21H
;返回:AL=输入字符
3. 键盘输入字符串(功能号0AH)
AH=0AH
DS:DX=缓冲区地址
;缓冲区格式:第一个字节=最大字符数,第二个字节=实际字符数,后续=输入字符
4. 结束程序(功能号4CH)
AH=4CH
AL=返回码
INT 21H
5. 显示字符(功能号02H)
AH=02H
DL=字符
INT 21H