* Operand type
- Immediate (즉시값) : 상수, 숫자
- register (레지스터)
- memory (메모리)
- R8 : AH, AL, BH, BL, CH, CL, DH, DL
- R16 : AX, BX, CX, DX, SI, DI, SP, BP
- R32 : EAX, EBX, ECX, EDX, ESI, EDI, ESP, EBP
- SERG : CS, BS, SS
- IMM : immediate value, number
- r/m [size] : register or memory
> Direct Memory Operands
// 변수는 주소값을 가르킨다. 변수에서 +-를 시켜서 직접적으로 이동이 가능(Offset move)
.data
var BYTE 10h ; offset value 00001000
mov al, [00001000] ; mov al, var 과 같은 의미.
; [ㅁ]는 ㅁ의 내용을 지칭. 실질적으로 메모리를 쓸때는 '[]'생량 가능
; 그러나 지금과 같이 실질적 주소를 사용하면 '[]'를 해줘야 한다.
mov al, [var + 5] ; val_offset + 5 = 00001005 위치의 값을 al로 이동
mov al, var+5 ; var + 5 = 15h를 al로 이동
; 변수 > 단지 그 offset 값을 가르키며, pointer처럼 사용됨
; 위와 같은 혼동을 막기 위해서 '[]'를 써주는 것이 좋다!
; >> Direct offset operand
* MOV 연산
- mov destination, source
- 매우 유연함
- destination에 CS(code section), EIP, IP(instruction pointer)는 둘 수 없다. (Program execute와 밀접)
- role(조건)
> 두 피연산자는 같은 size
> 두 피연산자 모두 메모리 피연산자여서는 안된다.
> CS, EIP, IP는 도착점 피연산자가 될수 없다.
> 즉시값은 세그먼트 register로 이동이 불가능
- memory에서 memory로 이동, register를 사용
> mov var2, val1(X) > mov ax, var1
mov var2, ax
* 정수의 부호확정(Zero/sign extension)
- 작은 메모리의 값을 더 큰 메모리로 이동/복사 할때 사용된다.
- unsigned value = zero extension / 복사될 value를 0으로 두고선 복사 실시
> 큰 레지스터를 0으로 체운후에 그보다 작은 레지스터를 큰 레지스터의 뒷부분에 복사
ex)
.data
count word 1
.code
mov ecx, 0 ; ecx를 0으로 초기화(4byte)
mov cx , count ; ecx의 뒷부분(cx)에 count값을 복사
- signed value = sign extension / 복사될 값에 FFFF(max value)로 두고선 복사 실시
> 큰 레지스터를 가장 큰수(F)로 체운후 그보다 작은 레지스터 뒷부분을 복사 또는 이동
ex)
.data
count word f000h
.code
mov ecx, ffff ; ecx를 max값으로 변환
mov cx,count ; ecx의 뒷부분(cx)에 count값 복사
- Unsigned와 signed에 따라서 나눠서 실행하기 어렵기 때문에 별도의 명령어를 제공해준다.
ⓐ movzx 명령(zero extension)
- source값을 destination 으로 이동 후 0으로 앞을 체운다.(부호없는 정수에만 사용)
ex) MOVZ r32, r/m 8
MOVZX r32, r/m 16 ; destination is register
ⓑ MOVSX 명령(signed extension)
- source 값을 dstination으로 이동 후 sign bit을 확장한다.
ex) MOVSX r32, r/m8
* LAHF와 SAHF 명령(flag 관련)
- LAHF : load flag into ah, flag 값을 모두 ah에 복사
- SAHF : save ah into flag, ah에 저장된 값을 flag로 다시 복사
- function등을 사용시 되돌아 왔을대 이전 값을 복구하기 위해서 사용한다.
ex)
LAHF
mov saveflags, ah ; saveflags변수로 flag상태 저장
; some instruction
mov ah, saveflags ; saveflags변수를 ah로 복사
SAHF
* XCHG 명령
- 두 피연산자의 내용을 맞교환한다.
- 즉시값을 제외(숫자는 memory에 저장되지 않는다!)하고 모두 mov와 같은 role을 같는다.
- memory끼리의 맞교환을 위해서는 임시로 레지스터를 사용하고 mov연산자를 사용해야한다.
ex) xchg ax,bx
mov ax, val1
xchg ax, val2
mov val1, ax
* INC, DEC명령
- 단일 피연산자에 1을 더하거나 빼는 연산자.
ex) INC reg/mem
.data
val word 1000h
.code
inc val ; 1001h
dec val ; 1000h
* 연산명령어
- ADD dest,source ; dest = dest + source // 메모리끼리 불가능
- SUB dest,source ; dest = dest - source // 메모리끼리 불가능
- NEG reg/mem ; value = -value
* Flags
- Zero flag : 연산결과가 0이면 1로 set된다.
- carry flag : add연산시에는 마지막 carry값이 1이면 1로 set된다.
minus연산 시에는 작은수에서 큰수를 뺄때 1로 set된다. (없는 1을 빌려옴)
음수의 최대 값에 NEG연산을 실시하면 1로 set된다.(없는 1을 빌려옴)
- overflow flag : signed arithmetic으로 가정 하였을때 overflow시 1로 set된다.
- sign flag : 연산결과가 음수이면 1로 set딘다.
※ INC/DEC연산시 zero flag에는 영향을 주지만 carry flag에는 영향을 주지 않는다.
> 덧셈, 뺄셈개념이 아니다!!
ex)
.data
var byte 255
.code
inc var ; ZF = 1, CF = 0