함수 호출은 하드웨어에 종속적인 부분이 많다.
예를 들어 ARM 아키텍처에서는 함수의 전달 인자와 리턴 주소를 레지스터에 저장하도록 결정했다.
이처럼 각 아키텍처의 호출 규약(Calling Convention) 에 따라 함수 호출 방식이 달라진다.


스택 프레임 (Stack Frame)

함수 호출 과정에서 할당되는 메모리 블록을 스택 프레임이라고 한다.

  • 함수 호출이 완료되어 반환되면, 해당 스택 프레임 내부에 선언된 변수들에는 더 이상 접근할 수 없다.

주요 레지스터

SP (Stack Pointer)

  • 현재 스택의 최상단(top) 위치를 가리키는 레지스터.
  • 스택에 데이터를 push하거나 함수 호출 시 지역 변수 공간을 확보하면 SP 값이 이동한다.
  • 함수가 종료되면 SP를 이전 위치로 되돌려 해당 함수가 사용하던 스택 프레임을 해제한다.

PC vs SP
PC(Program Counter)가 다음에 실행할 명령어의 위치를 가리킨다면,
SP는 현재 스택의 사용 위치를 가리킨다.


FP (Frame Pointer)

SP는 스택의 현재 위치를 가리키기 때문에, 스택 프레임을 “어디서부터” 해제할지에 대한 기준점이 필요하다. 그 역할을 FP(Frame Pointer) 가 담당한다.

  • 함수가 호출되면, 호출 시점의 SP 값을 FP에 저장한다.
  • 함수 해제 시 FP에 저장된 위치까지 스택을 반환한다.

중첩 호출 문제와 해결

함수 안에서 또 다른 함수가 호출되면, FP 레지스터의 값이 덮어씌워지기 때문에 이전 함수의 프레임으로 복귀하기 어려워진다.

해결책: 함수 호출이 일어날 때마다, 현재 FP 값을 스택에 저장(백업)한 뒤 새로운 값으로 FP를 갱신한다.


PC (Program Counter)

  • 코드 영역과 관련된 레지스터로, 다음에 실행할 명령어의 주소를 가리킨다.
  • CPU의 Fetch 단계에서 코드 영역의 명령어를 가져올 때, 어디까지 실행했는지 추적하는 역할을 한다.

PC 백업의 필요성

함수1-앞부분 → (함수2 호출) → 함수1-뒷부분

함수 2가 종료된 후 함수 1의 이어지는 위치로 되돌아오려면 PC 값을 미리 저장해 두어야 한다.
이 경우에도 스택에 PC를 저장(백업) 한다.
이렇게 저장된 값을 리턴 주소(Return Address) 라고 부른다.


함수 호출 과정 예시

단계동작
① 함수 호출 직전SP는 현재 스택의 끝 위치를 가리킴
② 함수 호출 직전FP는 이전 함수의 스택 프레임 시작 위치를 가리킴
③ 함수 호출 시현재 FP 값을 SP가 가리키는 위치(스택)에 저장
현재 SP 값을 FP에 저장 (새 프레임 기준점 설정)
⑤ 함수 실행 중지역 변수 등이 쌓이며 SP가 이동
⑥ 함수 종료 시FP 값을 SP에 저장 → 현재 스택 프레임 제거
스택에 저장해 두었던 이전 FP 값을 복구

함수 호출 vs 프로시저 호출

구분설명
함수 호출입력에 대한 반환값(출력)이 존재하는 호출
프로시저 호출반환값 없이 특정 동작만 수행하도록 모듈화한 호출

함수 인자(Arguments)는 어디에 저장되는가?

CPU 아키텍처 및 호출 규약(Calling Convention)에 따라 다르지만, 크게 두 가지 방식이 있다.

  • 스택 저장 방식: 지역 변수와 마찬가지로 스택에 할당 (전통적인 방식)
  • 레지스터 저장 방식: 성능 향상을 위해 레지스터에 저장 (ARM, x86-64 등 현대 아키텍처에서 주로 사용)