프로세서 명령어 세트는 AND, OR, XOR, TEST, NOT 명령어를 제공한다. 이 명령어들은 프로그램의 필요에 따라 비트를 test, set, clear한다.
명령어들은 다음과 같다.
명령어 | 형식 | |
---|---|---|
1 | AND | AND 피연산자1, 피연산자2 |
2 | OR | OR 피연산자1, 피연산자2 |
3 | XOR | XOR 피연산자1, 피연산자2 |
4 | TEST | TEST 피연산자1, 피연산자2 |
5 | NOT | NOT 피연산자1 |
모든 경우의 첫 번째 피연산자는 레지스터나 메모리에 위치한다. 두 번째 피연산자는 레지스터나 메모리에 위치하거나 즉시 상수 값(immediate constant value)이다. 하지만, 메모리-메모리 간의 연산은 불가능하다. 이 명령어들은 피연산자의 비트를 비교하거나 일치시킨다. 그리고 CF, OF, PF, SF, ZF 플래그를 설정한다.
AND 명령어는 비트 단위(bitwise) AND 명령을 하기 위해 사용된다. 비트 단위 AND 명령어는 같은 자리의 비트가 둘 다 1이라면 1을 반환하고, 그렇지 않으면 0을 반환한다. 예를 들어,
Operand1: 0101
Operand2: 0011
------------------------------
After AND -> Operand1: 0001
AND 명령어는 하나 또는 그 이상의 비트를 클리어하는데 사용할 수 있다. 예를 들어, BL 레지스터가 0011 1010을 담고 있고, 상위 비트들을 0으로 초기화하고 하고자 한다면, 0FH와 AND 연산을 하면 된다.
AND BL, 0FH ; BL을 0000 1010로 변경한다.
다른 예를 들어보자. 주어진 숫자가 짝수인지 홀수인지 확인하고 싶다면, 숫자의 최하위 비트(least significant bit)를 확인하면 된다. 최하위 비트가 1이라면, 숫자는 홀수이고 0이라면, 짝수이다.
숫자가 AL레지스터에 저장되어 있다고 하면, 다음과 같이 할 수 있다.
AND AL, 01H ; AL과 0000 0001의 AND 연산
JZ EVEN_NUMBER
이에 관한 프로그램은 다음과 같다.
❗️ 64비트 Intel macOS에서 동작하는 코드이다.
section .text
global _main
_main:
mov ax, 8h ; ax에 8저장
and ax, 1 ; ax과 1 AND 연산
; AND 연산결과가 0이면 zero flag가 1
; AND 연산결과가 1이면 zero flag가 0
jz even ; zero flag가 1인 경우, even로 이동
mov rax, 0x2000004
mov rdi, 1
mov rsi, odd_msg
mov rdx, len2
syscall
jmp outprog
even:
mov ah, 09h
mov rax, 0x2000004
mov rdi, 1
mov rsi, even_msg
mov rdx, len1
syscall
outprog:
mov rax, 0x2000001
mov rdi, 0
syscall
section .data
even_msg db 'Even Number!'
len1 equ $ - even_msg
odd_msg db 'Odd Number!'
len2 equ $ - odd_msg
코드를 컴파일하고 실행하면, 다음의 결과를 확인할 수 있다.
Even Number!
ax 레지스터에 홀수를 넣으면
mov ax, 9h ; ax에 9를 넣는다.
프로그램은 다음과 같이 출력한다.
Odd Number!
레지스터의 모든 값을 클리어하기 위해서는 00H와 AND연산을 하면 된다.
OR 명령어는 비트 단위 OR 연산을 처리하기 위해 사용된다. 비트 단위 OR 명령어는 같은 자리의 비트가 하나라도 1이라면 1을 반환한다. 그리고 두 비트가 모두 0이라면 0을 반환한다.
예를 들어,
Operand1: 0101
Operand2: 0011
------------------------------
After OR -> Operand1: 0111
OR 명령은 하나 또는 그 이상의 비트를 설정하는데 사용할 수 있다. 예를 들어, AL 레지스터에 0011 1010이 들어있다고 가정하고, 하위 비트들의 값을 설정하고 싶다면, 0000 1111과 OR 연산을 하면 된다. 즉, FH
OR BL, 0FH ; BL을 0011 1111로 설정한다.
예제
다음 예제는 OR 연산을 설명한다. AL 레지스터에 5을 저장하고 BL 레지스터에 3을 각각 저장하고, 다음의 명령을 실행한다.
OR AL, BL
AL 레지스터에는 7이 저장된다.
❗️ 64비트 Intel macOS에서 동작하는 코드이다.
section .text
global _main
_main:
mov al, 5
mov bl, 3
or al, bl
add al, byte '0'
mov r10, result
mov [r10], al
mov rax, 0x2000004
mov rdi, 1
mov rsi, result
mov rdx, 1
syscall
outprog:
mov rax, 0x2000001
syscall
section .bss
result resb 1
코드를 컴파일하고 실행하면, 다음의 결과를 얻을 수 있다.
7
XOR 명령어는 XOR 연산을 실행한다. XOR 명령어는 피연산자들의 같은 자리 비트가 서로 다를 경우에만 결과 비트를 1로 설정한다. 피연산자의 비트가 같다면(둘 다 0이거나 1), 결과 비트는 0으로 설정된다.
예를 들어,
Operand1: 0101
Operand2: 0011
------------------------------
After XOR -> Operand1: 0110
동일한 피연산자끼리 XOR 연산을 수행하면 피연산자가 0으로 초기화 된다. 이런 연산은 레지스터를 초기화하는데 사용한다.
XOR EAX, EAX
TEST 명령어는 AND 명령어와 같은 동작을 한다. 그러나, AND 명령어와 다르게, 첫 번째 피연산자를 변경하지 않는다. 그래서, 레지스터에 있는 숫자가 짝수인지 홀수인지 확인하고자 한다면, 원본 숫자를 변경하지 않는 TEST 명령어를 사용할 수 있다.
TEST AL, 01H
JZ EVEN_NUMBER
NOT 명령어는 비트 단위 NOT 연산을 실행한다. NOT 명령어는 피연산자의 비트를 반대로 바꾼다. 피연산자는 레지스터나 메모리에 위치한다.
예를 들어,
Operand1: 0101 0011
After NOT -> Operand1: 1010 1100