Function Prologue Epilogue.
A.함수의 호출.
1.함수 호출은 간단히 말해 이런 식.
2.함수가 사용한 파라메터를 스택에 넣고, 함수 시작 지점으로 함수 호출.
3.함수 내에서 사용할 스택 프레임을 설정 = 프롤로그.
4.함수 내용 수행.
5.수행을 마치고 처음 호출한 지점으로 돌아가기 위해 스택을 복원 = 에필로그.
즉 호출한 지점의 다음 라인으로 점프.
이 때 3번 과정을 프롤로그, 5번 과정을 에필로그라고 한다.
둘 다 스택 프레임 설정과 복원에 관계 있다.
B. 함수 호출 규약.
프롤로그와 에필로그는 함수 호출 규약 = 콜링 컨벤션에 따라 조금 다르다. Ex) -CDECL.
1. 스택에 파라미터 삽입 순서 : 왼쪽 => 오른쪽.
2. 스택의 정리를 호출한 함수(Caller)에서 수행. 즉 가변 인자 사용 가능.
3.Name mangling => 함수 이름 앞에 _추가 Ex) _foo
4.C and C++ 기본 함수 호출 규약.
역순으로 파라메터를 Push하고 함수 호출을 한 후, 이어지는 다음 라인에 스택을 정리.
즉 Caller가 직접 스택을 정리.
Caller의 Ebp를 저장하고 Caller의 Ebp를 새로 확보. 새로운 Ebp를 이용해서 foo 함수 내에서
파라미터 및 local변수로의 접근을 시도한다. local 변수에 사용할 스택을 할당하는데 여기서는 4바이트를
변수 하나이므로, 단순히 Ecx를 Push를 함으로써 이를 수행한다. 하지만 Local변수들이 8바이트일 경우
"sub esp, 8"과 같이 스택을 할당한다.
C.함수 프롤로그 & 에필로그.
프롤로그
=베이스 포인터, 즉 Ebp를 스택에 저장하고 현재 스택포인터(Esp)를 베이스 포인터(Ebp)에다가 저장한다.
즉 해당하는 함수 실행 준비 과정.
프롤로그에서 쓰이는 어셈블리어.
==>Push ebp => 이전 스택의 베이스 주소를 저장한다.
==>Mov ebp,esp=> 현재 스택의 첫 주소를 새로운 스택의 베이스로 설정한다.
에필로그
=현재 스택 포인터, 즉 Esp를 베이스포인터(Ebp)로 복귀한 후 베이스 포인터(Ebp)를 복구해주고,
Ret를 통해 다음에 가야 할 address로 점프.
함수 실행을 마무리하는 프롤로그의 반대 과정.
에필로그에서 쓰이는 어셈블리어.
==>Mov esp,ebp=>베이스 주소를 이전의 스택으로 되돌린다.
==>Pop ebp=> 베이스 포인터를 복구한다.
c+.함수 프롤로그 & 에필로그 추가 설명.
에필로그.
1.새로운 함수 호출 시점에 스택에 Ret 생성한다. cf) Ret == 복귀 주소.
2.Sfp(Save Frame Pointer) 백업을 생성한다. Ebp에 Esp값을 수록한다.(빈 스택의 모양).
Sfp에는 Ebp 복구 주소 들어가 있다.
3. 새로운 함수의 시작(함수의 시작과 동시에 새로운 스택을 할당하는 모양).
프롤로그.
1.Esp에 Ebp의 값을 넣어 Esp를 Ebp의 위치로 내린다.
2.Sfp에 수록되어 있던 Ebp의 복귀 주소로 Ebp의 위치를 복귀한다.
3.Pop()함수를 실행한다.Ret 위치에 Esp가 위치한다.
4.Ret(Pop()Eip + Jmp()Eip)가 실행된다.
4-1 Pop()Eip ==> Eip를 Ret에 위치한다.
4-2 Jmp()Eip ==> 함수 호출이 끝난 후 다음 명령을 이어간다.
D.스택 프레임.
함수 호출시 할당되는 메모리 블록이다.(지역 변수의 선언으로 인해 할당되는 메모리 블록)
함수가 호출될 때 스택에는 함수로 전달되는 인자. 즉 실행을 마치고 돌아올 복귀 번지다.
지역 변수 정보들이 저장되고, 이 때 스택에 저장되는 함수의 호출 정보를 스택 프레임이라고 한다.
또한 함수 실행 중에도 필요한 경우 임시적인 정보 저장을 위해 스택을 사용하되 Push랑 Pop이
일치하므로, 함수가 리턴하면 정확하게 호출 전의 상태로 돌아가 항상성을 유지한다.
즉 함수가 호출될 때 인수와 복귀 번지, 지역 변수 영역들을 가진 스택 프레임이 생성되고,
리턴된 후 정확하게 복구하도록 되어 있다.
E.함수의 호출 과정.
1.인자를 스택에 집어 넣는다.
2.함수를 호출한다.
3.프레임 포인터를 설정한다.
4.로컬 변수를 위한 공간을 할당한다.
5.호출한 함수의 실행 상태를 보존한다.
6.함수를 실행한다.
7.호출한 함수의 실행 상태를 복구한다.
8.스택을 정리하고 프레임 포인터를 복구한다.
9.함수로부터 돌아간다.
10.스택에 집어넣은 인자를 정리한다.
여기서 1~5가 프롤로그 7~10 에필로그.
Cf)실행 중인 작업을 처리하는 메모리의 구성.
'#Tip' 카테고리의 다른 글
The heap. (0) | 2018.04.07 |
---|---|
PLT and GOT (0) | 2018.04.06 |
Gdb basic command. (0) | 2018.04.05 |
Windows에서 VMware의 Ubuntu에 SSH로 접속. (0) | 2018.03.31 |
Cpu and assembly language. (0) | 2018.03.27 |