# 附录三:汇编指令集 ## 一、数据传送指令 ### 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 ```