📜  装配-条件

📅  最后修改于: 2020-11-05 05:07:27             🧑  作者: Mango


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

Sr.No. Conditional Instructions
1

Unconditional jump

This is performed by the JMP instruction. Conditional execution often involves a transfer of control to the address of an instruction that does not follow the currently executing instruction. Transfer of control may be forward, to execute a new set of instructions or backward, to re-execute the same steps.

2

Conditional jump

This is performed by a set of jump instructions j depending upon the condition. The conditional instructions transfer the control by breaking the sequential flow and they do it by changing the offset value in 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

条件跳转

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

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

Instruction Description Flags tested
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

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

Instruction Description Flags tested
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

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

Instruction Description Flags tested
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 指令集的语法-

例,

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