기본 구조
동사에 해당하는 **명령어(Operation Code, Opcode)**와 목적어에 해당하는 **피연산자(Operand)**로 구성
명령어**(Operation Code, Opcode)**
Arithmetic Instruction
명령어 |
설명 |
ADD |
캐리를 포함하지 않은 덧셈 |
SUB |
캐리를 포함하지 않은 뺄셈 |
ADC |
캐리를 포함한 덧셈 |
SBB |
캐리를 포함한 뺄셈 |
CMP |
두개의 오퍼랜드 비교 |
INC |
오프랜드 내용을 1 증가 |
DEC |
오프랜드 내용을 1 감소 |
NEG |
오퍼랜드의 2의 보수, 즉 부호 반전 |
AAA |
덧셈 결과 AL 값을 UNPACK 10 진수로 보정 |
DAA |
덧셈 결과 AL 값을 PACK 10진수로 보정 |
AAS |
뺄셈 결과 AL 값을 UNPACK 10 진수로 보정 |
DAS |
뺄셈 결과 AL 값을 PACK 10진수로 보정 |
MUL |
AX와 오퍼랜드를 곱셈하여 결과를 AX 또는 DX:AX에 저장 |
IMUL |
부호화된 곱셈 |
AAM |
곱셈 결과 AX 값을 UNPACK 10진수로 보정 |
DIV |
AX 또는 DX:AX 내용을 오퍼랜드로 나눔. |
몫은 AL, AX 나머지는 AH, DX로 저장 | | IDIV | 부호화된 나눗셈 | | AAD | 나눗셈 결과 AX 값을 UNPACK 10진수로 보정 | | CBW | AL의 바이트 데이터를 부호 비트를 포함하여 AX 워드로 확장 | | CWD | AX의 워드 데이터를 부호를 포함하여 DX:AX의 더블 워드로 변환 |
Data Transfer Instruction
명령어 |
설명 |
MOV |
데이터 이동(전송) |
PUSH |
오퍼랜드 내용을 스택에 쌓음 |
POP |
스택으로부터 값을 가져옴 |
XCHG |
첫 번째 오퍼랜드와 두 번째 오퍼랜드 교환 |
XLAT |
BX:AL 이 지시한 테이블의 내용을 AL로 로드 |
LEA |
메모리 오프셋값을 레지스터로 로드 |
LDS |
REG ← (MEM), ds ← (MEM+2) |
LES |
REG ← (MEM), ES ← (MEM+2) |
LAHF |
플래그의 내용을 AH의 특정 비트로 로드 |
SAHF |
AH의 특정 비트가 플래그 레지스터로 전송 |
PUSHF |
플래그 레지스터의 내용을 스택에 쌓음 |
POPF |
스택으로부터 플래그 레지스터로 가져옴 |
Logical Instruction
명령어 |
설명 |
NOT |
오퍼랜드의 1의 보수, 즉 비트 반전 |
SHL / SAL |
왼쪽으로 오퍼랜드만큼 자리 이동(최하위 비트는 0) |
SHR |
오른쪽으로 오퍼랜드만큼 자리이동(최상위 비트는 0) |
SAR |
오른쪽으로 자리 이동, 최상위 비트는 유지 |
ROL / ROR |
왼쪽 / 오른쪽으로 오퍼랜드만큼 회전이동 |
RCL / RCR |
캐리를 포함하여 왼쪽 / 오른쪽으로 오퍼랜드만큼 회전 이동 |
AND |
논리 AND |
TEST |
첫 번째 오퍼랜드와 두 번째 오퍼랜드를 AND 하여 그 결과로 플래그 세트 |
OR |
논리 OR |
XOR |
배타 논리 합(OR) |
String Instruction
명령어 |
설명 |
REP |
REP 뒤에 오는 STRING 명령어를 CS가 0이 될 때까지 반복 |
MOVS |
DS:DI가 지시한 메모리 데이터를 ES:DI가 지시한 메모리로 전송 |
COMPS |
DS:DI와 ES:DI의 내용을 비교하고 결과에 따라 플래그 설정 |
SCAS |
AL 또는 AX와 ES:DI가 지시한 메모리 내용 비교하고 결과에 따라 플래그 설정 |
LODS |
SI 내용을 AL 또는 AX로 로드 |
STOS |
AL 또는 AX를 ES:DI가 지시하는 메모장에 저장 |
Control Transfer Instruction
명령어 |
설명 |
예시 |
CALL |
프로시저 호출 |
|
JMP |
무조건 분기 |
|
RET |
CALL로 스택에 PUSH된 주소로 복귀 |
|
JE / JZ |
결과가 0이면 분기 |
ZF = 1 |
JL / JNGE |
결과가 작으면 분기(부호화된 수) |
SF ≠ OF |
JB / JNAE |
결과가 작으면 분기(부호화 안된 수) |
CF = 1 |
JLE / JNG |
결과가 작거나 같으면 분기(부호화된 수) |
ZF = 1 or SF ≠ OF |
JBE / JNA |
결과가 작거나 같으면 분기(부호화 안된 수) |
CF = 1 or ZF = 1 |
JP / JPE |
Parity Flag가 1이면 분기 |
PF = 1 |
JO |
오버플로우가 발생하면 분기 |
OF = 1 |
JS |
플래그가 1이면 분기 |
SF = 1 |
JUMP Instruction
명령어 |
설명 |
예시 |
JC |
캐리가 발생하면 분기 |
CF = 1 |
JNE / JNZ |
결과가 0이 아니면 분기 |
ZF = 0 |
JNL / JGE |
결과가 크거나 같으면 분기(부호화 된 수 ) |
SF = OF |
JNB / JAE |
결과가 크거나 같으면 분기(부호화 안된 수) |
CF = 0 |
JNLE / JG |
결과가 크면 분기(부호화된 수) |
ZF = 0 AND SF = OF |
JNBE / JA |
결과가 크면 분기(부호화 안된 수) |
CF = 0 AND ZF = 0 |
JNP / JPO |
패리티 플래그가 0이면 분기 |
PF = 0 |
JNO |
오버플로우가 아닌 경우 분기 |
OF = 0 |
JNS |
부호 플래그가 0이면 분기 |
SF = 0 |
JNC |
캐리가 아닌 경우 분기 |
CF = 0 |
LOOP |
CX를 1로 감소, 0이 될 때까지 지정된 라벨로 분기 |
|
LOOPZ / LOOPE |
CX가 0이면 지정된 라벨로 분기 |
ZF = 1 |
LOOPNZ / LOOPNE |
CX가 0이 아니면 지정된 라벨로 분기 |
ZF = 0 |
JCXZ |
CX가 0이면 분기 |
CX = 0 |
INT |
인터럽트 실행 |
|
INTO |
오버플로우가 발생하면 인터럽트 실행 |
|
IRET |
인터럽트 복귀(리턴) |
|
Processor Control Instruction
명령어 |
설명 |
CLC |
캐리 플래그 클리어 |
CMC |
캐리 플래그를 반전 |
CLD |
디렉션 플래그를 클리어 |
CLI |
인터럽트 플래그를 클리어 |
HLT |
정지 |
STC |
캐리 플래그 셋 |
NOP |
아무 동작 하지 않음 |
STD |
디렉션 플래그 셋 |
STI |
인터럽트 플래그 셋 |
WAIT |
프로세서를 일시 정지 상태로 한다. |
ESC |
이스케이프 명령 |
피연산자(Operand)
- 상수(Immediate Value)
- 레지스터(Register)
- 메모리(Memory)
- BYTE, WORD, DWORD, QWORD
각각 1바이트, 2바이트, 4바이트, 8바이트의 크기를 지정
프로시저
- 특정 기능을 수행하는 코드 조각
- 호출(Call) : 프로시저를 부르는 행위
- 반환(Return) : 프로시저에서 돌아오는 것
- call addr : addr에 위치한 프로시져 호출
- 연산
jmp addr
push return_address
- leave : 스택프레임 정리
💡 스택 프레임
함수별로 서로가 사용하는 스택의 영역을 구분하기 위한 프레임