기능 프롤로그 및 에필로그

Function prologue and epilogue

어셈블리 언어 프로그래밍에서 함수 프롤로그는 함수의 시작 부분에 있는 몇 줄의 코드이며, 스택을 준비하고 함수 내에서 사용할 수 있도록 등록합니다.마찬가지로 함수 에필로그는 함수의 끝에 나타나며 스택과 레지스터를 함수가 호출되기 전의 상태로 복원합니다.

프롤로그와 에필로그는 어셈블리 언어 자체의 일부가 아닙니다.어셈블리 언어 프로그래머와 많은 상위 언어컴파일러가 사용하는 규칙을 나타냅니다.각 기능에서 동일한 형태를 가지며 상당히 견고합니다.

함수 프롤로그 및 에필로그에는 버퍼 오버플로우 보호를 위한 코드도 포함되어 있는 경우가 있습니다.

프롤로그

함수 프롤로그는 일반적으로 아키텍처에 기본 포인터(프레임 포인터라고도 함)와 스택포인터가 있는 경우 다음 액션을 수행합니다.

  • 나중에 복원할 수 있도록 현재 기본 포인터를 스택에 푸시합니다.
  • 베이스 포인터의 값은 베이스 포인터가 스택의 상부를 가리키도록 스택포인터 주소(스택의 상부를 가리킴)로 설정됩니다.
  • 스택이 다운되는지 업인지에 따라 값을 줄이거나 늘려 스택포인터를 더 이동합니다x86에서는 함수의 로컬 변수를 위한 공간을 확보하기 위해 스택 포인터가 감소합니다.

몇 가지 가능한 프롤로그를 쓸 수 있기 때문에 스택 설정이 약간 다릅니다.프로그래머나 컴파일러가 함수 내부에서 스택을 올바르게 사용하는 한 이러한 차이는 허용됩니다.

를 들어, GCC에 의해 작성된 전형적인 x86 어셈블리 언어 함수 프롤로그를 다음에 나타냅니다.

 밀다 에브피  움직이다 에브피, 특히  후보선수 특히, N 

N immediate 값은 로컬 사용을 위해 스택에 예약된 바이트 수입니다.

같은 결과를 얻을 수 있습니다.enter순서:

 를 입력하십시오. N, 0 

보다 복잡한 프롤로그는 의 두 번째 피연산자에 대해 다른 값(0 제외)을 사용하여 얻을 수 있습니다.enter설명.이러한 프롤로그는 파스칼과 같은 언어에서 요구되는 중첩된 함수를 허용하기 위해 몇 가지 기본/프레임 포인터를 푸시합니다.다만, 이러한 언어의 최신 버전에서는, 경우에 [citation needed]따라서는 네스트의 깊이를 제한하고 있기 때문에, 이러한 순서를 사용하지 않습니다.

에필로그

function epilogue는 function 프롤로그의 액션을 되돌리고 calling 함수로 제어를 되돌립니다.일반적으로 다음 작업을 수행합니다(이 절차는 아키텍처마다 다를 수 있습니다).

  • 스택 포인터를 현재 베이스 포인터에 드롭하면 로컬 변수의 프롤로그에 예약된 공간이 해방됩니다.
  • 기본 포인터를 스택에서 꺼내고 프롤로그 이전의 값으로 복원합니다.
  • 이전 프레임의 프로그램 카운터를 스택에서 팝업하여 호출 함수로 돌아갑니다.

주어진 에필로그는 위의 프롤로그(전체 또는 를 사용하는 프롤로그) 중 하나의 효과를 반전시킵니다.enter)) 특정 호출 규칙에서는 스택에서 인수를 지우는 것은 착신측의 책임입니다.따라서 에필로그에는 스택포인터를 아래로 또는 위로 이동하는 스텝도 포함될 수 있습니다.

예를 들어, 이러한 3가지 단계는 32비트 x86 어셈블리 언어로 다음 지침에 따라 수행할 수 있습니다.

 움직이다 특히, 에브피   에브피  리트 

프롤로그와 마찬가지로 x86 프로세서에는 에필로그의 일부를 실행하는 명령어가 내장되어 있습니다.다음 코드는 위의 코드와 동일합니다.

 떠나  리트 

leave명령어는mov그리고.pop지시사항을 참조하십시오.

함수는 여러 개의 에필로그를 포함할 수 있습니다.모든 함수 종료점은 마지막에 공통 에필로그로 이동하거나 자체 에필로그를 포함해야 합니다.따라서 프로그래머 또는 컴파일러는 종종 다음과 같은 조합을 사용합니다.leave그리고.ret(예를 들어, C 컴파일러는 이 기능을 대체한다.return와의 진술leave/ret시퀀스)

추가 정보

  • de Boyne Pollard, Jonathan (2010). "The gen on function perilogues". Frequently Given Answers.