知识回顾

一、什么是分支跳转?

分支跳转是根据条件改变程序执行流程的机制,是建立 if、else、while、for 等高级结构的基础。


二、跳转指令分类

1. 无条件跳转

jmp label; 直接跳转到标签处
jmp reg; 跳转到寄存器指定的地址
jmp mem; 跳转到内存地址

2. 条件跳转

基于标志位的状态决定是否跳转。


三、条件跳转指令详解(重点)

1. 无符号比较跳转(用于地址、索引、数组长度等)

指令含义条件(标志位)
jajump if aboveCF=0 且 ZF=0(大于)
jaejump if above or equalCF=0(大于或等于)
jbjump if belowCF=1(小于)
jbejump if below or equalCF=1 或 ZF=1(小于或等于)
je / jzjump if equal / zeroZF=1
jne / jnzjump if not equal / not zeroZF=0

2. 有符号比较跳转(用于负数、温度、坐标等)

指令含义条件(标志位)
jgjump if greaterZF=0 且 SF=OF(大于)
jgejump if greater or equalSF=OF(大于或等于)
jljump if lessSF≠OF(小于)
jlejump if less or equalZF=1 或 SF≠OF(小于或等于)

四、分支结构搭建方式

1. 单分支(if)

cmp eax, ebx jle skip ; 执行 if 语句块 skip:

2. 双分支(if-else)

cmp eax, ebx jle else_part ; if 语句块 jmp end_if else_part: ; else 语句块 end_if:

3. 多分支(if-else if-else)

cmp eax, 1 je case1 cmp eax, 2 je case2 cmp eax, 3 je case3 jmp default_case


五、循环结构中的跳转

1. while 循环

while_start: cmp eax, 10 jge while_end ; 循环体 inc eax jmp while_start while_end:

2. for 循环(计数器控制)

asm复制

mov ecx, 0 for_start: cmp ecx, 10 jge for_end ; 循环体 inc ecx jmp for_start for_end:


六、标志位与跳转关系(底层机制)

标志位含义影响跳转
ZF零标志jejnejzjnz
CF进位标志jajbjaejbe
SF符号标志jljgjlejge
OF溢出标志jljgjlejge

✅ 总结:条件跳转指令本质上是对标志位的判断,而这些标志位由 cmp、sub、add、test 等指令设置。

示例

调试

dArray定义后,$指向数组结束后的下一个字节地址

**($-dArray)/4**数组元素个数计算,(40字节) ÷ 4 = 10个元素

并预留出了一个位置方便后续插入。

先初始话要插入的元素和比较索引

进入循环比较过程

每次循环进行比较,CF=1,则说明小于不发生ja无符号大于跳转,向下执行,索引+1,jb无符号小于跳转开始下一次循环。

第6次循环时,CF值变为1,索引值为5(插入位置),进行ja跳转

将EDI索引赋值从最后开始移动。

进入循环比较

比较当前移动位置与插入位置,如果SF≠OF(小于)完成JI有符号跳转,否则向下继续运行,去除当前元素,向下移动一个位置。EDI-1,继续回到循环。

第6次循环时,EDI<ESIjl有符号小于跳转,当移动位置到达插入位置之前时停止并完成跳转。

将要插入新元素放入索引为5的数组中

最终得到的插入新数组符合预期

特殊情况分析

1. 插入最小值的情况

如果要插入的值小于所有现有元素(如插入25):

  • 第一次比较:50 vs 25 → 50>25 → 立即跳转到c20
  • ESI=0,表示插入到数组开头
  • 所有元素向后移动一位

2. 插入最大值的情况

如果要插入的值大于所有现有元素(如插入3000):

  • 所有比较都不满足ja条件
  • ESI增加到10(等于ITEMS)
  • 元素不需要移动,直接插入到末尾

3. 插入重复值的情况

如果要插入的值等于某个现有元素:

  • 由于使用ja(大于跳转),等于时不跳转
  • 会插入到相等元素的前面位置