彙編 - 邏輯指令
處理器指令集提供了 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