스택 작동 방식을 이해하는 데 문제가 있습니다. 먼저 내 작은 코드 :RSP가 스택 맨 위에 있지 않습니까?
void func1 (int z) {
int i = 1;
}
int main () {
func1 (89);
return 0;
}
내가 사용하고 : 우분투 16.04 64 비트, GCC 버전 5.4.0, GDB 버전 7.11.1.
컴파일러가 스택에서 함수 인수를 푸시하는 방법을 확인하기 위해 GDB를 사용하여 디버깅했습니다. 나는 어디 RSP 포인트의 시점에서 스택을 검토 할 때는
,이 얻을 :
(gdb) p &i
$4 = (int *) 0x7fffffffdf14
:
나는 새로운 창조 변수의 주소를 출력
(gdb) x/10xw $rsp
0x7fffffffdf20: 0xffffdf30 0x00007fff 0x00400525 0x00000000
0x7fffffffdf30: 0x00400530 0x00000000 0xf7a2e830 0x00007fff
0x7fffffffdf40: 0x00000000 0x00000000
,이 얻을
함수에 전달 된 변수의 주소를 출력하면 다음과 같이 표시됩니다.
(gdb) p &z
$5 = (int *) 0x7fffffffdf0c
스택의 수가 적어집니다.
그래서 나는이 명령을 호출 할 때 RSP
이 항상 스택 맨을 가리킨다 고 생각했습니다. x/10xw $rsp
함수에서 모든 변수를 볼 수는 있지만 거기에서 볼 수는 없습니다.
이 명령의 첫 번째 주소는 변수 z
의 주소보다 길다. 그 때문에 나는 RSP
점이 스택 맨 위에 있지 않다고 추측했습니다.
내게 궁금한 것은 i
의 주소가 z
의 주소보다 높다는 것입니다. i
은 나중에 z
보다 스택에 푸시되었으므로 i
은 내 의견으로는 z보다 낮은 주소 여야합니다.
누군가가 왜 그런지 설명 할 수 있기를 바랍니다.
편집 : 답변을 찾았습니다! 컴파일러에서 최적화되었습니다. func1()
에서 RSP
레지스터는 필요하지 않기 때문에 스택의 "위쪽"을 가리키고 있지 않았습니다. func1()
에 다른 함수가 호출 된 경우에만 필요했습니다. 그래서 컴파일러는 이것을보고 RSP
레지스터를 감소시키지 않았습니다. func1()
에서 어떤 함수 호출에
여기 ismy 어셈블러 코드 :
0x00000000004004d6 <+0>: push rbp
0x00000000004004d7 <+1>: mov rbp,rsp
0x00000000004004de <+8>: mov DWORD PTR [rbp-0x14],edi
0x00000000004004e1 <+11>: mov DWORD PTR [rbp-0x4],0x1
0x00000000004004e8 <+18>: mov eax,0x0
0x00000000004004f3 <+29>: leave
0x00000000004004f4 <+30>: ret
그래서 당신은
RSP
을 감소시키는에 대한
SUB
전화를 볼 수 있습니다.
이제 함수 호출에
func1()
의 코드는 :
0x00000000004004d6 <+0>: push rbp
0x00000000004004d7 <+1>: mov rbp,rsp
0x00000000004004da <+4>: sub rsp,0x20
0x00000000004004de <+8>: mov DWORD PTR [rbp-0x14],edi
0x00000000004004e1 <+11>: mov DWORD PTR [rbp-0x4],0x1
0x00000000004004e8 <+18>: mov eax,0x0
0x00000000004004ed <+23>: call 0x4004f5 <func2>
0x00000000004004f2 <+28>: nop
0x00000000004004f3 <+29>: leave
0x00000000004004f4 <+30>: ret
그래서 당신은
RSP
을 감소시키는에 대한
SUB
전화를 볼 수 있습니다. 따라서
RSP
은 "위쪽"을 가리킬 수 있습니다.
Linux 용 64 비트 호출 규칙은 처음 6 개의 인수에 대해 레지스터를 사용합니다. 스택이 필요 없습니다. –
레지스터에 값이 저장됩니까? 당신은 내가 그것에 관해 읽을 수있는 링크 또는 무언가를 안다? –
이것은 좋은 스레드입니다. http://stackoverflow.com/questions/2535989/what-are-the-calling-conventions-for-unix-linux-system-calls-on-x86-64 –