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메모리에 있는건 주소값입니다. 그 주소의 포인터값을 넣은겁니다.
어느 정도 보시면 아시겠지만 (레지스터) 요거는 실제 값을 바꾸는게 아니라 레지스터에 있는 값을 참조하는 것입니다.
쉽게 말할려고 했는데 말이 계속 꼬이네요
일단 여기서 끝내겠습니다.