본문 바로가기

dis & asm

main 분석 (3)

gcc 3.22

지금 pc방이라서 집에 쓰는 gcc가 다르네요
보니까 약간의 어셈코드가 다른데 큰 차이는 없습니다.

포인터가 어셈에서 어떻게 쓰이는지 보겠습니다.
먼저 disasm 입니다.


 80482f4:       55                      push   %ebp
 80482f5:       89 e5                   mov    %esp,%ebp
 80482f7:       83 ec 18                sub    $0x18,%esp
 80482fa:       83 e4 f0                and    $0xfffffff0,%esp
 80482fd:       b8 00 00 00 00          mov    $0x0,%eax
 8048302:       29 c4                   sub    %eax,%esp
        int a;
        int b;
        int *p;

        a=10;
 8048304:       c7 45 fc 0a 00 00 00    movl   $0xa,0xfffffffc(%ebp)
        b=20;
 804830b:       c7 45 f8 14 00 00 00    movl   $0x14,0xfffffff8(%ebp)

        p=&a;
 8048312:       8d 45 fc                lea    0xfffffffc(%ebp),%eax
 8048315:       89 45 f4                mov    %eax,0xfffffff4(%ebp)
        *p=15;
 8048318:       8b 45 f4                mov    0xfffffff4(%ebp),%eax
 804831b:       c7 00 0f 00 00 00       movl   $0xf,(%eax)

-------------------------------------------------------------------------------

        a=10;
 8048304:       c7 45 fc 0a 00 00 00    movl   $0xa,0xfffffffc(%ebp)

전에 본것처럼 여기서는 0xfffffffc(%ebp)  이건 음수로 표현한거입니다.

즉  2의 보수입니다.  이걸 양수로 바꾸면 4가 됩니다.

그말은   movl $0xa , -0x4(%ebp)  이게 됩니다.

        b=20;
 804830b:       c7 45 f8 14 00 00 00    movl   $0x14,0xfffffff8(%ebp)   <-- 이건 movl $0x14 , -0x8(%ebp)

여기까지는 쉽습니다.

        p=&a;
 8048312:       8d 45 fc                lea    0xfffffffc(%ebp),%eax
 8048315:       89 45 f4                mov    %eax,0xfffffff4(%ebp)


lea    0xfffffffc(%ebp),%eax   <----  이것또한  포인터 변형

0x-4(%ebp)  ,  % eax   메모리 이동입니다.   movl과 비슷합니다.

mov    %eax,0xfffffff4(%ebp)   <---- eax레지에 있는걸  -0xc(%ebp)여기로 옮기는 겁니다.

lea 와 mov 차이점은  잘 몰라서 movl 로 바꿔서  disasm 블 해보았습니다.

lea --> mov  로 바꿔서 해봐았더니 eax에 0xa가 들어갑니다.
언뜻보면 맞는거 같지만  

ebp-0x4 번지에는 0xa가 들어가 있습니다.
문제는 ebp-0x4 번지의 주소값을 %eax에 복사를 해야합니다.

movl 은 ebp-0x4번지의 값을 %eax에 넣었습니다.
그럼 %eax는 0xa값을 가집니다.

mov    %eax,0xfffffff4(%ebp)  그럼 ebp-0xc번지에는 0xa가 들어갑니다.

문제는 ebp-0xc번지는 포인터 변수의 값입니다
포인터 변수는 현재 p=&a; 의 값 즉 a의 주소값을 가지는데
movl로 바꿔버리면 p=*a의 값을 가집니다  현재 p에 값은 십진수로 10의 값을 가집니다.

왜 lea를 써야 하는지 아시겠죠?  저도 지금 해보니 약간의 이해가 되네요


뭐 그 이후도 똑같습니다.  b변수값을 p가 참조하고 

        *p=15;
 8048318:       8b 45 f4                mov    0xfffffff4(%ebp),%eax
 804831b:       c7 00 0f 00 00 00       movl   $0xf,(%eax)

p변수로 15를 넣는겁니다..

이걸 disasm하면

0xfffffff4(%ebp),%eax  <---- ebp-0xc번지에 있는 값을 eax에 넣습니다.   그말은 a변수의 주소값을 넣는거죠

movl   $0xf,(%eax)  f=15 값을 eax에 값에 있는 참조하는 값에 넣습니다. 

즉 eax메모리에 있는건 주소값입니다. 그 주소의 포인터값을 넣은겁니다.

어느 정도 보시면 아시겠지만 (레지스터) 요거는 실제 값을 바꾸는게 아니라 레지스터에 있는 값을 참조하는 것입니다.

쉽게 말할려고 했는데 말이 계속 꼬이네요

일단 여기서 끝내겠습니다.