포스트

스택 프레임(Stack Frame)과 콜스택(Call Stack)

콜 스택(Call Stack)이란, 프로그램이 실행되는 동안 현재 실행중인 함수(혹은 Procedure)에 관한 정보를 관리하기 위한 자료 구조입니다.

그리고 스택 프레임(Stack Frame)은 콜 스택에 담기는 메모리 블록으로, 함수에서 사용되는 값이나 반환 주소 등을 담고 있는 데이터 블록입니다.

콜 스택(Call Stack)

콜 스택은 프로그램이 실행되는 동안 현재 실행중인 함수(혹은 Procedure)에 관한 정보를 관리하기 위한 자료 구조로, 각 프로세스의 스택 메모리 영역이라고 할 수 있습니다.

콜 스택을 사용하는 목적은 프로그램의 실행 흐름을 제어하고, 어떤 함수가 어떤 순서로 호출되었는지, 그리고 어디로 돌아가야 하는지 등을 추적하기 위함입니다.

이를 위해 스택 자료구조를 사용합니다. (스택 자료구조는 링크를 참조해 주세요.)

콜스택의 주요 역할

  1. 함수 호출 정보 저장: 함수가 호출될 때마다 콜스택에는 그 함수의 ‘스택 프레임’이라는 데이터 블록이 추가됩니다.
  2. 프로그램의 실행 흐름 제어: 스택이라는 자료구조로 호출 순서를 유지하면서, 역순서 보장으로 함수 호출이 종료되고 어떤 함수로 돌아가야 하는지 등의 흐름을 제어합니다.

작동 방식

  1. 함수 호출: 함수가 호출되면 새로운 스택 프레임이 생성되어 콜스택의 맨 위(push)에 추가됩니다.
  2. 함수 실행: 콜스택의 맨 위에 있는 스택 프레임을 기반으로 현재 함수가 실행됩니다.
  3. 함수 종료: 함수가 작업을 마치면, 그 함수의 스택 프레임은 콜스택에서 제거(pop)됩니다. 그리고 저장되어 있던 반환 주소로 돌아가 작업을 이어서 수행합니다.

스택 프레임(Stack Frame)

스택 프레임은 프로그램의 함수(혹은 Procedure)가 호출될 때 생성되는 데이터 블록입니다.

이 블록은 함수의 실행에 필요한 여러 가지 정보를 담고 있으며, 함수가 종료되면 이 정보는 메모리에서 해제됩니다.

스택 프레임의 주요 구성 요소

  1. 매개 변수(Parameters): 함수가 호출될 때, Caller가 전달되는 인자들의 정보를 저장합니다.
  2. 반환 주소(Return Address): 함수의 실행이 끝난 후, 돌아갈 부모 함수(Caller)의 주소를, Caller가 저장합니다.
  3. 이전 EBP 값(Old EBP): 함수 프롤로그(Function Prologue)에서 현재 EBP 값을 저장합니다. 이는 이전 함수의 스택 프레임의 기준점을 나타냅니다.
  4. 지역 변수(Local Variables): 함수 내에서만 사용되는 변수들의 값을 저장합니다.

스택 프레임의 주요 구성 요소


IP, BP, SP란?

이때, 스택 프레임과 관련된 포인터들이 있습니다.

  • IP (Instruction Pointer): 다음 수행되는 명령어의 위치를 가리키는 레지스터입니다.
  • SP (Stack Pointer): 다음 데이터의 저장을 위해 스택 최상단의 주소를 지시하는 레지스터입니다. 스택의 주소는 높은 값에서 낮은 값으로 할당되기 때문에, ESP가 가리키는 최상단 주소는 낮은 주소값이 됩니다.
  • BP (Base Pointer): 함수 시작시 현재 함수의 기준 주소를 가리킵니다. ESP는 그 위치가 수시로 변경되기 때문에, ESP로 지역변수나 매개변수에 접근하기 어려워집니다. 따라서 EBP를 고정하고, EBP 기준으로 값에 접근하는게 쉽기 때문에, EBP는 함수가 실행되는 도중에는 고정 값을 가집니다.

스택프레임 동작 1

스택프레임 동작 2

이 이미지에서 ESP는 스택의 아래(높은 주소)로 이동할 뿐, 실제로 데이터가 지워지는 것은 아닙니다. 다만, 사용하지 않는 무효한 값이 될 뿐입니다.


스택 오버플로우(Stack Overflow)

스택 오버플로우는 함수 호출이 깊어지거나 지역 변수의 사용이 과도할 때 스택 포인터가 스택의 경계를 넘어서면 발생합니다.

즉, 스택에 너무 많은 데이터가 쌓여 스택의 용량을 초과할 때 발생합니다.

스택의 크기는 컴파일러 설정에 따라 다를 수 있습니다. VisualStudio 윈도우 기준 32bit에서는 1MB이고, 64bit에서는 1MB~4MB 정도로 알고 있습니다. 하지만, 컴파일러 옵션을 통해서 조절할 수 있습니다.


스택 언더플로우 (Stack Underflow)

스택 언더플로우는 스택에서 데이터를 꺼내려 할 때 스택이 비어있는 상태에서 발생합니다. 즉, 꺼낼 데이터가 없는데, 꺼내려고 시도할 때 발생합니다.

스택 언더 플로우가 발생하는 상황은 일반적으로 드물고, 경험한적이 없지만, 보통 함수가 잘못된 방식으로 반환되어 콜스택의 제어 흐름이 깨질 때 발생 할 것으로 알고 있습니다.

또한, 낮은 수준의 프로그래밍(어셈블리어)에서 스택 포인터 조작을 잘못 할 경우에 발생할수도 있습니다.

이 기사는 저작권자의 CC BY-NC-ND 4.0 라이센스를 따릅니다.