C언어 기초/02주차

x32 x64 어셈블리 실행시 메모리 사용 .. 01_셋팅하기

윤레카 2017. 2. 3. 17:42

스압주의...

x32 (32비트 컴퓨터) -- 레지스터가 4 Byte 씩 실행되는 구조이다

x64 (64비트 컴퓨터) -- 레지스터가 8 Byte 씩 실행되는 구조이다  -- 요즘 거의 사용하는 형태



기계어(어셈블리) 디버깅 과정을 통해

해당 명령어 (mov, sub 등..) 수행하면서

메모리 할당을 어떻게 받고, 레지스터의 각 역할사용 등을 확인해 볼 수 있다.



 #include <stdio.h>                               


   int my_func(int n){

      return n* 2;

   }


   int main(void){

      int n = 3, res;

      res = my_func(n);

      printf("res = %d\n", res);


      return 0;

   }


  0x0000000000400534 <+0>  : push    %rbp

  0x0000000000400535 <+1>  : mov    %rsp, %rbp

  0x0000000000400538 <+4>  : sub     $0x10, %rsp

  0x000000000040053c <+8>  : movl    $0x3, -0x8(%rbp)

  0x0000000000400543 <+15> : mov    -0x8(%rbp), %eax

  0x0000000000400546 <+18> : mov    %eax, %edi

  0x0000000000400548 <+20> : callq   0x400526 <my_func>

  0x000000000040054d <+25> : mov    %eax, -0x4(%rbp)

  0x0000000000400550 <+31> : mov    -0x4(%rbp), %eax

  0x0000000000400553 <+31> : mov    %eax, %esi

  0x0000000000400555 <+33> : mov    $0x4005f4, %edi

  0x000000000040055a <+38> : mov    $0x0, %eax

  0x000000000040055f <+43> : callq    0x400400 <printf@plt>

  0x0000000000400564 <+48> : mov    $0x0, %eax

  0x0000000000400569 <+53> : leaveq

  0x000000000040056a <+54> : retq





아래 사항을 확인해보기 위한.. 리눅스 기본 Setting



1.  vi [파일이름.c]  >>>  insert 키를 누르고  >>>  왼쪽 위 의 코드 작성하기


2.  작성을 완료하였다면, gdb 를 사용할 수 있도록 컴파일하기

    gcc -g -o [파일의별칭아무거나] [파일이름.c]


3.  컴파일이 성공하였다면, gdb 소환

    gdb [파일의별칭설정한것]


4.  gdb 소환에 성공하였다면, breakpoint 을 main 으로 잡기

    b main


5.  실행하기

    r


6.  디버깅 전체보기

    disas


7.  그러면 현재 화살표가 가리키고 있는 곳이 breakpoint 로 잡혀있는 것을 확인할 수 있다.

    디버깅을 첫줄부터 시도해보기 위해... 

    맨 윗줄의 0x0000000000400534 긁어서 >>> 오른클릭 >>> 복사


8.  breakpoint 추가하기 / 주의할 점은.. *을 붙인다는 것

    b *0x0000000000400534


9.  breakpoint 가 잘 잡혔는지 확인해보기

    info b

    그럼 잡혀있는 것이 2개 뜨지?


10. 잘 잡힌것을 확인했다면, 다시 실행하기(재시작)

     r


11. 다시 실행 후 현재 화살표가 가리키고 있는 곳이 첫 줄임을 확인하자

     disas


12. 여기까지 잘 따라왔다면.. 디버깅을 한 줄씩 해보면서, 

     실제 각 레지스터의 역할과 데이터가 메모리상에서 어떻게 처리되는지를 확인해 볼 수 있다.

     어셈블리어 단위로 1 줄 진행하기 : si

     C언어 단위로 1 줄 진행하기 : s




=================== 셋 팅 완 료 ===================


[참고] '%'는 레지스터 사용시 활용, '$'는 상수값 사용시 활용

[참고] p/x $레지스터이름 :