news 2026/6/12 19:42:54

一篇速成 汇编程序语言设计之 8086 汇编核心指令

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
一篇速成 汇编程序语言设计之 8086 汇编核心指令

作者:逆境不可逃

技术永无止境

希望我的内容可以帮助到你!!!!


大家吼 ! 我是 逆境不可逃 今天给大家带来文章

《 一篇速通 汇编程序语言设计之 8086 汇编核心指令 》

近期文章 欢迎阅读

【学Git看这篇文章就够了】Git 终极避坑指南 + 全命令速查表-CSDN博客

【学Git看这篇文章就够了】远程仓库 AND 企业协作进阶-CSDN博客

【学Git看这篇文章就够了】基础入门之本地单机 Git-CSDN博客

好,废话不多说,进入正题

一开始接触汇编,看到满屏的英文缩写指令都会觉得头大

其实这些指令就像 CPU 能听懂的「基础动词」

掌握了它们,你就能给 CPU 发号施令

让它完成数据搬运、数值计算、批量处理等各种操作

今天我们把最常用的四大类指令 ——数据传送算术运算逻辑操作串处理

用通俗的比喻和直白的用法讲清楚,零基础也能快速理解

一、数据传送指令:CPU 的「搬运小分队」

数据传送是汇编里最常用的操作,就像现实里的搬家、储物、互换位置。它的核心是把数据在寄存器、内存、外设之间挪来挪去,绝大多数情况下不会改变数据本身,只改变数据的存放位置。

1. 通用数据传送指令:最基础的搬运操作

这是日常开发中使用频率最高的一组,包含 4 条指令:MOV、PUSH、POP、XCHG

  • MOV(Move):数据复制传送相当于电脑里的「复制粘贴」 把源位置的数据复制一份放到目标位置,源位置的数据保持不变 ,格式:MOV 目标操作数, 源操作数,示例:MOV AX, BX—— 把 BX 寄存器里的数值,复制一份放到 AX 寄存器中, 注意:不能直接把一段内存数据传到另一段内存,也不能直接修改段寄存器,需要通过通用寄存器中转。

  • PUSH / POP:栈操作指令你可以把栈理解成一个「后进先出」的箱子:PUSH 是往箱子最上面放东西(压栈),POP 是从箱子最上面拿东西(弹栈)。

    • PUSH AX:把 AX 的值放到栈顶,栈指针自动上移
    • POP AX:把栈顶的值取出放到 AX,栈指针自动下移 常用于保存临时数据、调用子程序时保存现场。
  • XCHG(Exchange):数据交换相当于「互换位置」,不用中间变量,直接交换两个位置的数据。 示例:XCHG AX, BX—— 执行完成后,AX 里是原来 BX 的值,BX 里是原来 AX 的值。

2. 累加器专用传送指令:和外设打交道

这组指令专门通过累加器(AX/AL)和外部设备端口(比如键盘、串口)交互,包含IN、OUT、XLAT

  • IN:从端口读取数据从指定的外设端口读取数据,存到 AL(8 位)或 AX(16 位)中。 示例:IN AL, 20H—— 从 20 号端口读取一个字节,放到 AL 寄存器。

  • OUT:向端口写入数据把 AL 或 AX 里的数据,写入到指定的外设端口。 示例:OUT 20H, AL—— 把 AL 里的字节数据,写入 20 号端口。

  • XLAT(Translate):查表转换俗称「换码指令」,用来快速查表取值。比如你提前在内存里存了一张 ASCII 码对照表,用 XLAT 就能根据索引快速取出对应的值,结果自动存入 AL。 用法:先把表的首地址存入 BX,索引值存入 AL,执行 XLAT 即可得到表中对应位置的数值。

3. 地址传送指令:拿地址,不拿数据

这组指令传送的不是数据本身,而是数据在内存中的地址,包含LEA、LDS、LES

  • LEA(Load Effective Address):取有效地址把内存操作数的偏移地址,送到指定的通用寄存器。注意它取的是「地址坐标」,不是地址里存储的数值。 示例:LEA AX, [BX+SI]—— 把 BX+SI 计算出的偏移地址放到 AX,而不是把这个地址里的数据放到 AX。 通俗理解:MOV 是拿盒子里的东西,LEA 是拿盒子的位置坐标。

  • LDS / LES:加载远地址一次性加载「段地址 + 偏移地址」:LDS 会把段地址存入 DS 数据段寄存器,LES 会把段地址存入 ES 附加段寄存器,偏移地址统一存入指定的通用寄存器。 示例:LDS SI, [1000H]—— 把内存 1000H 处的偏移地址给 SI,后续的段地址给 DS。

4. 标志寄存器传送指令:操作状态标志

标志寄存器保存着 CPU 运算的各种状态(比如是否进位、结果是否为 0),这组指令专门用来读写标志寄存器,包含LAHF、SAHF、PUSHF、POPF

  • LAHF:把标志寄存器的低 8 位(SF、ZF、AF、PF、CF 等状态标志),复制到 AH 寄存器。
  • SAHF:和 LAHF 相反,把 AH 里的值写回标志寄存器的低 8 位,用来修改标志位。
  • PUSHF / POPF:对整个 16 位标志寄存器做栈操作。PUSHF 把标志寄存器整体压栈保存,POPF 把栈顶数据弹出恢复标志位,常用于子程序中保存和恢复运算状态。

5. 类型转换指令:自动扩展数据长度

做乘除法运算时,经常需要把短数据扩展成长数据,这两条指令会自动按照符号位扩展,保证数值大小不变,包含CBW、CWD

  • CBW(Convert Byte to Word):字节转字把 AL 里的 8 位有符号数,扩展成 16 位有符号数,结果存在 AX 中。扩展规则:AL 最高位是 0 则 AH 全填 0,最高位是 1 则 AH 全填 1。

  • CWD(Convert Word to Double word):字转双字把 AX 里的 16 位有符号数,扩展成 32 位有符号数,高 16 位存在 DX,低 16 位存在 AX,同样按符号位自动扩展。

二、算术指令:CPU 的「自带计算器」

算术指令就是负责加减乘除运算,和我们日常使用的计算器逻辑基本一致,运算的同时会同步修改标志寄存器的状态位。

1. 加法指令

包含ADD、ADC、INC三条

  • ADD:普通加法两个数相加,结果存回目标操作数。 格式:ADD 目标, 源示例:ADD AX, BX—— 等价于 AX = AX + BX

  • ADC(Add with Carry):带进位加法相加时会额外加上进位标志 CF 的值,专门用来计算超过 16 位的大数。比如计算 32 位加法,先算低 16 位,再用 ADC 算高 16 位,把低 16 位的进位包含进去。

  • INC(Increment):自增 1给目标操作数加 1,等价于目标 = 目标 + 1,常用在循环中给计数器累加。 示例:INC CX—— CX 的数值加 1

2. 减法指令

包含SUB、SBB、DEC、NEG、CMP五条

  • SUB:普通减法目标操作数减去源操作数,结果存回目标。 示例:SUB AX, BX—— 等价于 AX = AX - BX

  • SBB(Subtract with Borrow):带借位减法相减时会额外减去借位标志 CF 的值,和 ADC 对应,用于实现大数减法。

  • DEC(Decrement):自减 1给目标操作数减 1,等价于目标 = 目标 - 1,循环中非常常用。

  • NEG(Negate):取负指令对操作数求补码,也就是正数变负数、负数变正数,等价于操作数 = 0 - 操作数

  • CMP(Compare):比较指令用目标操作数减去源操作数,但不保存运算结果,只修改标志位。它是分支判断的核心:执行完 CMP 后,我们就能通过标志位判断两个数是否相等、谁大谁小。 比如执行CMP AX, BX后,如果 ZF 标志为 1,说明 AX 和 BX 数值相等。

3. 乘法指令

包含MUL、IMUL,分别对应无符号数和有符号数乘法

  • MUL(Multiply):无符号乘法

    • 8 位乘法:一个乘数默认在 AL,另一个是指定的 8 位操作数,结果存在 AX(AH 存高 8 位,AL 存低 8 位)
    • 16 位乘法:一个乘数默认在 AX,另一个是指定的 16 位操作数,结果存在 DX:AX(DX 存高 16 位,AX 存低 16 位)
  • IMUL(Integer Multiply):有符号乘法用法和 MUL 完全一致,专门用于有符号数乘法,保证符号位计算正确。

4. 除法指令

包含DIV、IDIV,同样区分无符号和有符号

  • DIV(Divide):无符号除法

    • 8 位除法:被除数默认在 AX(16 位),除以指定的 8 位操作数;商存在 AL,余数存在 AH
    • 16 位除法:被除数默认在 DX:AX(32 位),除以指定的 16 位操作数;商存在 AX,余数存在 DX
  • IDIV(Integer Divide):有符号除法用法和 DIV 一致,专门处理有符号数除法,余数的符号和被除数保持一致。

5. 十进制调整指令

计算机内部用二进制运算,但很多场景需要用十进制(BCD 码)计算,这组指令的作用就是把二进制运算结果,修正为正确的十进制格式。

  • 压缩 BCD 调整:DAA(加法调整)、DAS(减法调整)压缩 BCD 指一个字节存两位十进制数,运算后用这两条指令修正结果。
  • 非压缩 BCD 调整:AAA(加法调整)、AAS(减法调整)、AAM(乘法调整)、AAD(除法调整)非压缩 BCD 指一个字节只存一位十进制数,对应四种运算的结果修正。

三、逻辑指令:CPU 的「位操作工具箱」

逻辑指令以二进制的「位」为单位进行操作,是汇编里非常灵活的一类指令,常用于控制某一位的开关、实现快速乘除。

1. 逻辑运算指令

包含AND、OR、NOT、XOR、TEST

  • AND:按位与两个二进制位都为 1,结果才是 1,否则为 0。 典型用法:把某几位清零(屏蔽位)。比如AND AL, 0FH—— 把 AL 的高 4 位清零,低 4 位保持不变。

  • OR:按位或两个二进制位只要有一个是 1,结果就是 1。 典型用法:把某几位置 1。比如OR AL, 80H—— 把 AL 的最高位设为 1,其余位不变。

  • NOT:按位取反把每一位的 0 变 1、1 变 0,是单操作数指令。注意它不会影响标志位。

  • XOR:按位异或两个位相同结果为 0,不同结果为 1。 典型用法:① 给寄存器快速清 0,比如XOR AX, AX,执行后 AX 一定为 0,比 MOV 指令更高效;② 翻转某几位的数值。

  • TEST:位测试指令和 AND 一样执行按位与运算,但不保存结果,只修改标志位。 用来检测某一位是否为 0。比如TEST AL, 01H,如果执行后 ZF=1,说明 AL 的最低位是 0。

2. 移位指令

把二进制数整体向左或向右移动,分为普通移位、算术移位、循环移位三类,共 8 条:SHL、SHR、SAL、SAR、ROL、ROR、RCL、RCR

逻辑移位
  • SHL(Shift Left):逻辑左移所有位整体左移,最低位补 0,最高位移入进位标志 CF。左移一位等价于无符号数乘以 2。
  • SHR(Shift Right):逻辑右移所有位整体右移,最高位补 0,最低位移入 CF。右移一位等价于无符号数除以 2。
算术移位
  • SAL(Shift Arithmetic Left):算术左移效果和 SHL 完全一致,左移低位补 0,不影响符号位。
  • SAR(Shift Arithmetic Right):算术右移右移时最高位(符号位)保持不变,保证有符号数的正负属性不变,适合有符号数除以 2。
循环移位
  • ROL / ROR:不带进位循环移位ROL 循环左移:最高位移到最低位,同时送入 CF; ROR 循环右移:最低位移到最高位,同时送入 CF。 所有数据位在内部循环,不会丢失数据。

  • RCL / RCR:带进位循环移位把进位标志 CF 也加入循环圈,相当于多了一位参与循环。RCL 是带进位左移,RCR 是带进位右移。

四、串处理指令:CPU 的「批量处理流水线」

这里的「串」指内存中连续的一段数据(比如字符串、数组),串处理指令可以批量操作一整段数据,不用手动写循环逐个处理,执行效率非常高。

1. 方向标志指令:控制处理方向

串处理是按地址逐个推进的,方向标志决定了地址是递增还是递减:

  • CLD:清除方向标志,地址从低到高推进(从串头到串尾)
  • STD:设置方向标志,地址从高到低推进(从串尾到串头)

2. 核心串处理指令

所有串指令都有字节(后缀 B)和字(后缀 W)两个版本,默认规则:源串位于 DS:SI,目标串位于 ES:DI,每执行一次,SI/DI 会自动增减 1(字节)或 2(字)。

  • MOVSB / MOVSW:串传送把源串的一个字节 / 字,复制到目标串位置,然后自动修改 SI 和 DI。 配合重复前缀可以实现「批量复制内存块」,是最常用的串指令。

  • STOSB / STOSW:串存储把 AL(字节)或 AX(字)里的值,写入目标串的位置,然后自动修改 DI。 常用于给一段内存批量填充同一个值(比如批量清 0、填充空格)。

  • LODSB / LODSW:串读取把源串的一个字节 / 字,读取到 AL 或 AX 中,然后自动修改 SI。 通常配合循环使用,逐个读取串内数据进行处理。

  • CMPSB / CMPSW:串比较将源串和目标串的对应位置数据相减,不保存结果,只修改标志位,然后自动修改 SI 和 DI。 用来比较两个字符串 / 数组是否完全相同。

  • SCASB / SCASW:串扫描用 AL/AX 里的值,和目标串的对应位置数据做比较,只修改标志位,然后自动修改 DI。 用来在字符串中查找某个特定字符。

3. 重复前缀:让指令自动循环

串指令本身只执行一次,加上重复前缀后,就会自动重复执行;重复次数存放在 CX 寄存器中,每执行一次 CX 减 1,直到 CX 为 0 时停止。

  • REP:无条件重复只要 CX 不为 0 就持续重复,常和 MOVS、STOS 搭配,实现批量复制、批量填充。 示例:REP MOVSB—— 连续复制 CX 个字节,从源串复制到目标串。

  • REPE / REPZ:相等时重复除了 CX 不为 0,还要求比较结果相等(ZF=1)才继续重复。常和 CMPS、SCAS 搭配,用来查找第一个不相等的位置。

  • REPNE / REPNZ:不相等时重复CX 不为 0,且比较结果不相等(ZF=0)时才继续重复。常和 SCAS 搭配,用来在串中查找第一个匹配的字符。

写在最后

以上就是 8086 汇编最核心的四大类指令,它们是编写汇编程序的「基础词汇」:

  • 搬运数据用数据传送指令
  • 数值计算用算术指令
  • 按位操作用逻辑指令
  • 批量处理内存用串指令

刚开始不用死记硬背,写代码的时候多查多用,慢慢就能熟练掌握。等把这些指令吃透,你就能看懂绝大多数基础汇编代码,也能独立写出简单的汇编程序了。

附参考程序

; ========== 数据段:定义程序用到的变量和数据 ========== DATA SEGMENT ; 1. 算术运算测试用变量 num_byte DB 12H ; 8位字节变量 num_word DW 1234H ; 16位字变量 result DW ? ; 预留结果存储位置 ; 2. 串操作测试用数据 src_str DB 'Hello, Assembly!', 0 ; 源字符串,共16字节 dest_str DB 20 DUP(0) ; 目标缓冲区,20字节初始化为0 fill_buf DB 10 DUP(?) ; 批量填充测试缓冲区 search_ch DB 's' ; 待查找的字符 DATA ENDS ; ========== 代码段:编写指令逻辑 ========== CODE SEGMENT ASSUME CS:CODE, DS:DATA, ES:DATA ; 声明各段对应的段寄存器 START: ; 初始化数据段和附加段(串操作需要ES寄存器,这里和DS共用同一段) MOV AX, DATA MOV DS, AX MOV ES, AX ; ---------------------------------------------------------------------- ; 第一部分:数据传送指令演示 ; ---------------------------------------------------------------------- ; 1. MOV 基本数据传送:内存 → 寄存器 MOV AL, num_byte ; 把num_byte的值(12H)复制到AL寄存器 MOV BX, num_word ; 把num_word的值(1234H)复制到BX寄存器 ; 2. XCHG 数据交换:交换AX和BX的内容 XCHG AX, BX ; 执行后 AX=1234H,BX=0012H ; 3. PUSH / POP 栈操作:保存和恢复寄存器 PUSH AX ; 将AX压入栈顶保存 PUSH BX ; 将BX压入栈顶保存 POP AX ; 弹出栈顶数据到AX(得到原BX的值0012H) POP BX ; 弹出栈顶数据到BX(得到原AX的值1234H) ; 4. LEA 取有效地址:获取变量的内存偏移地址 LEA SI, src_str ; SI = src_str在数据段中的偏移地址 LEA DI, dest_str ; DI = dest_str在数据段中的偏移地址 ; 5. CBW 字节转字:有符号数符号扩展 MOV AL, 80H ; AL = 80H(有符号数 -128) CBW ; 扩展为16位,AX = FF80H,数值保持不变 ; 6. CWD 字转双字:16位扩展为32位 MOV AX, 8000H ; AX = 8000H(有符号数 -32768) CWD ; 扩展为32位,高16位DX=FFFFH,低16位AX=8000H ; ---------------------------------------------------------------------- ; 第二部分:算术指令演示 ; ---------------------------------------------------------------------- ; 1. ADD 普通加法 MOV AX, 1000H ADD AX, 2000H ; AX = AX + 2000H = 3000H ; 2. ADC 带进位加法:实现32位加法 ; 计算 0001FFFFH + 00020001H = 00040000H MOV AX, 0FFFFH ; 被加数低16位 MOV DX, 0001H ; 被加数高16位 ADD AX, 0001H ; 低16位相加,产生进位 CF=1 ADC DX, 0002H ; 高16位相加 + 进位,DX = 0001+0002+1 = 0004H ; 3. INC 自增1 MOV CX, 0 INC CX ; CX = CX + 1 = 1 ; 4. SUB 普通减法 SUB AX, 1000H ; AX = AX - 1000H ; 5. DEC 自减1 DEC CX ; CX = CX - 1 = 0 ; 6. NEG 取负(求补码) MOV AX, 5 NEG AX ; AX = -5(补码表示为 FFFBH) ; 7. CMP 比较指令:只修改标志位,不改变操作数 MOV AX, 10 CMP AX, 10 ; 两数相等,ZF标志位置1 CMP AX, 20 ; AX < 20,SF标志位置1 ; 8. MUL 无符号8位乘法:AL × 操作数 → AX MOV AL, 10H MOV BL, 20H MUL BL ; AX = 10H × 20H = 0200H ; 9. DIV 无符号8位除法:AX ÷ 操作数 → 商在AL,余数在AH MOV AX, 0200H MOV BL, 10H DIV BL ; AL = 20H(商),AH = 00H(余数) ; ---------------------------------------------------------------------- ; 第三部分:逻辑指令演示 ; ---------------------------------------------------------------------- ; 1. AND 按位与:清零高4位,保留低4位 MOV AL, 0ABH AND AL, 0FH ; AL = 0BH,高4位被强制清零 ; 2. OR 按位或:最高位置1 OR AL, 80H ; AL = 8BH,最高位变为1 ; 3. XOR 按位异或:快速清零寄存器(比MOV更高效) XOR AX, AX ; AX = 0000H ; 4. TEST 位测试:检测最低位是否为1 MOV AL, 03H TEST AL, 01H ; 结果非零,ZF=0,说明最低位是1 ; 5. SHL 逻辑左移:无符号数 ×2 MOV AX, 3 SHL AX, 1 ; AX = 6,左移1位等价于乘以2 ; 6. SAR 算术右移:有符号数 ÷2,符号位保持不变 MOV AX, 0FFFCH ; -4 的补码 SAR AX, 1 ; AX = 0FFFEH(-2),最高位保持1 ; 7. ROL 循环左移:最高位移到最低位 MOV AL, 11000000B ROL AL, 1 ; AL = 10000001B ; ---------------------------------------------------------------------- ; 第四部分:串处理指令演示 ; ---------------------------------------------------------------------- ; 1. 串传送:批量复制字符串(src_str → dest_str) CLD ; 清除方向标志,地址从低到高递增 LEA SI, src_str ; 源串地址 → SI LEA DI, dest_str ; 目标串地址 → DI MOV CX, 16 ; 复制长度:16个字节 REP MOVSB ; 重复执行MOVSB,直到CX=0,完成批量复制 ; 2. 串存储:批量填充内存(把fill_buf全部填0) LEA DI, fill_buf MOV CX, 10 ; 填充10个字节 MOV AL, 0 ; 填充的数值 REP STOSB ; 重复执行STOSB,10个字节全部变为0 ; 3. 串扫描:在dest_str中查找字符's' LEA DI, dest_str MOV AL, search_ch ; 待查找的字符 → AL MOV CX, 20 ; 最大扫描长度 CLD REPNE SCASB ; 不相等就继续找,找到匹配字符后停止 ; 找到后:DI指向匹配字符的下一位,CX为剩余未扫描长度 ; ---------------------------------------------------------------------- ; 程序结束:正常返回DOS系统 ; ---------------------------------------------------------------------- MOV AH, 4CH ; DOS功能号:程序退出 INT 21H ; 调用DOS中断 CODE ENDS END START

后续补充

一、无条件转移指令

JMP(Jump)
  • 含义:无条件跳转到指定地址执行。
  • 特点:不管任何标志位,直接修改IP(指令指针寄存器)的值。
  • 分类
    • 段内转移:只修改IP,不改变CS(代码段寄存器)。
    • 段间转移:同时修改CSIP,可以跳转到不同代码段。
  • 示例
    JMP label ; 跳转到label标签处执行

二、条件转移指令

这类指令会根据标志位(ZF、SF、OF、PF、CF 等)的状态,决定是否跳转。 注意:x86 实模式下,条件转移指令大多是短转移(范围 - 128~+127 字节)。

1. 零标志(ZF)相关
指令全称跳转条件等价关系
JZJump if ZeroZF = 1(结果为 0 / 相等)JE完全等价
JNZJump if Not ZeroZF = 0(结果非 0 / 不相等)JNE完全等价
JEJump if EqualZF = 1(两数相等)JZ完全等价
JNEJump if Not EqualZF = 0(两数不等)JNZ完全等价
  • 典型场景:比较指令CMP、减法 / 加法指令后,判断结果是否为 0 或两数是否相等。
    CMP AX, BX JE equal_label ; AX == BX 时跳转 JNE not_equal_label ; AX != BX 时跳转

2. 符号标志(SF)相关
指令全称跳转条件
JSJump if SignSF = 1(结果为负)
JNSJump if Not SignSF = 0(结果为非负)
  • 典型场景:判断带符号数运算结果的正负。
    ADD AX, BX JS negative_label ; 结果为负时跳转

3. 溢出标志(OF)相关
指令全称跳转条件
JOJump if OverflowOF = 1(运算溢出)
JNOJump if Not OverflowOF = 0(运算未溢出)
  • 典型场景:带符号数加减运算后,判断是否溢出。
    ADD AX, BX JO overflow_label ; 结果溢出时跳转

4. 奇偶标志(PF)相关
指令全称跳转条件
JP/JPEJump if Parity / Even ParityPF = 1(低 8 位中 1 的个数为偶数)
JNP/JPOJump if Not Parity / Odd ParityPF = 0(低 8 位中 1 的个数为奇数)
  • 典型场景:数据校验、串口通信中的奇偶校验。

5. 无符号数比较(CF/ZF)相关
指令全称跳转条件含义(无符号数 A、B)
JB/JNAEJump if Below / Not Above or EqualCF = 1A < B(小于)
JNB/JAEJump if Not Below / Above or EqualCF = 0A ≥ B(大于等于)
JBE/JNAJump if Below or Equal / Not AboveCF=1 或 ZF=1A ≤ B(小于等于)
JNBE/JAJump if Not Below or Equal / AboveCF=0 且 ZF=0A > B(大于)
  • 典型场景:无符号数大小比较,如地址边界检查、循环计数。
    CMP AX, 100 JB less_than_100 ; AX < 100 时跳转

6. 带符号数比较(SF/OF/ZF)相关
指令全称跳转条件含义(带符号数 A、B)
JL/JNGEJump if Less / Not Greater or EqualSF != OFA < B(小于)
JNL/JGEJump if Not Less / Greater or EqualSF == OFA ≥ B(大于等于)
JLE/JNGJump if Less or Equal / Not GreaterSF != OF 或 ZF=1A ≤ B(小于等于)
JNLE/JGJump if Not Less or Equal / GreaterSF == OF 且 ZF=0A > B(大于)
  • 注意:带符号数比较不能直接用 CF,必须结合SFOF判断。
  • 典型场景:带符号数排序、大小比较。

7.JCXZ(Jump if CX is Zero)
  • 含义:如果CX寄存器的值为 0,则跳转。
  • 跳转条件CX = 0(不影响任何标志位)。
  • 典型场景:循环前判断计数器是否为 0,避免循环执行 0 次。

    asm

    MOV CX, 0 JCXZ skip_loop ; CX为0,直接跳过循环 loop_body: ; ... LOOP loop_body skip_loop:

三、循环指令

这类指令默认以CX为计数器,每次执行会自动CX = CX - 1,并根据条件决定是否跳转。

1.LOOP(Loop)
  • 跳转条件CX ≠ 0时跳转。
  • 执行流程CX--,若CX≠0则跳转到目标地址。
  • 典型场景:基础循环结构。
    MOV CX, 5 loop_start: ; 循环体,执行5次 LOOP loop_start

2.LOOPZ/LOOPE(Loop while Zero / Equal)
  • 跳转条件CX ≠ 0 且 ZF = 1时跳转。
  • 执行流程CX--,若CX≠0且结果为 0 / 相等,则跳转。
  • 典型场景:循环查找相等的值,遇到不等则停止。

3.LOOPNZ/LOOPNE(Loop while Not Zero / Not Equal)
  • 跳转条件CX ≠ 0 且 ZF = 0时跳转。
  • 执行流程CX--,若CX≠0且结果非 0 / 不等,则跳转。
  • 典型场景:循环查找不等的值,遇到相等则停止。

四、子程序调用和返回指令

CALL(Call Procedure)
  • 含义:调用子程序(函数)。
  • 执行流程
    1. 将下一条指令的地址(返回地址)压入栈中。
    2. 跳转到子程序的入口地址执行。
  • 分类:段内调用、段间调用(段间调用会同时压入CSIP)。
RET(Return from Procedure)
  • 含义:从子程序返回,回到调用处继续执行。
  • 执行流程:从栈中弹出返回地址,恢复IP(段内返回)或CS:IP(段间返回)。
  • 变体RET n表示返回时额外从栈中弹出n个字节,用于平衡调用参数。

五、中断与中断返回指令

INT(Interrupt)
  • 含义:触发软中断,跳转到对应的中断服务程序。
  • 格式INT nn为中断号(0~255)。
  • 执行流程
    1. FLAGSCSIP依次压入栈。
    2. 清除IF(中断允许标志)和TF(陷阱标志)。
    3. 根据中断号n,从中断向量表中取出中断服务程序的入口地址,跳转到该地址执行。
INTO(Interrupt on Overflow)
  • 含义:溢出中断。
  • 执行流程:如果OF = 1,则触发INT 4号中断;否则不执行任何操作。
  • 典型场景:带符号数运算后,自动检测溢出并触发中断。
IRET(Interrupt Return)
  • 含义:从中断服务程序返回。
  • 执行流程:从栈中依次弹出IPCSFLAGS,恢复中断前的执行状态。

关键区分点

  1. 条件转移 vs 循环指令
    • 条件转移指令只判断标志位,不修改CX
    • 循环指令会自动CX--,并结合标志位判断。
  2. 无符号 vs 带符号比较指令
    • 无符号:用JB/JA/JBE/JAE,判断CF/ZF
    • 带符号:用JL/JG/JLE/JGE,判断SF/OF/ZF
  3. JZ/JEJNZ/JNE完全等价,只是为了可读性设计了两套助记符。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/12 19:42:54

GPS-SDR-SIM终极指南:5步打造专业级GPS信号仿真环境

GPS-SDR-SIM终极指南&#xff1a;5步打造专业级GPS信号仿真环境 【免费下载链接】gps-sdr-sim Software-Defined GPS Signal Simulator 项目地址: https://gitcode.com/gh_mirrors/gp/gps-sdr-sim GPS-SDR-SIM是一款开源的软件定义无线电GPS信号仿真器&#xff0c;它通过…

作者头像 李华
网站建设 2026/6/12 19:42:52

如何快速使用waifu2x-caffe:专业AI图像放大降噪完整指南

如何快速使用waifu2x-caffe&#xff1a;专业AI图像放大降噪完整指南 【免费下载链接】waifu2x-caffe waifu2xのCaffe版 项目地址: https://gitcode.com/gh_mirrors/wa/waifu2x-caffe waifu2x-caffe是一款基于Caffe深度学习框架的AI图像放大与降噪工具&#xff0c;专为Wi…

作者头像 李华
网站建设 2026/6/12 19:42:17

GEO 优化系统源码开发 搭建全流程技术分享

一、项目整体概述 1. 什么是 GEO 优化系统 GEO&#xff08;地理定位 / 地域定向&#xff09;优化系统&#xff0c;核心是基于 IP、经纬度、区域编码实现地域流量分发、IP 池管理、定位伪装、区域风控、地域访问策略配置的一体化平台。常见应用场景&#xff1a;跨境业务、多区…

作者头像 李华
网站建设 2026/6/12 19:39:57

MCF5223x微控制器:集成以太网与加密的嵌入式系统设计实战

1. 项目概述&#xff1a;为什么选择MCF5223x&#xff1f;在工业自动化、智能楼宇或者远程数据采集这类项目中摸爬滚打过的工程师&#xff0c;大概都经历过类似的纠结&#xff1a;需要一个性能足够、接口丰富、最好自带网络功能的控制器&#xff0c;但一看那些高端的应用处理器&…

作者头像 李华
网站建设 2026/6/12 19:39:54

Codex 智能编程助手落地应用指南

接手一个缺乏文档、逻辑错综复杂的遗留项目&#xff0c;大概是每位开发者职业生涯中都会遇到的“至暗时刻”。面对成千上万行没有注释的代码&#xff0c;新人往往需要数周甚至数月才能理清脉络&#xff0c;而老员工在维护时也常常如履薄冰&#xff0c;生怕改动一行引发连锁反应…

作者头像 李华