개념
프롤로그(Prologue)와 에필로그(Epilogue)는 무엇일까요. 프롤로그는 보통 문학 작품에서 본편을 시작하기 전에 먼저 읽도록 하는 파트입니다. 에필로그는 작품의 줄거리가 끝난 후 보충된 부분을 말합니다.
함수의 프롤로그(function prologue)와 에필로그(function epilogue)도 마찬가지입니다. 함수의 프롤로그는 함수 시작 부분의 몇 줄의 코드입니다. 스택과 레지스터를 함수 내에서 사용할 수 있습니다. 함수의 에필로그는 함수의 끝에 나타나며, 스택과 레지스터를 함수가 호출되기 전의 상태로 복원합니다.이는 어셈블리 언어 자체의 일부가 아닌 사용하는 규칙을 나타냅니다.
컴파일 결과 확인
아래 C언어 예제를 바탕으로 x86-64 gcc 4.5.3 컴파일러로 컴파일해보겠습니다.
void function(int x) {
}
int main() {
function(0);
return 0;
}
아래 코드는 컴파일 된 결과입니다.
function:push rbpmov rbp, rspmov DWORD PTR [rbp-4], edileaveretmain:push rbpmov rbp, rspmov edi, 0call functionmov eax, 0leaveret
함수 프롤로그 (function prologue)
함수 프롤로그란 함수가 호출되면 그 함수의 영역을 설정해줍니다. 아래는 X86의 프롤로그입니다.
push rbp
mov rbp, rsp
push 명령을 수행하면 rsp는 스택의 상단을 가리킵니다. rbp 값을 스택에 저장하고 rbp 값을 rsp 값에 복사하는 과정을 함수 프롤로그라고 합니다.
함수 에필로그 (function epilogue)
함수 에필로그는 프롤로그의 작업을 되돌리고 제어를 호출함수로 반환합니다. 아래와 같은 코드로 볼 수 있습니다.
leaveret
x86-64 gcc 12.2 버전의 컴파일러로 컴파일러로 컴파일하면 다음과 같습니다.
nop // 쓰기도 하고 안 쓰기도 함
pop rbpret
함수의 에필로그는 다음과 같이 연산됩니다.
push esp, ebp
pop ebp
ret
내부적인 명령은 다음과 같습니다.
leave
mov esp, ebp
pop ebp
ret
pop eip
jmp eip
pop rbp를 마치고 난 후의 스택에는 function 함수가 끝나고 수행해야 할 주소가 저장되어 있으며, ret 명령이 수행되면 함수 호출이 종료됩니다.
지금까지 함수의 프롤로그와 에필로그를 알아봤습니다.
출처
위키
- https://namu.wiki/w/%ED%94%84%EB%A1%A4%EB%A1%9C%EA%B7%B8
- https://namu.wiki/w/%EC%97%90%ED%95%84%EB%A1%9C%EA%B7%B8
- https://en.wikipedia.org/wiki/Function_prologue_and_epilogue
블로그
- https://jiravvit.tistory.com/entry/%ED%95%A8%EC%88%98-%ED%94%84%EB%A1%A4%EB%A1%9C%EA%B7%B8prolog-%ED%95%A8%EC%88%98-%EC%97%90%ED%95%84%EB%A1%9C%EA%B7%B8eplilog
- https://velog.io/@notjustmoney/Computer-%ED%95%A8%EC%88%98-%ED%94%84%EB%A1%A4%EB%A1%9C%EA%B7%B8%EC%97%90%ED%95%84%EB%A1%9C%EA%B7%B8
컴파일러 사이트