리눅스 x86 호출규약
2019년 10월 30일
32비트 리눅스의 호출 규약Calling Convention에 대해서 알아보자.
- 스택 메모리에서 서브루틴은 호출자의 아래쪽으로 생성된다.
- eax 레지스터로 리턴값을 전달한다.
- ebp 레지스터 위에 함수의 return address가 있고, 그 위에 인자argument가 쌓여있다.
예
int add(int a, int b){
return a+b;
}
int main(){
int a,b,c;
a = 3;
b = 7;
c = add(a, b);
return 0;
}
를 다음과 같이 32비트 컴파일을 하고 gdb로 확인해보자.
gcc -m32 add.c -o add
gdb add
add를 실행하는 과정을 쪼개서 과정을 표현해보았다(가로가 긴 화면에서 보는 것을 권장한다). 메모리를 한 열이 4바이트인 표로 그렸다. eip는 레지스터 표가 아닌 왼쪽에 어셈블리 코드에 화살표로 나타냈고, esp와 ebp는 메모리 표에 위치를 나타낼 수 있을 때 메모리에 표시했다.
관련된 Assembly Instructions
push Reg
: esp를 4 감소시키고mov Reg, (%esp)
한다.pop Reg
:mov (%esp), Reg
후 esp를 4 증가시킨다.call Dest
:push 다음 인스트럭션
후mov Dest, %eip
한다.ret
:pop %eip
leave
:mov %esp, %ebp