汇编 - 条件执行
汇编语言中的条件执行是通过多个循环和分支指令完成的。 这些指令可以改变程序中的控制流程。 在两种情况下观察到条件执行 −
| 序号 | 条件说明 |
|---|---|
| 1 | 无条件跳转 这是由 JMP 指令执行的。 条件执行通常涉及将控制转移到不跟随当前正在执行的指令的指令的地址。 控制权的转移可以是向前的,以执行一组新的指令,也可以是向后的,以重新执行相同的步骤。 |
| 2 | 条件跳转 这是根据条件由一组跳转指令 j<condition> 执行的。 条件指令通过中断顺序流来转移控制,并通过更改 IP 中的偏移值来实现。 |
在讨论条件指令之前,让我们先讨论 CMP 指令。
CMP指令
CMP 指令比较两个操作数。 一般用在条件执行中。 该指令基本上将一个操作数与另一个操作数相减,以比较操作数是否相等。 它不会干扰目标或源操作数。 它与条件跳转指令一起用于决策。
语法
CMP destination, source
CMP 比较两个数值数据字段。 目标操作数可以位于寄存器或内存中。 源操作数可以是常量(立即数)数据、寄存器或内存。
示例
CMP DX, 00 ; Compare the DX value with zero JE L7 ; If yes, then jump to label L7 . . L7: ...
CMP通常用于比较计数器值是否达到需要运行循环的次数。 考虑以下典型情况−
INC EDX CMP EDX, 10 ; Compares whether the counter has reached 10 JLE LP1 ; If it is less than or equal to 10, then jump to LP1
无条件跳转
如前所述,这是由 JMP 指令执行的。 条件执行通常涉及将控制转移到不跟随当前正在执行的指令的指令的地址。 控制权的转移可以是向前的,以执行一组新的指令,也可以是向后的,以重新执行相同的步骤。
语法
JMP 指令提供了一个标签名称,其中控制流立即转移。 JMP指令的语法为 −
JMP label
示例
以下代码片段说明了 JMP 指令 −
MOV AX, 00 ; Initializing AX to 0 MOV BX, 00 ; Initializing BX to 0 MOV CX, 01 ; Initializing CX to 1 L20: ADD AX, 01 ; Increment AX ADD BX, AX ; Add AX to BX SHL CX, 1 ; shift left CX, this in turn doubles the CX value JMP L20 ; repeats the statements
条件跳转
如果条件跳转中满足某个指定条件,则控制流转移到目标指令。 根据条件和数据,有许多条件跳转指令。
以下是用于算术运算的有符号数据上使用的条件跳转指令 −
| 说明 | 描述 | 已测试标志 |
|---|---|---|
| JE/JZ | Jump Equal or Jump Zero | ZF |
| JNE/JNZ | Jump not Equal or Jump Not Zero | ZF |
| JG/JNLE | Jump Greater or Jump Not Less/Equal | OF, SF, ZF |
| JGE/JNL | Jump Greater/Equal or Jump Not Less | OF, SF |
| JL/JNGE | Jump Less or Jump Not Greater/Equal | OF, SF |
| JLE/JNG | Jump Less/Equal or Jump Not Greater | OF, SF, ZF |
以下是用于逻辑运算的无符号数据的条件跳转指令 −
| 说明 | 描述 | 已测试标志 |
|---|---|---|
| JE/JZ | Jump Equal or Jump Zero | ZF |
| JNE/JNZ | Jump not Equal or Jump Not Zero | ZF |
| JA/JNBE | Jump Above or Jump Not Below/Equal | CF, ZF |
| JAE/JNB | Jump Above/Equal or Jump Not Below | CF |
| JB/JNAE | Jump Below or Jump Not Above/Equal | CF |
| JBE/JNA | Jump Below/Equal or Jump Not Above | AF, CF |
以下条件跳转指令有特殊用途并检查标志的值 −
| 说明 | 描述 | 已测试标志 |
|---|---|---|
| JXCZ | Jump if CX is Zero | none |
| JC | Jump If Carry | CF |
| JNC | Jump If No Carry | CF |
| JO | Jump If Overflow | OF |
| JNO | Jump If No Overflow | OF |
| JP/JPE | Jump Parity or Jump Parity Even | PF |
| JNP/JPO | Jump No Parity or Jump Parity Odd | PF |
| JS | Jump Sign (negative value) | SF |
| JNS | Jump No Sign (positive value) | SF |
J<condition> 指令集的语法 −
示例,
CMP AL, BL JE EQUAL CMP AL, BH JE EQUAL CMP AL, CL JE EQUAL NON_EQUAL: ... EQUAL: ...
示例
以下程序显示三个变量中最大的一个。 变量是两位数变量。 三个变量 num1、num2 和 num3 的值分别为 47、22 和 31 −
section .text
global _start ;must be declared for using gcc
_start: ;tell linker entry point
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 ;file descriptor (stdout)
mov eax,4 ;system call number (sys_write)
int 0x80 ;call kernel
mov ecx,largest
mov edx, 2
mov ebx,1 ;file descriptor (stdout)
mov eax,4 ;system call number (sys_write)
int 0x80 ;call kernel
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

