汇编语言 条件跳转指令
汇编语言中的条件执行是通过几个循环和分支指令来完成的。这些指令可以改变程序中的控制流。
在两种情况下观察到有条件执行:
编号 | 条件指令 |
---|---|
1 | 无条件跳转 这由 JMP 指令执行条件执行通常涉及将控制权转移到当前执行指令后面的指令的地址控制权的转移可以向前,以执行一组新的指令,也可以向后,以重新执行相同的步骤。 |
2 | 条件跳转 这由一组跳转指令 j<condition> 执行,具体取决于条件条件指令通过中断顺序流来传输控制,并通过更改 IP 中的偏移值来实现 |
让我们在讲解条件指令之前先介绍一下 CMP 指令。
CMP 指令
CMP 指令比较两个操作数。它通常用于条件执行。此指令基本上是从另一个操作数中减去一个,以比较操作数是否相等。它不会干扰目标或源操作数。它与条件跳转指令一起用于决策。
语法
CMP 比较两个数字数据字段。目标操作数可以在寄存器中,也可以在内存中。源操作数可以是常量数据、寄存器或内存。
实例
CMP DX,00 ; 将 DX 值与 0 进行比较
JE L7 ; 如果等于,则跳转到标签 L7
.
.
L7: ...
CMP 通常用于比较计数器值是否已达到需要运行循环的次数。
比如下面的典型条件:
INCEDX
CMPEDX, 10; 比较计数器是否达到 10
JLELP1 ; 如果它小于或等于 10,则跳转到 LP1
无条件跳转
如前所述,这是通过 JMP 指令执行的。条件执行通常涉及将控制权转移到不遵循当前执行指令的指令的地址。控制权的转移可以是前进的(执行新的指令集),也可以是后退的(重新执行相同的步骤)。
语法
JMP 指令提供了一个标签名称,控制流将立即转移到该标签名称。JMP 指令的语法是:
JMP label
实例
下面是一个 JMP 指令的实例:
MOV AX, 00 ; 将AX初始化为0
MOV BX, 00 ; 将BX初始化为0
MOV CX, 01 ; 初始化CX为1
L20:
ADD AX, 01 ; 增量AX
ADD BX, AX ; 将AX添加到BX
SHL CX, 1 ; 向左移动CX,这反过来使CX的值翻倍
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 |
JO | Jump If Overflow | OF |
JNO | 如果没有溢出则跳转 | OF |
JP/JPE | 跳校验或偶校验 | PF |
JNP/JPO | 跳转无奇偶校验或跳转奇偶校验 | PF |
JS | 跳跃符号(负值) | SF |
JNS | 跳转无符号(正值) | SF |
J <condition> 指令集的语法:
CMPAL, BL
JEEQUAL
CMPAL, BH
JEEQUAL
CMPAL, CL
JEEQUAL
NON_EQUAL: ...
EQUAL: ...
实例
以下程序显示 3 个变量中最大的一个。变量是两位数的变量。3 个变量 num1
,num2
和 num3
分别具有值 47、22 和 31:
section .text
global _start ;必须声明 gcc
_start: ;告诉链接器入口点
mov ecx, [num1]
cmp ecx, [num2]
jg check_third_num
mov ecx, [num2]
check_third_num:
cmp ecx, [num3]
jg _exit
mov ecx, [num3]
_exit:
mov [largest], ecx
mov ecx,msg
mov edx, len
mov ebx,1 ;文件描述 (stdout)
mov eax,4 ;系统调用号 (sys_write)
int 0x80 ;调用内核
mov ecx,largest
mov edx, 2
mov ebx,1 ;文件描述 (stdout)
mov eax,4 ;系统调用号 (sys_write)
int 0x80 ;调用内核
mov eax, 1
int 80h
section .data
msg db "The largest digit is: ", 0xA,0xD
len equ $- msg
num1 dd '47'
num2 dd '22'
num3 dd '31'
segment .bss
largest resb 2
结果如下:
The largest digit is:
47