============================== Assembly =================================


7 =>    0x0000000000400548 <+20> : callq   0x400526 <my_func>      일 때,


                                                                       call : 함수 호출시 사용하는 니모닉(mnemonic)

                                                                       call = push + jmp

                                                                               push 는 복귀 주소를 스택에 저장함

                                                                               jmp 는 call 뒤에 오는 주소값으로 이동시킴


<call 전>

(gdb) p $rsp

$1 = 0x7fffffffdd20                              


<call 이후>

(gdb) p $rsp

$2 = 0x7fffffffdd18                       // 주소가 바뀌어 있다 !!  8Byte 할당 받음..

(gdb) x $rsp

$3 = ffdd18 : 0x0040054d             // 들어있는 값을 확인 - 함수가 끝난 후, 복귀할주소 저장되어 있음


============================== Computer =================================


7. callq 니모닉 처리

0x7fffffffdd18

 

0x7fffffffdd30


 숫자 '3'

 

  숫자 '3'

   

 rsp 레지스터

 

 rbp 레지스터

 eax 레지스터

 

 edi 레지스터

   



 

 Stack

 메모리 주소


rbp> 

0x00400570

 


 

0x7fffffffdd38
 

0x7fffffffdd30 

 

숫자 3

 


0x7fffffffdd28 

 



 



<이전 rsp 위치


0x7fffffffdd20 

 

 

0x0040054d

 

<rsp
 

0x7fffffffdd18
 

 0x00400570

 

   바뀔 rsp

<(-0x8(%rsp))



0x7fffffffdd10 


함수가 끝난 후 복귀해야 할 주소 : 0x0040054d 는 현재, rsp가 가리키는 스택에 들어있음

함수가 끝나면 Jump니모닉을 실행할 터이고.. 그럼 저 주소로 Jump 함..

그런데.. 가만보니.. my_func 함수가 실행되는 동시에.. 스택프레임이 다시 생성되고 있음 !! 


(gdb) x $rsp -0x8

$4 = ffdd10 : 0x00400570  





============================ 함수 안으로 들어가서.. ===========================


  int my_func(int n){

      return n* 2;

   }

 


  0x0000000000400526 <+0>  : push   %rbp

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

  0x000000000040052a <+4>  : mov    %edi, -0x4(%rbp)

  0x000000000040052d <+7>  : mov    -0x4(%rbp), %eax

  0x0000000000400530 <+10> : add    %eax, %eax

  0x0000000000400532 <+12> : pop    %rbp

  0x0000000000400533 <+13> : retq






============================== Assembly =================================


8 =>     0x0000000000400526 <+0>  : push    %rbp    는, 위에서 callq 호출시 실행되었고


(gdb) p $rsp

$4 = 0x7fffffffdd10                   // 스택 프레임 생성 : 공간할당 -> rbp 주소 따라가면 있는 데이터 밀어넣기 





============================== Assembly =================================


9 =>     0x0000000000400527 <+1>  : mov    %rsp, %rbp    일 때,

                                                 rsp의 값을 rbp에 넣어라

(gdb) p $rsp

$5 = 0x7fffffffdd10                      // 8Byte 공간할당 됨, 돌아갈 주소의 포인터를 갖고 있음 

(gdb) p $rbp

$6 = 0x7fffffffdd10                      // rsp == rbp ,  동일한 상황이 됨

(gdb) x $rsp

0x7ffdd10 : 0xffdd30                    // 이전 rbp 위치를 가리키고 있다 -ㅁ- ;;


============================== Computer =================================


9. 스택프레임 생성 - rbp 설정

0x7fffffffdd10

 

0x7fffffffdd10


 숫자 '3'

 

  숫자 '3'

   

 rsp 레지스터

 

 rbp 레지스터

 eax 레지스터

 

 edi 레지스터

   



 

 Stack

 메모리 주소



이전 rbp위치>

0x00400570

 

 

0x7fffffffdd38

0x7fffffffdd30 

 

숫자 3

 


0x7fffffffdd28 

 



 





0x7fffffffdd20 

 

 

0x0040054d

 


 

0x7fffffffdd18

 
 
rbp>

 0x00400570

 
 
<rsp


 
0x7fffffffdd10 
    






============================== Assembly =================================


10 =>     0x000000000040052a <+4>  : mov    %edi, -0x4(%rbp)    일 때,

                                                 edi 의 값을 rbp-0x4 위치에 넣어라

(gdb) p $rsp

$7 = 0x7fffffffdd10                      

(gdb) p $rbp

$8 = 0x7fffffffdd10                     

(gdb) x $rbp -0x4

0x7ffdd0c : 0x00000003                        // edi 레지스터의 값을 스택에 넣었음을 확인


============================== Computer =================================


10. (의미없는 수행) edi 레지스터의 데이터를 스택에 넣어라

0x7fffffffdd10

 

0x7fffffffdd10


 숫자 '3'

 

 숫자 '3'

   

 rsp 레지스터

 

 rbp 레지스터

 eax 레지스터

 

 edi 레지스터

   



 

 Stack

 메모리 주소




0x00400570

 

 

0x7fffffffdd38

0x7fffffffdd30 

 

숫자 3

 


0x7fffffffdd28 

 



 





0x7fffffffdd20 

 

 

0x0040054d

 


 

0x7fffffffdd18

 
 
rbp>

 0x00400570

 
 
<rsp



0x7fffffffdd10 


 
-0x4(%rbp)>

 숫자 '3'

 

 


0x7fffffffdd0c






============================== Assembly =================================


11 =>     0x000000000040052d <+7>  : mov    -0x4(%rbp), %eax   일 때,

                                                   rbp-0x4 의 값을 eax 레지스터에 넣어라

(gdb) p $eax

$9 = 3                                  // eax 레지스터에 이미 3 들어 있는데.. 또 3을 넣다니.. 의미없는 수행과정      


============================== Computer =================================


11. (의미없는 수행) rbp-0x4의 값을 eax 레지스터에 넣어라

0x7fffffffdd10

 

0x7fffffffdd10


 숫자 '3'

 

 숫자 '3'

   

 rsp 레지스터

 

 rbp 레지스터

 eax 레지스터

 

 edi 레지스터

   



 

 Stack

 메모리 주소




0x00400570

 

 

0x7fffffffdd38

0x7fffffffdd30 

 

숫자 3

 


0x7fffffffdd28 

 



 





0x7fffffffdd20 

 

 

0x0040054d

 


 

0x7fffffffdd18

 
 
rbp>

 0x00400570

 
 
<rsp



0x7fffffffdd10 


 

-0x4(%rbp)>

 숫자 '3'

 


 

0x7fffffffdd0c







============================== Assembly =================================


12 =>      0x0000000000400530 <+10> : add    %eax, %eax   일 때,

                                                    eax += eax 

(gdb) p $eax

$10 = 6                                  // 3 += 3 이므로, eax 레지스터의 값이 6으로 갱신됨


============================== Computer =================================


12. 3 더하기 3은~?

0x7fffffffdd10

 

0x7fffffffdd10


 숫자 '6'

 

 숫자 '3'

   

 rsp 레지스터

 

 rbp 레지스터

 eax 레지스터

 

 edi 레지스터

   







============================== Assembly =================================


13 =>       0x0000000000400532 <+12> : pop    %rbp   일 때,

                                                    1. rbp 는 : 이전 rbp위치 에 담겨있는 정보 - 돌아갈 주소로 감 

 2. rsp 는 : +0x8 됨.. 할당 전의 주소로 복귀

(gdb) p $rbp

$11 = 0x7fffffffdd30  


(gdb) p $rsp

$12 = 0x7fffffffdd18      


(gdb) x $rbp

0x7fffffffdd30 = 0x00400570


(gdb) x $rsp

0x7fffffffdd18 = 0x0040054d    


(gdb) p $rip

$12 = 0x400533  <my_func+13>


============================== Computer =================================


13. pop 니모닉 실행

0x7fffffffdd18

 

0x7fffffffdd30


 숫자 '6'

 

 숫자 '3'

   

 rsp 레지스터

 

 rbp 레지스터

 eax 레지스터

 

 edi 레지스터

   



 

 Stack

 메모리 주소



rbp>

0x00400570

 

 

0x7fffffffdd38

0x7fffffffdd30 

 

숫자 3

 


0x7fffffffdd28 

 



 





0x7fffffffdd20 

 

 

0x0040054d

 

<rsp

 

0x7fffffffdd18

 
 
이전 rbp위치>

 0x00400570

 
 
<이전 rsp위치



0x7fffffffdd10 


 

-0x4(%rbp)>

 숫자 '3'

 


 

0x7fffffffdd0c







============================== Assembly =================================


14 =>    0x0000000000400533 <+13> : retq    시전 과 동시에, <my_func>함수를 빠져나옴

                                                                          0x000000000040054d <+25> 할 차례라고 가리키고 있음



============================== Computer =================================


14. 

0x7fffffffdd18

 

0x7fffffffdd30


 숫자 '6'

 

  숫자 '3'

   

 rsp 레지스터

 

 rbp 레지스터

 eax 레지스터

 

 edi 레지스터

   



 

 Stack

 메모리 주소


rbp> 

0x00400570

 


 

0x7fffffffdd38
 

0x7fffffffdd30 

 

숫자 3

 


0x7fffffffdd28 

 



 





0x7fffffffdd20 

 

 

0x0040054d

 

<rsp
 

0x7fffffffdd18
 


 

   








이 정도만 보아도.. 그동안 배운 자료구조, 운영체제, C언어, 어셈블리, 컴퓨터구조.. 등 많은 과목이 스쳐지나가면서

퍼즐이 맞춰지듯 이해가 된다.. 신기하다..

+ Recent posts