汇编 - 条件执行

汇编语言中的条件执行是通过多个循环和分支指令完成的。 这些指令可以改变程序中的控制流程。 在两种情况下观察到条件执行 −

序号 条件说明
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