汇编语言 逻辑指令

处理器指令集提供指令 ANDORXORTESTNOT 布尔逻辑,这些逻辑根据程序的需要测试、设置和清除位。

这些指令的格式如下:

编号指令格式
1ANDAND 操作数 1,操作数 2
2OROR 操作数 1,操作数 2
3XORXOR 操作数 1,操作数 2
4TESTTEST 操作数 1,操作数 2
5NOTNOT 操作数 1

在所有情况下,第一个操作数都可以在寄存器或内存中。第二个操作数可以是寄存器/内存,也可以是立即数(常数)。但是,内存到内存操作是不可能的。这些指令比较或匹配操作数的位,并设置 CFOFPFSFZF 标志。


AND 指令

AND 指令用于通过执行逐位 AND 运算来支持逻辑表达式。如果两个操作数的匹配位都是 1,则按位 AND 操作返回 1,否则返回 0。例如:

  1. Operand1: 0101
  2. Operand2: 0011
  3. ----------------------------
  4. After AND -> Operand1: 0001

AND 操作可用于清除一个或多个位。例如,假设 BL 寄存器包含 0011 1010 。如果需要将高位清除为 0,则使用 0FH 对其进行 与运算

  1. ANDBL, 0FH ; BL 设置为 0000 1010

让我们来看另一个例子。如果要检查给定数字是奇数还是偶数,一个简单的测试将是检查数字的最低有效位。如果为 1,则数字为奇数,否则为偶数。

假设数字在 AL 寄存器中,我们可以这样写:

  1. AND AL, 01H ; ANDing with 0000 0001
  2. JZ EVEN_NUMBER

下面是一个实例:

实例
  1. section .text
  2. global _start ;必须声明 gcc
  3. _start: ;告诉链接器入口点
  4. mov ax, 8h ;在 ax 中获得 8
  5. and ax, 1 ;进行与运算
  6. jz evnn
  7. mov eax, 4 ;系统调用号 (sys_write)
  8. mov ebx, 1 ;文件描述 (stdout)
  9. mov ecx, odd_msg ;消息
  10. mov edx, len2 ;消息长度
  11. int 0x80 ;调用内核
  12. jmp outprog
  13. evnn:
  14. mov ah, 09h
  15. mov eax, 4 ;系统调用号 (sys_write)
  16. mov ebx, 1 ;文件描述 (stdout)
  17. mov ecx, even_msg ;消息
  18. mov edx, len1 ;消息长度
  19. int 0x80 ;调用内核
  20. outprog:
  21. mov eax,1 ;系统调用号 (sys_exit)
  22. int 0x80 ;调用内核
  23. section .data
  24. even_msg db 'Even Number!' ;显示偶数的消息
  25. len1 equ $ - even_msg
  26. odd_msg db 'Odd Number!' ;显示奇数的消息
  27. len2 equ $ - odd_msg

结果如下:

  1. Even Number!

用一个奇数位更改 AX 寄存器中的值,例如:

  1. mov ax, 9h ; ax 中获取 9

结果如下:

  1. Odd Number!

同样,要清除整个寄存器,您可以将其与 00H 进行 与运算


OR 指令

OR 指令用于通过执行逐位 OR 运算来支持逻辑表达式。如果其中一个或两个操作数的匹配位为 1,则按位 OR 运算符返回 1。如果两个位都为 0,则返回 0。

比如,

  1. Operand1: 0101
  2. Operand2: 0011
  3. ----------------------------
  4. After OR -> Operand1: 0111

或运算 可用于设置一个或多个位。例如,假设AL寄存器包含 0011 1010,则需要设置 4 个低阶位,您可以将其与值 0000 1111(即 FH)进行 或运算

  1. OR BL, 0FH ; 设置 BL 0011 1111
实例

下面的实例演示 OR 指令。让我们将值 5 和 3 分别存储在 ALBL 寄存器中,然后是指令,

  1. OR AL, BL

应在 AL 寄存器中存储 7:

  1. section .text
  2. global _start ;必须设置 gcc
  3. _start: ;告诉链接器入口点
  4. mov al, 5 ;al 中获得 5
  5. mov bl, 3 ;bl 中获得 3
  6. or al, bl ;进行或运算, 结果应为 7
  7. add al, byte '0' ;将十进制转换为 ascii
  8. mov [result], al
  9. mov eax, 4
  10. mov ebx, 1
  11. mov ecx, result
  12. mov edx, 1
  13. int 0x80
  14. outprog:
  15. mov eax,1 ;系统调用号 (sys_exit)
  16. int 0x80 ;调用内核
  17. section .bss
  18. result resb 1

结果如下:

  1. 7

XOR 指令

XOR 指令实现按位异或运算。当且仅当来自操作数的位不同时,XOR 运算将结果位设置为 1。如果来自操作数的位相同(均为 0 或均为 1),则将结果位清除为 0。

例如,

  1. Operand1: 0101
  2. Operand2: 0011
  3. ----------------------------
  4. After XOR -> Operand1: 0110

将操作数与自身进行 XOR 会将操作数更改为 0。这用于清除寄存器。

  1. XOR EAX, EAX

TEST 指令

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

例如,

  1. TEST AL, 01H
  2. JZ EVEN_NUMBER

NOT 指令

NOT 指令实现按位否操作。NOT 运算反转操作数中的位。操作数可以在寄存器中,也可以在内存中。

例如,

  1. Operand1: 0101 0011
  2. After NOT -> Operand1: 1010 1100