티스토리 뷰

** 번역한 내용이 대부분임. 문서 하단에 출처 참조함.


명령어 - 데이터 이동 / 산술 및 논리 연산

기계어는 주로 3가지 목표를 가진다. 
1. 데이터 이동 / 2. 알고리즘, 로직 / 3. 프로그램 흐름 제어
여기에서는, x86 시스템에서의 중요한 명령어를 예시를 들어 설명합니다.
단, 여기서 나타내는 예제들은 완전한 x86 명령어들은 아니지만, 보편적으로 유용한 부분을 가지고 있습니다. 완벽한 예제들을 보려면, Intel에서 제공하는 명령어 예제들을 참고하면 됩니다.

# 기호 표시
<reg32>    Any 32-bit register (EAXEBXECXEDXESIEDIESP, or EBP)
<reg16>Any 16-bit register (AXBXCX, or DX)
<reg8>Any 8-bit register (AHBHCHDHALBLCL, or DL)
<reg>Any register
<mem>A memory address (e.g., [eax][var + 4], or dword ptr [eax+ebx])
<con32>Any 32-bit constant
<con16>Any 16-bit constant
<con8>Any 8-bit constant
<con>Any 8-, 16-, or 32-bit constant


1. 데이터 이동 명령어

mov — Move (Opcodes: 88, 89, 8A, 8B, 8C, 8E, ...)

mov 명령어는 두번째 인자의 주어진 데이터(레지스터, 메모리 주소, 상수값)을 첫번째 인자에 복사합니다. (첫번째 인자의 데이터가 삭제되지 않음. 복사만 한다) 

주의할 점은, 레지스터끼리의 데이터 이동은 가능하지만, 메모리 주소간의 데이터 이동은 할 수 없다.

이러한 경우에 메모리 간 데이터 복사를 위해서는 복사하고자 하는 데이터를 먼저 특정 레지스터로 이동 후 이동해야 한다.


Syntax
mov <reg>,<reg>
mov <reg>,<mem>
mov <mem>,<reg>
mov <reg>,<const>
mov <mem>,<const>


mov eax, ebx — ebx의 데이터를 eax에 속사한다.
mov byte ptr [var], 5 — 상수값 5h 를 var 주소에 저장된 포인터가 가르키는 주소로 복사한다.



push — Push stack (Opcodes: FF, 89, 8A, 8B, 8C, 8E, ...)

push 명령어는 현재 ESP 레지스터가 가지고 있는 스택 메모리 주소에 인자 값을 복사하고, ESP 포인터의 값을 -4h 한다. (이 때, 무조건 4바이트 단위로 복사하게 된다.) ESP 포인터는 push 명령어에 의해 작아지게 되고, 스택이 아래로 자라게 된다.

-> 스택은 높은 메모리 주소(0xFFFFFFFF) 부터 낮은 메모리 주소(0x00000000)으로 자란다.

추가로 , 4바이트가 아닌 2바이트, 1바이트 크기의 레지스터는 곧바로 스택에 push 할 수 없다.


Syntax
push <reg32>
push <mem>
push <con32>

Examples
push eax — eax 레지스터의 데이터를 스택으로 옮긴다.
push [var] — var 포인터가 나타내는 메모리의 데이터를 스택으로 옮긴다.



pop — Pop stack

pop 명령어는 현재 ESP 레지스터가 가지고 있는 스택 메모리 주소에 있는 데이터를 인자로 복사하고, ESP 포인터의 값을 +4h 한다. (이 때, 무조건 4바이트 단위로 복사하게 된다.) ESP 포인터는 pop 메모리에 의해 커진다. 이때, pop명령 실행 시에 읽어진 메모리의 주소에 있는 데이터가 초기화되지는 않는다.


Syntax
pop <reg32>
pop <mem>



lea — Load effective address

lea 명령어는 2번째 인자의 메모리 주소를 첫번째 인자에 넣는다. 

원하는 메모리의 포인터를 얻을 때 흔히 사용되며, 주소값을 계산하여 액세스하는 과정에서, mov 명령어로 처리하면 프로그램이 길어지는 것을 좀 더 효율적으로 처리하기위해 만들어진 것으로 보인다.


Syntax
lea <reg32>,<mem>

Examples
lea edi, [ebx+4*esi] — EBX+4*ESI 의 주소값에 담긴 데이터가 edi에 로드된다. 브라켓이 없다면, 이 주소가 도르된다.
lea eax, [var] — var 의 데이터가 eax 로 로드된다.
lea eax, [val] — val 의 데이터가 eax 로 로드된다.


+

movsx / movzx (작은 데이터가 큰 공간으로 이동할 때, 최상의 비트를 복사 / 복사 하지 않음의 유무)

: src의 memory address 에 별도의 크기가 명시되어 있지 않는 경우 - 1바이트(8비트)를 복사한다.



2. 산술 및 논리 명령어

! - 간단한 명령어들은 생략. 본 문서 및의 참조에서 확인.

add / sub / inc / dec


imul — Integer Multiplication

imul 명령어는 정수 곱셈을 계산할 때 사용하며, 인자가 2개와 3개일 때의 2가지 문법을 지원한다.

인자가 2개일 경우, 첫번째 인자와 두번째 인자를 곱한 결과를 첫번째 인자에 저장한다.

인자가 3개일 경우, 두번째 인자와 세번째 인자를 곱한 결과를 첫번째 인자에 저장한다.

추가로, 첫번째 인자는 반드시 레지스터여야만 한다. 또한, 세번째 인자가 올 경우에는 반드시 const 형태의 정수만 사용할 수 있다.


Syntax
imul <reg32>,<reg32>
imul <reg32>,<mem>
imul <reg32>,<reg32>,<con>
imul <reg32>,<mem>,<con>

Examples

imul eax, [var] — var포인터가 가리키는 값 * eax 를 eax에 저장한다.
imul esi, edi, 25 — esi 에 EDI * 25를 저장한다.



idiv — Integer Division

idiv 명령어는 정수 나눗셈을 계산할 때 사용된다.

다른 명령어들과 다르게, EDX 레지스터를 최상위 비트로, EAX 레지스터를 최하위 비트로 설정해, EDX(4bytes) + EAX(4bytes) 형태로 이어붙인 64비트의 정수형 데이터를 인자값 데이터로 나눈다.

이 때, 나눗셈의 몫을 EAX 레지스터에, 나머지를 EDX 에 저장한다.

흔히 EDX 데이터와 EAX를 따로 설정하기 보다는 cdq 명령어를 이용해 4비트의 EAX 데이터를 EDX(MSB) + EAX(LSB) 로 변환해주는 명령어와 병행하여 사용한다.


Syntax
idiv <reg32>
idiv <mem>

Examples

idiv ebx — EDX:EAX 를 EBX로 나눈 후 몫을 EAX에, 나머지를 EDX에 저장한다.

idiv DWORD PTR [var] — EDX:EAX 를 var포인터가 가리키는 데이터로 나눈 후, 몫을 EAX, 나머지를 EDX에 저장한다.


생략 : and / or / xor / not / neg 명령어.

+ xor 명령어의 경우, xor reg, reg 를 통해 레지스터의 값을 0x00 00 00 00 으로 초기화하는데에 종종 쓰인다.



shl, shr — Shift Left, Shift Right

shl, shr 명령어는 첫번째 인자의 값을 왼쪽 또는 오른쪽으로 쉬프트 연산하며, 이때 생기는 빈 공간을 0비트로 채운다. 또한 이때 데이터 길이보다 밀려난 비트는 버려지고, shl의 경우 최상위 비트를 CF로, shr의 경우 최하위 비트를 CF로 복사한다.


Syntax
shl <reg>,<con8>
shl <mem>,<con8>
shl <reg>,<cl>
shl <mem>,<cl>

shr <reg>,<con8>
shr <mem>,<con8>
shr <reg>,<cl>
shr <mem>,<cl>

Examples

shl eax, 1 — 최상위 비트가 2일 경우, EAX 값 * 2의 효과와 동일한 결과가 되는 왼쪽으로 1번 쉬프트 연산을 한다.
shr ebx, cl — EBX에 2의 cl 값 승으로 나눈 값을 저장한 것과 동일한 결과가 되는 오른쪽으로 2번 쉬프트 연산을 한다.


3. 특수 명령어

rep <INSTRUCTION>

ecx 레지스터가 0이 되지 전까지 INSTRUCTION 을 계속 반복해서 실행함. (ecx == 0) 일 경우, 반복을 중지한다.


stosb, stosw, stosd

(byte, word, dword) size 만큼의 eax 레지스터의 값을(EAX, AX, AL) edi(ptr)에 복사한다.

이때, edi 는 명령어가 마지막으로 복사한 주소 + 1이 된다.


4. 흐름 제어 명령어

cmp eax, 1

-> eax==1 일때 ZF 를 설정한다.


! 출처 있음.

  • Unsigned 계열(부호가 없는 값)
    • je: jump equal - 비교 결과가 같을 때 점프
    • jne: jump not equal - 비교 결과가 다를 때 점프
    • jz: jump zero - 결과가 0일 때 점프, je와 같음(cmp 명령에서 결과가 같으면 0을 출력합니다).
    • jnz: jump not zero - 결과가 0이 아닐 때 점프

    • ja: jump above - cmp a, b에서 a가 클 때 점프
    • jae: jump above or equal - 크거나 같을 때 점프
    • jna: jump not above - 크지 않을 때 점프
    • jnae: jump not above or equal - 크지 않거나 같지 않을 때 점프

    • jb: jump below - cmp a, b에서 a가 작을 때 점프
    • jbe: jump below or equal - 작거나 같을 때 점프
    • jnb: jump not below - 작지 않을 때 점프
    • jnbe: jump not below or equal - 작지 않거나 같지 않을 때 점프

    • jc: jump carry - 캐리 플래그가 1일 때 점프
    • jnc: jump not carry - 캐리 플래그가 0일 때 점프

    • jnp/jpo: jump not parity / parity odd - 패리티 플래그가 0일 때 / 홀수일 때 점프
    • jp/jpe: jump parity / parity even - 패리티 플래그가 1일 때 / 짝수일 때 점프

    • jecxz: jump ecx zero - ecx 레지스터가 0일때 점프
  • Signed 계열(부호가 있는 값)
    • jg: jump greater - cmp a, b에서 a가 클 때 점프
    • jge: jump greater or equal - 크거나 같을 때 점프
    • jng: jump not greater - 크지 않을 때 점프
    • jnge: jump not greater or equal - 크지 않거나 같지 않을 때 점프

    • jl: jump less - cmp a, b에서 a가 작을 때 점프
    • jle: jump less or equal - 작거나 같을 때 점프
    • jnl: jump not less - 작지 않을 때 점프
    • jnle: jump not less or equal - 작지 않거나 같지 않을 때 점프

    • jo/jno: jump overflow / not overflow - 오버플로 플래그가 1일 때 / 0일 때 점프
    • js/jns: jump sign / not sign - 사인(부호) 플래그가 1일 때(음수) / 0일 때(양수) 점프


본 문서는 http://www.cs.virginia.edu/~evans/cs216/guides/x86.html 문서의 내용을 번역한 일부를 참고하였습니다.

추가 참고 문서 : http://codeengn.com/archive/Assembly/%EC%96%B4%EC%85%88%EB%B8%94%EB%A6%AC%20%EC%BD%94%EB%93%9C%20%ED%95%B4%EC%84%9D%EC%97%90%20%ED%95%84%EC%9A%94%ED%95%9C%20%EA%B8%B0%EB%B3%B8%20%EC%A7%80%EC%8B%9D%20%5Bforyou2008%5D.pdf

http://pyrasis.com/blog/entry/ReverseEngineeringForNewbieAssemblyOperation

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함