Zettelkasten

스택은 함수의 실행 정보를 프레임 단위로 저장한다

·수정 2026.04.23·수정 2

요약

  • 스택은 LIFO 구조로 함수 호출마다 스택 프레임을 push하고, 함수 종료 시 pop하여 중첩된 함수 실행을 관리한다
  • 각 프레임에 반환 주소가 저장되어 있어 함수 종료 후 어디로 돌아갈지 알 수 있다

본문

스택 프레임에 저장되는 정보

  • 반환 주소 (Return Address): 함수 종료 후 돌아갈 코드 위치
  • 이전 프레임 포인터: 호출자의 스택 프레임 위치
  • 매개변수: 함수에 전달된 인자
  • 지역 변수: 함수 내부에서 선언된 변수

반환 주소의 정체

  • 반환 주소는 Text 영역에 있는 call 명령어 바로 다음 명령어의 주소
  • 반환 주소 은 Text 영역의 주소, 저장 위치는 Stack 영역
Text 영역
─────────────────────────────
0x1004: call foo        ← 함수 호출
0x1009: call bar        ← 반환 주소 (foo가 끝나면 여기로)
  • call 명령어 자체가 아닌 "다음" 명령어 주소를 저장하는 이유: call 주소로 돌아가면 같은 함수를 다시 호출하여 무한 루프 발생

Text 영역 vs Stack 영역

구분 Text 영역 Stack 영역
저장 내용 코드 (명령어) 함수 실행 정보
특성 정적 (불변) 동적 (호출마다 생성/소멸)
예시 함수 코드는 한 번만 존재 같은 함수 10번 호출 시 10개의 스택 프레임

동작 원리

A() → B() → C() 호출 시:

┌─────────────────┐  ← Stack Top
│  C의 스택 프레임  │
├─────────────────┤
│  B의 스택 프레임  │
├─────────────────┤
│  A의 스택 프레임  │
└─────────────────┘

C() 종료 → C 프레임 pop → B로 복귀
B() 종료 → B 프레임 pop → A로 복귀

같은 함수도 호출마다 별도 프레임

int add(int a, int b) {
    return a + b;
}

void main() {
    int x = add(3, 5);   // 첫 번째 스택 프레임 생성 → 종료 시 제거
    int y = add(10, 20); // 두 번째 스택 프레임 생성 → 종료 시 제거
}

각 호출이 독립적인 스택 프레임을 가지므로 값이 섞이지 않는다.


스택의 특성

  • 자동 메모리 관리: 함수 종료 시 스택 프레임이 자동으로 정리됨 (힙과 달리 명시적 해제 불필요)
  • 크기 제한: 스택 영역은 고정 크기(보통 1~8MB)로 할당됨
  • Stack Overflow: 재귀 호출이 깊어지면 스택 프레임이 계속 쌓여 크기 제한을 초과할 때 발생

참고