汇编语言 条件

  • 条件

    汇编语言中的条件执行是通过几个循环和分支指令来完成的。这些指令可以更改程序中的控制流。在两种情况下观察到条件执行-
    • 无条件跳转 - 这是通过JMP指令执行的。条件执行通常涉及将控制权转移到不遵循当前执行指令的指令的地址。控制权的转移可以是前进的(执行新的指令集),也可以是后退的(重新执行相同的步骤)。
    • 无条件跳转 - 这取决于条件由一组跳转指令j <condition>执行。条件指令通过中断顺序流程来转移控制,而它们通过更改IP中的偏移值来进行控制。
    让我们在讨论条件指令之前先讨论CMP指令。
  • CMP指令

    CMP 指令比较两个操作数。它通常用于条件执行中。该指令基本上从另一个操作数中减去一个操作数,以比较操作数是否相等。它不会干扰目标或源操作数。它与条件跳转指令一起用于决策。
    句法
    
    CMP destination, source
    
    CMP 比较两个数字数据字段。目标操作数可以在寄存器中或在内存中。源操作数可以是常量(立即数)数据,寄存器或内存。
    
    CMP DX, 00  ; 将DX值与0进行比较
    JE  L7      ; 如果等于,则跳转到标签L7
    .
    .
    L7: ...  
    
    CMP 通常用于比较计数器值是否已达到需要运行循环的次数。考虑以下典型条件-
    
    INC     EDX
    CMP     EDX, 10 ; 比较计数器是否达到10
    JLE     LP1     ; 如果它小于或等于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为零则跳转 没有
    JC 如果携带则跳 CF
    JNC 如果不携带则跳转 CF
    JO 溢出时跳转 OF
    JNO 如果没有溢出则跳转 OF
    JP/JPE 跳校验或偶校验 PF
    JNP/JPO 跳转无奇偶校验或跳转奇偶校验 PF
    JS 跳跃符号(负值) SF
    JNS 跳转无符号(正值) 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