외로운 Nova의 작업실

Assembly 언어 공부 - 14(데이터 전송 이론 및 실습) 본문

Programming/Assembly

Assembly 언어 공부 - 14(데이터 전송 이론 및 실습)

Nova_ 2022. 7. 29. 23:06

안녕하세요, 이번시간에는 어셈블리어에서 데이터 전송에 대해서 배워보도록 하겠습니다.

 

MOV

MOV destination(첫번째 피연산자), source(두번째 피연산자)

MOV 명령어는 두번째 피연산자의 값을 첫번째 피연산자로 값을 복사합니다. mov를 사용할때 주의할점은 메모리의 값을 다른 메모리로 전송을 못한다는 것입니다. 메모리 간의 전송을 할때는 레지스터를 사용하여 교환을 이루어지게 해줘야합니다.

 

MOVZX

MOVZX destination(첫번째 피연산자), source(두번째 피연산자)

MOVZX 명령어는 두번째 피연산자의 값을 첫번째 피연산자로 값을 복사하면서, 남는 공간을 0으로 채우게됩니다.

예를 들어, eax에 AADDBBCC가 있다고 했을때 MOVZX eax, AABB를 하게되면 eax에는 0000AABB가 됩니다.

 

MOVSX

MOVSX destination(첫번째 피연산자), source(두번째 피연산자)

MOVSX 명령어는 두번째 피연산자의 값을 첫번째 피연산자로 값을 복사하면서, 남는 공간을 부호비트로 채우게됩니다.

MOVSX 명령어가 있는 이유는 아래의 코드를 보고 확인 할 수 있습니다.

.data
signedVal SWORD -16 ;FFF0h(-16)

.code
mov ecx, 0
mov cx, signedVal ;ECX = 0000FFF0h(+65,520)

위와 같은 코드를 쓰게되면 mov를 통해 -16을 복사해야하지만 결국 복사된 값은 +65,520입니다. 이를 방지하려면 ECX에는 FFFFFFF0h가 되었어야합니다. 즉, 0대신 부호비트 F가 채워져야한다는 것입니다. 이를 위해 MOVSX가 나왔습니다. 위 코드를 알맞게 변환 시키면 아래와 같은 코드가 됩니다.

.data
signedVal SWORD -16 ;FFF0h(-16)

.code
MOV ecx, 0
MOVSX cx, signedVal ;ECX = FFFFFFF0h(-16)

LAHF 명령어

LAHF 명령어는 Load AH, Flag 라는 뜻입니다. 즉, Flag의 값을 AH에 복사하라는 뜻입니다. Flag는 여러가지가 있지만 해당 명령어는 Sign, Zero, Carry, 보조 Carry, Parity 플래그가 복사됩니다.

 

SAHF 명령어

SAHF 명령어는 Store AH, Flag 라는 뜻입니다. 즉, AH 값을 Flag에 복사하라는 뜻입니다. LAHF 명령어와 함께 사용하면 이전에 변수에 저장해놓았던 플래그의 값을 복구할 수 있는 방법이 있습니다.

 

XCHG 

XCHG op1, op2 는 eXCHanGe data 라는 뜻입니다. op1 피연산자와 op2 피연산자의 값을 서로 바꿔주는 명령어 입니다. 단, 메모리 끼리는 서로 바꿀 수 없습니다.

 

직접 오프셋 피연산자

메모리 피연산자의 경우 결국, 메모리의 주소로 변환되는데, 그 과정에서 변위를 더하여 직접 오프셋 피연산자를 만들 수 있다. 예를 들어, arrayB BYTE 10h, 20h, 30h, 40h, 50h 가 있다해보자.

mov al, arrayB ; AL = 10h가 들어간다.

mov al, arrayB+1; AL = 20h가 들어간다.

mov al, arrayB+2; AL = 30h가 들어간다.

이런식으로 직접 오프셋 피연산자를 만들 수 있다.메모리의 경우 1개의 메모리에는 8비트가 들어간다.

 

예제 프로그램(MOVES)

; this program is Moves

include 	c:\assembly\irvine32.inc
includelib  c:\assembly\irvine32.lib
includelib  c:\assembly\kernel32.lib
includelib  c:\assembly\user32.lib

.data
val1 WORD 1000h
val2 WORD 2000h
arrayB BYTE 10h, 20h, 30h, 40h
arrayW WORD 1000h, 2000h, 3000h, 4000h
arrayD DWORD 10000000h, 20000000h

.code

main PROC

; Demonstracting MOVZX instruction:
mov bx, 0A69Bh
movzx eax, bx ; EAX = 0000A69Bh
movzx edx, bl ; EDX = 0000009Bh
movzx cx, bl ; CX = 009Bh
call DumpRegs

;Demonstracting MOVSX instruction:
mov bx, 0A69Bh
movsx eax, bx; EAX = FFFFA69Bh
movsx edx, bl; EDX = FFFFFF9Bh
movsx cx, bl; CX = FF9Bh
call DumpRegs

;Memory-to-memory exchange:
mov ax, val1 ; AX = 1000h
xchg ax, val2 ; AX = 2000h, val2 = 1000h
mov val1, ax; val1 = 2000h
movzx eax, val1 ; EAX = 00002000h
movzx ebx, val2 ; EBX = 00001000h
call DumpRegs

;Direct-Offset Addressing(byte array)
mov al, arrayB ; AL = 10h
mov al, [arrayB + 1] ; AL = 20h
mov al, [arrayB + 2] ; AL = 30h
movzx eax, [arrayB + 3] ; EAX = 00000040h
call DumpRegs

;Direct-Offset Addressing(word array)
mov ax, arrayW ; ax = 1000h
mov ax, [arrayW + 2] ; ax = 2000h
movzx eax, [arrayW + 4] ; EAX = 00003000h
call DumpRegs

;Direct-Offset Addressing(Dword array)
mov eax, arrayD ; EAX = 10000000h
mov eax, [arrayD + 4] ; EAX = 20000000h
call DumpRegs

exit

main ENDP
END main

위 코드를 실행시키면 아래와 같이 실행됩니다.

코드에 있는 주석과 같이 한번 보시게되면 실제로 잘 적용 된 것을 확인 할 수 있습니다. 

Comments