ESP(스택 포인터)가 아닌 EBP(베이스 포인터) 레지스터를 사용하여 스택 내의 로컬 변수, 파라미터, 복귀 주소에 접근하는 기법을 말합니다
ESP 레지스터의 값은 프로그램 안에서 수시로 변경되기 때문에 스택에 저장된 변수, 파라미터에 접근하고자 할 때 ESP 값을 기준으로 하면 프로그램을 만들기 어렵고, CPU가 정확한 참고할 때 어려움이 있습니다
어떤 기준 시점(함수 시작)의 ESP 값을 EBP에 저장하고 이를 함수 내에서 유지해주면, ESP 값이 아무리 변하더라도 EBP를 기준(BASE)으로 안전하게 해당 함수의 변수, 파라미터, 복귀 주소에 접근할 수 있습니다
PUSH EBP ; 함수 시작(EBP를 사용하기 전에 기존의 값을 스택에 저장)
MOV EBP, ESP ; 현재의 ESP(스택포인터0를 EBP에 저장
... ; 함수 본체
; 여기서는 ESP값이 변경되어도 EBP값은 변하지 않기 때문에
; 안전하게 로컬 변수와 파라미터를 액세스 할 수 있음
MOV ESP, EBP ; ESP를 정리(함수 시작했을 때의 값으로 복원시킴)
POP EBP ; 리턴되기 전에 저장해 놓았던 원래 EBP 값으로 복원
RETN ; 함수 종료
StackFrame.cpp 파일을 가지고 진행했습니다
#include "stdio.h"
long add(long a, long b)
{
long x = a, y = b;
return (x + y);
}
int main(int argc, char* argv[])
{
long a = 1, b = 2;
printf("%d\n", add(a, b));
return 0;
}
해당 소스코드를 가지고 실행파일로 만들어 디버깅을 시작합니다
main 함수의 주소인 401020에 BP(Break Point)를 설치 후 실행을 했습니다
이 때 스택의 상태는 아래와 같습니다

현재 ESP 값은 0019FF74이며 여기에는 main() 함수가 끝난 후 리턴 할 주소인 769900F9가 저장되어 있습니다
int main(int argc, char* argv[])
{

시작과 동시에 스택 프레임을 생성합니다
먼저 EBP가 베이스 포인터의 역할을 하도록 이전에 가지고 있던 값을 스택에 백업해두기 위한 용도로 PUSH를 합니다
두 번째로 ESP의 값을 EBP로 옮깁니다
명령 실행 후 ESP의 값은 EBP와 같도록 설정되며 main() 함수가 끝나기 전까지 EBP 값은 고정됩니다
EBP 설정이 완료되었습니다


long a = 1, b = 2;
이제 main() 함수 내 로컬 변수(a, b)를 위한 공간을 만들고 값을 입력합니다

먼저 ESP 값에서 8을 빼는 과정을 진행합니다
현재 ESP 값은 0019FF70입니다
두 변수에게 필요한 메모리 공간을 확보(예약)한 것입니다
EBP 값은 main() 함수 내에서 고정이므로 이를 기준으로 삼아서 로컬 변수에 접근할 수 있습니다
MOV DWORD PTR SS:[EBP-4], 1

실행 후 스택의 모양을 확인해보면 1, 2 순으로 저장된 것을 확인할 수 있습니다