튜기's blogggg

64bit stack frame

by St1tch

32비트 cpu일떄는 함수 호출규약이 여러개 있었지만 

64비트로올라오면서 한개로 통합이 되었다 

기존 fastcall(함수의 인자가 레지스터로 전달되는방식)호출규약을 이용한다.


64비트 레지스터로는 기존의 레지스터에서 확장된 레지스터를 사용하고(rax, rbx ,rsp등등..)

8개의 레지스터가 추가되었다 (r8~r15)


스택프레임

다음과 같은 C코드를 짠다고 했을 떄

1
2
3
4
5
6
7
8
9
long myfunc(long a, long b, long c, long d,
            long e, long f, long g, long h)
{
    long xx = a * b * c * d * e * f * g * h;
    long yy = a * b * c * d * e * f * g * h;
    long zz = utilfunc(xx, yy, xx % yy);
    return zz + 20;
}
            


다음과 같은 모양에 스택프레임이 형성이 된다


함수를 호출할 때 최초 6개의 정수나 포인터 인자의 경우에는 RDI, RSI, RDX, RCX, R8, R9 에 순서대로

넘겨지게 되고, 더 많은 숫자의 인자가 들어오게 된다면 스태을 통해 전달되게 된다.

실수 인자는 xmm0~xmm7까지 총 8개를 순서대로 사용하고 8개가 넘어갈시 스택을 통해 전달된다.

리턴값은 rax, rdx를 사용한다.


근데 x86 스택프레임에서는 볼 수 없었던 red zone이 생기게 된다.

AMD ABI에 정의된 바로는



원문

The 128-byte area beyond the location pointed to by %rsp is considered to be reserved and shall not be modified by signal or interrupt handlers. Therefore, functions may use this area for temporary data that is not needed across function calls. In particular, leaf functions may use this area for their entire stack frame, rather than adjusting the stack pointer in the prologue and epilogue. This area is known as the red zone.


발번역

%rsp가 가르키는 128byte의 공간(red zone)은 예비로 놔둔 공간이고  signal이나 인터럽트 핸들러를통해 변경되지 않습니다.

그러므로 함수 호출간에 보존될 필요가 없는 휘발성 데이터들이 이공간을 사용하게 됩니다.

특별히 말단함수(leaf function 다른 함수들을 호출하지 않는 함수들)들은 스택 포인터를 프롤로그와 에필로그로 조정하기 보다는 이 공간을 스택프레임 전체로 쓰기도 합니다.


간단하게 말하자면 red zone은 최적화라 볼 수 있다. 

rsp아래 128byte가 시그널이나 인터럽트 핸들러를 통해 변경되지 않는다는 것을 안다면 

http://eli.thegreenplace.net/2011/09/06/stack-frame-layout-on-x86-64/


출처 : http://jen6.tistory.com/77

블로그의 정보

튜기's blogg(st1tch)

St1tch

활동하기