쿼리큘럼 개인적 정리

어셈블리어의 기본 정리

MAKGA 2021. 6. 9. 21:34
320x100

기본 형식 : [operation dst, src]

operation - 명령

dst - 목적지 : 연산의 결과가 저장 되는 곳으로 레지스터나 메모리가 온다.

src - 출발지 : 레지스터, 메모리, 상수 모두 가능하다.

dst와 src의 크기는 동일해야함!!

 

범용 레지스터

EAX(ExtendAccumulatorRegister): 사칙연산등 산술 연산에 사용되며, 함수의 반환값을 처리할 때도 사용됨

EBX(ExtendBaseRegister): 간접 번지 지정에 사용되며, 산수 및 변수를 저장함

ECX(ExtendCountRegister): 반복에서 카운트 역할을 수행함

EDX(ExtendDataRegister): EAX를 보조하는 역할을 수행함

 

인덱스 레지스터

ESI(ExtendSourceIndex): 복사나 비교를 할 경우 출발지 주소를 저장하는 레지스터

EDI(ExtendDestinationIndex): 복사나 비교를 할 경우 목적지 주소를 저장하는 레지스터

 

포인터 레지스터

EIP(ExtendInstructionPointer): 다음에 실행할 명령어의 주소를 가지고 있는 레지스터

ESP(ExtendStackPointer): Stack pointer의 가장 최근에 저장된 공간의 주소를 저장하는 레지스터

EBP(ExtendBottomPointer): Stack pointer의 기준점(바닥)을 저장하는 레지스터

 

자주 사용되는 명령어

- push: 값을 스택에 저장

ex) push eax

- pop: 스택 가장 상위에 있는 값을 꺼내어 레지스터에 저장

ex) pop eax

- mov: 메모리나 레지스터의 값을 이동하거나 대입

ex) mov eax, ebx -> eax = ebx

ex) mov dword[ebx], 0x12 -> ebx가 가리키는 포인터 위치에 0x12을 대입 (대괄호는 포인터라는 의미)

- inc: 값을 1 증가 시킴

ex) inc eax

- dec: 값을 1 감소 시킴

ex) dec eax

- add : 레지스터나 메모리의 값을 덧셈

ex) add ecx, ebx -> ecx += ebx

- sub : 레지스터나 메모리의 값을 뺄셈

ex) sub eax, 20 -> eax -= 20

- call: 프로시저 호출

- lea: 주소 값을 대입

ex) lea edi, dword ptr [ebp+8]

- ret: 호출했던 바로 다음 지점으로 이동

- cmp: 두 레지스터의 값을 비교

- jmp: 특정한 곳으로 분기

- jle: 비교 결과 값이 '0'이거나(ZF=1), 작을경우 해당 주소로 점프

- int: OS의 인터럽트 system call

- nop: 아무 동작 안함

 

 

예제 코드

int func(int a, int b)
{
    return a - b;
}

int main(void)
{
    int a = 10;
    int b = 20;
    int c = 30;
    int d = (c - a);
    int e = ++a;
    int f = b--;
    int g = a > b ? a : b;
    int h = func(b, a);

    system("pause");
    return 0;
}

어셈블리 코드

00CE11E5  jmp         00CE29A0

int func(int a, int b) 
{ 
00CE29A0  push        ebp   // ebp 값을 스택에 push
00CE29A1  mov         ebp,esp   // ebp = esp
00CE29A3  sub         esp,0C0h   // esp -= 0C0h
00CE29A9  push        ebx   // ebx 값을 스택에 push
00CE29AA  push        esi   // esi 값을 스택에 push
00CE29AB  push        edi   // edi 값을 스택에 push
00CE29AC  lea         edi,[ebp+FFFFFF40h]  // edi에 ebp+FFFFFF40h의 값 대입
00CE29B2  mov         ecx,30h   // ecx = 30h
00CE29B7  mov         eax,0CCCCCCCCh   // eax = 0CCCCCCCCh
00CE29BC  rep stos    dword ptr es:[edi]   // eax 값을 edi가 가리키는곳에 ecx 반복 복사
00CE29BE  mov         ecx,0CEE091h   // ecx = 0CEE091h
00CE29C3  call        00CE1415
return a - b; 
00CE29C8  mov         eax,dword ptr [ebp+8]   // eax = a;
00CE29CB  sub         eax,dword ptr [ebp+0Ch] // a -= b;
}

int main(void)
{
00CE2A00  push        ebp  
00CE2A01  mov         ebp,esp  
00CE2A03  sub         esp,124h  
00CE2A09  push        ebx  
00CE2A0A  push        esi  
00CE2A0B  push        edi  
00CE2A0C  lea         edi,[ebp+FFFFFEDCh]  
00CE2A12  mov         ecx,49h 
00CE2A17  mov         eax,0CCCCCCCCh 
00CE2A1C  rep stos    dword ptr es:[edi]  
00CE2A1E  mov         ecx,264092h 
00CE2A23  call        00CE1415  
    int a = 10;
00CE2A28  mov         dword ptr [ebp-8],0Ah   // 0A = 10
    int b = 20;
00CE2A2F  mov         dword ptr [ebp-14h],14h   // 14 = 20
    int c = 30;
00CE2A36  mov         dword ptr [ebp-20h],1Eh   // 20 = 30
    int d = c + a;
00CE2A3D  mov         eax,dword ptr [ebp-20h]   // eax레지스터에 c값 대입
00CE2A40  add         eax,dword ptr [ebp-8]   // eax레지스터에 a값 덧셈
00CE2A43  mov         dword ptr [ebp-2Ch],eax   // d에 eax레지스터값 대입
    int e = ++a;
00CE2A46  mov         eax,dword ptr [ebp-8]   // eax레지스터에 a값 대입
00CE2A49  add         eax,1   // eax레지스터에 1 덧셈
00CE2A4C  mov         dword ptr [ebp-8],eax   // a에 eax레지스터값 대입
00CE2A4F  mov         ecx,dword ptr [ebp-8]   // ecx레지스터에 a값 대입
00CE2A52  mov         dword ptr [ebp-38h],ecx   // e에 ecx레지스터값 대입
    int f = b--;
00CE2A55  mov         eax,dword ptr [ebp-14h]   // eax레지스터에 b값 대입
00CE2A58  mov         dword ptr [ebp-44h],eax   // f에 eax레지스터값 대입
00CE2A5B  mov         ecx,dword ptr [ebp-14h]   // ecx레지스터에 b값 대입
00CE2A5E  sub         ecx,1   // ecx레지스터에 1 뺄셈
00CE2A61  mov         dword ptr [ebp-14h],ecx   // ecx값 b에 대입
    int g = a > b ? a : b;
00CE2A64  mov         eax,dword ptr [ebp-8]   // eax레지스터에 a값 대입
00CE2A67  cmp         eax,dword ptr [ebp-14h]   // eax레지스터와 b값 비교
00CE2A6A  jle         00CE2A77   // cmp 결과가 0일경우(ZF=1) 해당 주소 점프
---------------------------------a > b가 참인 경우---------------------------------------
00CE2A6C  mov         ecx,dword ptr [ebp-8]   // ecx레지스터에 a값 대입
00CE2A6F  mov         dword ptr [ebp+FFFFFEDCh],ecx  // ebp+FFFFFEDC에 ecx레지스트값 대입
00CE2A75  jmp         00CE2A80   // 00256C70 점프
---------------------------------a > b가 거짓인 경우-------------------------------------
00CE2A77  mov         edx,dword ptr [ebp-14h]   // edx레지스터에 b값 대입
00CE2A7A  mov         dword ptr [ebp+FFFFFEDCh],edx // ebp+FFFFFEDC에 ecx레지스트값 대입
-----------------------------------------------------------------------------------------
00CE2A80  mov         eax,dword ptr [ebp+FFFFFEDCh] // eax레지스터에 [ebp+FFFFFEDCh] 값 대입
00CE2A86  mov         dword ptr [ebp-50h],eax   // g에 eax레지스터값 대입
    int h = func(b, a);
00CE2A89  mov         eax,dword ptr [ebp-8]   // eax레지스터에 a값 대입
00CE2A8C  push        eax   // 스택에 eax레지스터값 저장
00CE2A8D  mov         ecx,dword ptr [ebp-14h]   // ecx레지스터에 b값 대입
00CE2A90  push        ecx   // 스택에 ecx레지스터값 저장
00CE2A91  call        00CE11E5   // 00CE11E5 호출(이 주소에서 func로 jmp)
00CE2A96  add         esp,8   //
00CE2A99  mov         dword ptr [ebp-5Ch],eax   //

    system("pause");
00CE2A9C  mov         esi,esp  
00CE2A9E  push        25EE10h  
00CE2AA3  call        dword ptr ds:[00CED1B4h]  
00CE2AA9  add         esp,4  
00CE2AAC cmp         esi,esp 
00CE2AAE  call        002513D9  
    return 0;
00CE2AB3  xor         eax,eax  
}

 

320x100