汇编语言 条件跳转指令

汇编语言中的条件执行是通过几个循环和分支指令来完成的。这些指令可以改变程序中的控制流。

在两种情况下观察到有条件执行:

编号条件指令
1

无条件跳转

这由 JMP 指令执行条件执行通常涉及将控制权转移到当前执行指令后面的指令的地址控制权的转移可以向前,以执行一组新的指令,也可以向后,以重新执行相同的步骤。

2

条件跳转

这由一组跳转指令 j<condition> 执行,具体取决于条件条件指令通过中断顺序流来传输控制,并通过更改 IP 中的偏移值来实现

让我们在讲解条件指令之前先介绍一下 CMP 指令。


CMP 指令

CMP 指令比较两个操作数。它通常用于条件执行。此指令基本上是从另一个操作数中减去一个,以比较操作数是否相等。它不会干扰目标或源操作数。它与条件跳转指令一起用于决策。

语法

CMP 比较两个数字数据字段。目标操作数可以在寄存器中,也可以在内存中。源操作数可以是常量数据、寄存器或内存。

实例
  1. CMP DX,00 ; DX 值与 0 进行比较
  2. JE L7 ; 如果等于,则跳转到标签 L7
  3. .
  4. .
  5. L7: ...

CMP 通常用于比较计数器值是否已达到需要运行循环的次数。

比如下面的典型条件:

  1. INCEDX
  2. CMPEDX, 10; 比较计数器是否达到 10
  3. JLELP1 ; 如果它小于或等于 10,则跳转到 LP1

无条件跳转

如前所述,这是通过 JMP 指令执行的。条件执行通常涉及将控制权转移到不遵循当前执行指令的指令的地址。控制权的转移可以是前进的(执行新的指令集),也可以是后退的(重新执行相同的步骤)。

语法

JMP 指令提供了一个标签名称,控制流将立即转移到该标签名称。JMP 指令的语法是:

  1. JMP label
实例

下面是一个 JMP 指令的实例:

  1. MOV AX, 00 ; AX初始化为0
  2. MOV BX, 00 ; BX初始化为0
  3. MOV CX, 01 ; 初始化CX1
  4. L20:
  5. ADD AX, 01 ; 增量AX
  6. ADD BX, AX ; AX添加到BX
  7. SHL CX, 1 ; 向左移动CX,这反过来使CX的值翻倍
  8. JMP L20 ; 重复的语句

条件跳转

如果在条件跳转中满足某些指定条件,则控制流将转移到目标指令。根据条件和数据,有许多条件跳转指令。

以下是用于算术运算的有符号数据的条件跳转指令:

指令描述标志测试
JE/JZ跳转等于或跳转零ZF
JNE/JNZ跳转不等于或跳转不为零ZF
JG/JNLE跳转大于或跳转不小于/等于OF, SF, ZF
JGE/JNL跳转大于/等于或不小于跳转OF, SF
JL/JNGE跳转小于或不大于/等于OF, SF
JLE/JNG跳少/等于或跳不大于OF, SF, ZF

以下是对用于逻辑运算的无符号数据使用的条件跳转指令:

指令描述标志测试
JE/JZ跳转等于或跳转零ZF
JNE/JNZ跳转不等于或跳转不为零ZF
JA/JNBE跳转向上或不低于/等于CF, ZF
JAE/JNB高于/等于或不低于CF
JB/JNAE跳到以下或跳到不高于/等于CF
JBE/JNA跳到下面/等于或不跳到上方AF, CF

以下条件跳转指令有特殊用途,并检查标志的值:

指令描述标志测试
JXCZ如果 CX 为零则跳转none
JC如果携带则跳转CF
JNC如果不携带则跳转CF
JOJump If OverflowOF
JNO如果没有溢出则跳转OF
JP/JPE跳校验或偶校验PF
JNP/JPO跳转无奇偶校验或跳转奇偶校验PF
JS跳跃符号(负值)SF
JNS跳转无符号(正值)SF

J <condition> 指令集的语法:

  1. CMPAL, BL
  2. JEEQUAL
  3. CMPAL, BH
  4. JEEQUAL
  5. CMPAL, CL
  6. JEEQUAL
  7. NON_EQUAL: ...
  8. EQUAL: ...

实例

以下程序显示 3 个变量中最大的一个。变量是两位数的变量。3 个变量 num1num2num3 分别具有值 472231

  1. section .text
  2. global _start ;必须声明 gcc
  3. _start: ;告诉链接器入口点
  4. mov ecx, [num1]
  5. cmp ecx, [num2]
  6. jg check_third_num
  7. mov ecx, [num2]
  8. check_third_num:
  9. cmp ecx, [num3]
  10. jg _exit
  11. mov ecx, [num3]
  12. _exit:
  13. mov [largest], ecx
  14. mov ecx,msg
  15. mov edx, len
  16. mov ebx,1 ;文件描述 (stdout)
  17. mov eax,4 ;系统调用号 (sys_write)
  18. int 0x80 ;调用内核
  19. mov ecx,largest
  20. mov edx, 2
  21. mov ebx,1 ;文件描述 (stdout)
  22. mov eax,4 ;系统调用号 (sys_write)
  23. int 0x80 ;调用内核
  24. mov eax, 1
  25. int 80h
  26. section .data
  27. msg db "The largest digit is: ", 0xA,0xD
  28. len equ $- msg
  29. num1 dd '47'
  30. num2 dd '22'
  31. num3 dd '31'
  32. segment .bss
  33. largest resb 2

结果如下:

  1. The largest digit is:
  2. 47