Computer Science 기본 지식/컴퓨터 구조

[컴퓨터 구조] 스택 포인터와 프레임 포인터

로파이 2021. 5. 1. 19:02

함수 호출과정에서 스택 프레임에 대해 일어나는 일을 알아보도록 한다.

 

스택 포인터와 프레임 포인터

 

스택 프레임 (Stack Frame)

기본적으로 함수가 호출될 때마다 전달한 인자와 정의한 지역(자동) 변수가 높은 주소부터 낮은 주소의 방향으로 차례대로 저장되는 구조이다. 이외에도 다른 함수를 호출할 때 복귀할 주소(다음 실행할 명령어의 주소), 프레임 포인터 및 보존되는 레지스터들이 스택에 저장된다. 스택 포인터는 함수 호출 시작부터 피호출 프로그램이 실행되는 단계 차례대로 저장되는 값들을 저장하기 위해 현 시점에서 저장할 메모리의 위치를 가리킨다.  

 

스택 프레임에 저장되는 값

- 복귀 주소

- 호출자 루틴의 프레임 포인터

- 사용하던 보존 레지스터

- 피호출자에 전달하는 인자

- 피호출자에서 사용되는 지역 변수들

 

프레임 포인터 (Frame Pointer)

함수 호출이 끝난다면 상위 호출로 돌아기전에 지역 변수에 할당한 자원을 파괴한 후 스택 포인터를 옮겨서 호출자가 함수를 호출하던 상황을 만들어야한다. 이 때, 프레임 포인터가 사용되는데 프레임 포인터는 호출자가 호출하던 시점의 스택 포인터를 저장하고 피호출 프로그램이 종료할 때 이 값을 이용하여 스택 포인터를 재조정하는데 사용한다.  

스택 포인터는 특수 레지스터, sp 레지스터에 저장되고 프레임 포인터는 fp 레지스터에 저장된다.

현 상황에서 func2()가 종료되면 스택 포인터는 fp 레지스터에 저장된 프레임 포인터를 보고 되돌아가야 한다. 하지만 fp 레지스터에는 func3()의 프레임 포인터 fp가 저장되어 있었고 func2()의 fp는 어디있는 지 모른다.

 

사실 func3()를 호출할 당시 fp 레지스터에 저장된 func2() 프레임 포인터가 스택에 저장된다.

추후 func3() 함수를 정상적으로 실행하고

func3()를 호출이 끝나고 func2()로 돌아오는 과정에서 스택 포인터를 fp 레지스터 값으로 바꾼다. 현재 스택 포인터 주소에는 func2()의 프레임 포인터가 저장되어 있고 이 값를 fp 레지스터에 초기화한다.

 

프레임 포인터는 현 프로시저가 사용하는 스택 프레임의 경계값이라고 할 수 있다.

 

복귀 단계에서는 다음 실행할 명령어 위치를 프로그램 카운터에 저장해야한다. 보통 다음 실행할 명령어 위치는 순차적 실행이 진행된다면 1워드 씩 증가하는 프로그램 카운터를 참조하면된다. 복귀할 때 실행할 명령어의 주소를 가져와야하기 때문에 함수 호출 시점에서 현재 프로그램 카운터를 스택에 저장하게된다.

따라서 현재 스택 프레임에는 프레임 포인터 뿐만 아니라 복귀 주소 또한 스택에 저장되어 있다.