본문 바로가기

Assembly

4-1강 - Data Transfer, Addressing and Arithmetic 1 (Data Transfer Instruction)

1. Data Transfer Instruction

1) Operand Type

1> Immediate (상수)
- a constant integer (8, 16, or 32 bits) (숫자 그 자체)
- instruction(opcode)에 맞게 인코딩된다. 
2> Register – uses a named register in the CPU
Register name은

- number로 변환되거나

- instruction(opcode)에 맞게 인코딩된다.

3> Memory – references a memory location
Memory address는

- instruction(opcode)에 맞게 인코딩되거나 (operand가 memory address를 가지거나)

- register가 memory address를 가지고 있다.

 

2) Instruction Operand Notation

- imm : immediate value를 나타내니 constant를 말하는 것이다.

- r/m

  • r은 위의 r8에서 r을 의미 => general register
  • m은 memory operand를 의미

 

3) Direct Memory Operands 

참고 : https://endlessong.tistory.com/32

 

 

4) MOV

1> format  

MOV destination, source

 

2> 정의 및 특징

- 정의 : source에서 destination으로 보내는 것이다.

- 'destination = source' 와 같은 의미이다. (다른 프로그래밍 언어에서 이렇게 사용)

 

3> 규칙

- destinationsourcesize가 같아야 한다.

- destinationsource 모두 memory operand 일 수 없다. (memory operand : mem) (일반 variable도 memory이다.)

- destinationIP, EIP, RIP, CS가 올 수 없다. (IP : instruction pointer) (segment 계열 자체가 안 된다. CS, SS, DS)

=> [1] size 같고 [2] 둘 중 적어도 하나는 memory operand가 아니어야 하고 [3] destination != IP 계열, segment 계열

(추가 규칙 : [4] destination으로 immediate(constant, 숫자, 상수)가 오면 안 된다.)

 

4> 예시

- 예시 1 : MOV instruction format

(MOV mem, mem 은 문법상 오류)

MOV reg, reg
MOV mem, reg
MOV reg, mem
MOV mem, imm
MOV reg, imm

- 예시 2 : Memory to Memory

.data
var1 WORD ?
var2 WORD ?

.code
mov ax, var1
mov var2, ax

- 예시 3 : Overlapping value

value가 있는 destination에 MOV 연산을 가할 경우 덮어 쓰게 된다.

.data
oneByte BYTE 78h
oneWord WORD 1234h
oneDword DWORD 12345678h

.code
mov eax, 0                ;EAX=00000000h
mov al, oneByte           ;EAX=00000078h
mov ax, oneWord           ;EAX=00001234h
mov eax, oneDword         ;EAX=12345678h
mov ax, 0                 ;EAX=12340000h

- mov al, oneByte : destination source의 size를 잘 맞춰주었다. -> 그래서 al의 자리인 오른쪽 2개의 byte를 변경

- mov ax, oneWord : destination (AX의 오른쪽 2자리 AL)에 값이 있지만 MOV로 덮어쓴다. (overlapping)

- mov eax, oneDword : destination (EAX의 오른쪽 4자리 AX)에 값이 있지만 MOV로 덮어쓴다. (overlapping)

- mov ax, 0 : destination (EAX의 오른쪽 4자리 AX)에서 값이 있지만 MOV로 AX에 해당하는 부분만 덮어쓴다. 

 

5> 추가 예제

- 예제 1

count BYTE 100
wVal WORD 2
. . .
mov bl,count
mov ax,wVal
mov count,al
mov al,wVal      ; error : al = 1 byte (8-bit), Wval = 2byte (16-bit)
mov ax,count     ; error : ax = 2 byte (16-bit), count = 1byte (8-bit)
mov eax,count    ; error : eax = 4 byte (32-bit), count = 1byte (8-bit)

- 예제 2

bVal BYTE 100
bVal2 BYTE ?
wVal WORD 2
dVal DWORD 5
. . .
mov ds,45       ; ds는 destination으로 사용 불가
mov esi,wVal    ; esi : 4 byte (32-bit), wVal : 2 byte (16-bit) 
mov eip,dVal    ; eip는 destination으로 사용 불가
mov 25,bVal     ; constant는 destination으로 사용 불가
mov bVal2,bVal  ; 둘 다 memory variable이므로 사용 불가

 

5) Zero Extension (MOVZX instruction)

1> format

MOVZX destination, source

(size : destination > source)

 

2> 정의 및 특징

- 정의 : 큰 자료형이 destination이고 작은 자료형이 source이면 앞 부분이 그대로 남아있는다. 이 때, 0으로 채운다.

- 양수를 옮길 때 주로 사용한다. (그러면 size가 다른 register로 이동해도 값을 보존할 수 있다.)

- destination으로 register가 와야 한다.

 

3> 예시

(binary 예시이다.)

mov bl, 10001111b
movzx ax, bl      ; zero-extension

 

6) Sign Extension (MOVSX instruction)

1> format

MOVSX destination, source

(size : destination > source)

 

2> 정의 및 특징

- 정의 : 큰 자료형이 destination이고 작은 자료형이 source이면 앞 부분이 그대로 남아있는다. 이 때, 1로 채운다.

- 음수를 옮길 때 주로 사용한다. (보수 꼴로 음수를 저장해서 size가 다른 register로 이동해도 값을 보존할 수 있다.)

- destination으로 register가 와야 한다.

 

3> 예시

(binary 예시이다.)

mov bl, 10001111b
movsx ax, bl      ; sign-extension

 

7) XCHG Instruction

exchange, swap 

1> format

XCHG op1, op2

 

2> 정의 및 특징

- 정의 : <register와 register> 혹은 <memory와 register>에 있는 값을 교환 (op1op2의 value를 교환한다.) (swap)

- size는 같아야한다.

- immediate는 op1op2에 올 수 없다. (immediate는 operand가 될 수 없다.) (숫자 자체를 교환 못 하니까)

- 둘 중(op1 op2) 적어도 하나는 register여야 한다.

 

3> 예시

var1 WORD 1000h
var2 WORD 2000h
. . .
xchg ax,bx       ; exchange 16-bit regs
xchg var1,bx     ; exchange mem, reg
xchg var1,var2   ; error: 둘 다 memory operand이다.

- 둘 다 variable (memory operand)가 되어서는 안 된다.

 

8) Direct-Offset Operands

1> data label에 constant offset을 더해서 effective address(EA)를 만든다.

2> 예시 1

.data
arrayW WORD 1000h,2000h,3000h
arrayD DWORD 1,2,3,4

.code
mov ax,[arrayW+2]              ; AX = 2000h
mov ax,[arrayW+4]              ; AX = 3000h
mov eax,[arrayD+4]             ; EAX = 00000002h
; 여기까지는 정상적으로 assemble 가능하다.
mov ax,[arrayW-2]              ; Out of range
mov eax,[arrayD+16]            ; Out of range
; 아래 둘은 unknown value를 가져올 수 있다. (0을 주로 가져온다.)

- mov ax, [arrayW+2]

  • arrayW : data label
  • 2 : constant offset
  • arrayW+2 : effective address (EA)
  • [arrayW+2] : break해서 주소가 가리키는 value인 2000h가 ax로 이동한다.

- (주의) WORD는 2 byte, DWORD는 4 byte 단위이니 각각 2와 4씩 증가해야 한다.

 

3> 예시 2 : 재배열 예시

.data
arrayD DWORD 1,2,3

mov eax,arrayD			; 							<eax = 1>, [1, 2, 3]
xchg eax,[arrayD+4]		; 1(eax)과 2를 교환 (xchg) <eax =  2>, [1, 1, 3]
xchg eax,[arrayD+8]		; 2(eax)와 3을 교환 (xchg) <eax = 3>, [1, 1, 2]
mov arrayD,eax			; 							<eax = 3>, [3, 1, 2]

 

4> 예시 3

.data
myBytes BYTE 80h,66h,0A5h

 

- 오류 1 : 덧셈할 때 선언된 size(BYTE => 2byte)를 초과하면 잘려나간다.

.code
mov al,myBytes		; al = 80h
add al,[myBytes+1]	; al = 0E6h 
add al,[myBytes+2]	; al = 8Bh (원래 계산 결과 18Bh이지만 size 초과로 1은 저장할 수 없다.)
  • 2번째 : '0E6h' 에서 0은 뒤의 E가 16진수의 숫자라는 것을 표시하기 위해 사용
  • 3번째 : 원래 계산 결과 18Bh이지만 size 초과로 1은 저장할 수 없다.

 

- 오류 2: size mismatch

mov ax,myBytes
add ax,[myBytes+1]
add ax,[myBytes+2]
  • al은 2byte, ax는 4byte 용

- 오류 3

movzx ax,myBytes
mov bl,[myBytes+1]
add ax,bx
mov bl,[myBytes+2]
add ax,bx ; AX = sum
  • line 3에서는 bx의 bl만 초기화되고 bh가 0으로 초기화 된 것이 아니므로 원하지 않는 결과를 얻을 수 있습니다.
    • ax = (ah) 00 | (al) 80
    • bx = (ah) XX | (bl) 66

  • line 5도 동일한 문제가 생깁니다.

<코드 수정>

movzx ax,myBytes
movzx bx,[myBytes+1]
add ax,bx
movzx bx,[myBytes+2]
add ax,bx