汇编语言 逻辑指令

  • 逻辑指令

    处理器指令集提供指令AND,OR,XOR,TEST和NOT布尔逻辑,它们根据程序的需要测试,设置和清除位。
    这些说明的格式-
    指令 格式
    AND AND 操作数1,操作数2
    OR OR 操作数1,操作数2
    XOR XOR 操作数1,操作数2
    TEST TEST 操作数1,操作数2
    NOT NOT 操作数1
    在所有情况下,第一个操作数都可以在寄存器或内存中。第二个操作数可以是寄存器/内存,也可以是立即数(常数)。但是,内存到内存操作是不可能的。这些指令比较或匹配操作数的位,并设置CF,OF,PF,SF和ZF标志。
  • AND 指令

    AND 指令用于通过执行按位AND运算来支持逻辑表达式。如果两个操作数的匹配位均为1,则按位AND运算返回1,否则返回0。例如-
    
                 Operand1:  0101
                 Operand2:  0011
    ----------------------------
    After AND -> Operand1:       0001
    
    AND 操作可用于清除一个或多个位。例如,假设BL寄存器包含00111010。如果您需要将高阶位清除为零,则将其与0FH进行“与”运算。
    
    AND     BL,   0FH   ; This sets BL to 0000 1010
    
    让我们来看另一个例子。如果要检查给定数字是奇数还是偶数,一个简单的测试将是检查数字的最低有效位。如果为1,则数字为奇数,否则为偶数。
    假设数字在AL寄存器中,我们可以写-
    
    AND     AL, 01H     ; ANDing with 0000 0001
    JZ    EVEN_NUMBER
    
    以下程序说明了这一点-
    
    section .text
       global _start            ;must be declared for using gcc
            
    _start:                     ;tell linker entry point
       mov   ax,   8h           ;getting 8 in the ax 
       and   ax, 1              ;and ax with 1
       jz    evnn
       mov   eax, 4             ;system call number (sys_write)
       mov   ebx, 1             ;file descriptor (stdout)
       mov   ecx, odd_msg       ;message to write
       mov   edx, len2          ;length of message
       int   0x80               ;call kernel
       jmp   outprog
    
    evnn:   
      
       mov   ah,  09h
       mov   eax, 4             ;system call number (sys_write)
       mov   ebx, 1             ;file descriptor (stdout)
       mov   ecx, even_msg      ;message to write
       mov   edx, len1          ;length of message
       int   0x80               ;call kernel
    
    outprog:
    
       mov   eax,1              ;system call number (sys_exit)
       int   0x80               ;call kernel
    
    section   .data
    even_msg  db  'Even Number!' ;message showing even number
    len1  equ  $ - even_msg 
       
    odd_msg db  'Odd Number!'    ;message showing odd number
    len2  equ  $ - odd_msg
    
    尝试一下
    编译并执行上述代码后,将产生以下结果-
    
    Even Number!
    
    用一个奇数位更改ax寄存器中的值,例如-
    
    mov  ax, 9h                  ; getting 9 in the ax
    
    该程序将显示:
    
    Odd Number!
    
    同样,要清除整个寄存器,您可以将其与00H进行“与”运算。
  • OR 指令

    OR 指令用于通过执行按位或运算来支持逻辑表达式。如果来自任何一个或两个操作数的匹配位为1,则按位OR运算符将返回1。如果两个位均为零,则返回0。
    例如,
    
    
                 Operand1:     0101
                 Operand2:     0011
    ----------------------------
    After OR -> Operand1:    0111
    
    或运算可用于设置一个或多个位。例如,假设AL寄存器包含0011 1010,则需要设置四个低阶位,您可以将其与值0000 1111(即FH)进行或运算。
    
    OR BL, 0FH                   ; This sets BL to  0011 1111
    
    下面的示例演示OR指令。让我们将值5和3分别存储在AL和BL寄存器中,然后是指令,
    
    OR AL, BL
    
    应该在AL寄存器中存储7-
    
    section .text
       global _start            ;must be declared for using gcc
            
    _start:                     ;tell linker entry point
       mov    al, 5             ;getting 5 in the al
       mov    bl, 3             ;getting 3 in the bl
       or     al, bl            ;or al and bl registers, result should be 7
       add    al, byte '0'      ;converting decimal to ascii
            
       mov    [result],  al
       mov    eax, 4
       mov    ebx, 1
       mov    ecx, result
       mov    edx, 1 
       int    0x80
        
    outprog:
       mov    eax,1             ;system call number (sys_exit)
       int    0x80              ;call kernel
            
    section    .bss
    result resb 1
    
    尝试一下
    编译并执行上述代码后,将产生以下结果-
    
    7
    
  • XOR 指令

    XOR 指令实现按位XOR运算。当且仅当来自操作数的位不同时,XOR运算将结果位设置为1。如果来自操作数的位相同(均为0或均为1),则将结果位清除为0。
    例如,
    
                 Operand1:     0101
                 Operand2:     0011
    ----------------------------
    After XOR -> Operand1:    0110
    
    将操作数与自身进行XOR会将操作数更改为0。这用于清除寄存器。
    
    XOR     EAX, EAX
    
  • TEST 指令

    TEST 指令与AND运算的工作原理相同,但与AND指令不同的是,它不会更改第一个操作数。因此,如果我们需要检查寄存器中的数字是偶数还是奇数,我们也可以使用TEST指令执行此操作,而无需更改原始数字。
    
    TEST    AL, 01H
    JZ      EVEN_NUMBER
    
  • NOT 指令

    NOT 指令实现按位NOT运算。NOT操作将操作数中的位取反。操作数可以在寄存器中,也可以在存储器中。
    例如,
    
                 Operand1:    0101 0011
    After NOT -> Operand1:    1010 1100