汇编 - 逻辑指令
处理器指令集提供了 AND、OR、XOR、TEST 和 NOT 布尔逻辑指令,根据程序需要测试、设置和清除位。
这些指令的格式如下:
序号 | 指令 | 格式 |
---|---|---|
1 | AND | AND 操作数1, 操作数2 |
2 | OR | OR 操作数1, 操作数2 |
3 | XOR | XOR 操作数1, 操作数2 |
4 | TEST | TEST 操作数1, 操作数2 |
5 | NOT | NOT 操作数1 |
在所有情况下,第一个操作数可以是寄存器或内存中的值。第二个操作数可以是寄存器/内存中的值或立即数(常量)。但是,内存到内存的操作是不可能的。这些指令比较或匹配操作数的位,并设置 CF、OF、PF、SF 和 ZF 标志。
AND 指令
AND 指令用于通过执行按位 AND 操作来支持逻辑表达式。按位 AND 操作如果两个操作数的匹配位都为 1,则返回 1,否则返回 0。例如:
Operand1: 0101 Operand2: 0011 ---------------------------- After AND -> Operand1: 0001
AND 操作可用于清除一个或多个位。例如,假设 BL 寄存器包含 0011 1010。如果需要将高位清零,则将其与 0FH 进行 AND 操作。
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 进行 AND 操作。
OR 指令
OR 指令用于通过执行按位 OR 操作来支持逻辑表达式。按位 OR 运算符如果两个操作数中的任一个或两个操作数的匹配位为 1,则返回 1。如果两个位都为零,则返回 0。
例如,
Operand1: 0101 Operand2: 0011 ---------------------------- After OR -> Operand1: 0111
OR 操作可用于设置一个或多个位。例如,假设 AL 寄存器包含 0011 1010,需要设置四个低位,则可以将其与值 0000 1111,即 FH 进行 OR 操作。
OR BL, 0FH ; This sets BL to 0011 1111
示例
以下示例演示了 OR 指令。让我们分别将值 5 和 3 存储在 AL 和 BL 寄存器中,然后指令,
OR AL, BL
应将 7 存储在 AL 寄存器中:
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),则结果位将清零。
例如,
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