-
[컴퓨터 밑바닥의 비밀] 3.3 스택 영역: 함수 호출은 어떻게 구현될까?Study/컴퓨터 밑바닥의 비밀 2025. 3. 9. 17:30
스택 프레임 및 스택 영역
- 프로세스의 스택 영역에 스택 프레임(호출 스택)이 생성됨
- 프로세스의 스택 영역의 높은 주소가 맨 위에 있고 스택 영역은 낮은 주소 방향을 커짐
- 스택 영역이 차지하는 메모리는 함수 호출 깊이에 따라 증가하고 함수 호출이 완료될수록 감소함
함수 점프와 반환은 어떻게 구현될까?
- 함수 A가 함수 B를 호출하면, 제어권이 함수 A -> 함수 B로 옮겨짐
- 제어권: 실제로 CPU가 어떤 함수에 속하는 기계 명령어를 실행하는지
- 제어권이 이전될 때는 다음 두 가지 정보가 필요함
- 반환(return): 어디에서 왔는지에 대한 정보 (다시 돌아갈 정보)
- 점프(jump): 어디로 가는지에 대한 정보
- 함수 A가 함수 B를 호출할 때 알아야 하는 정보
- 함수 A의 기계 명령어가 어디까지 실행되었는지(어디에서 왔는지)
- 함수 B의 첫 번째 기계 명령어가 위치한 주소(어디로 가는지)
Q. 이런 정보를 어떻게 획득하고 유지할까?
- 함수별 스택 프레임을 사용함
- 함수 B는 마지막 기계 명령어인 ret까지 계속 실행되고, 이 기계 명령어는 CPU에 함수 A의 스택 프레임에 저장된 반환 주소로 점프하도록 전달함
매개변수 전달과 반환값은 어떻게 구현될까?
- 함수를 호출할 때는 매개변수를 전달하고 반환값을 가져와야 함
- x86-64에서는 대부분의 경우 매개변수의 전달과 반환값을 가져오는 작업을 레지스터로 함
- CPU 내부의 레지스터 수는 제한되어 있음
- 매개변수 수가 레지스터 수보다 많으면 나머지 매개변수는 스택 프레임에 직접 넣음
- 새로 호출된 함수가 이전 함수의 스택 프레임에서 매개변수를 가져옴
- 함수 B를 호출할 때 매개변수 중 일부를 함수 A의 스택 프레임에 넣음
지역 변수는 어디에 있을까?
- 지역 변수는 함수 내부에서 정의된 변수. 해당 함수에서만 사용 가능하고 외부에서는 접근 불가능
- 로컬 변수 수가 레지스터 수보다 많으면 이 변수들도 스택 프레임에 저장됨
레지스터의 저장과 복원
상황
- 레지스터는 CPU의 내부 리소스
- CPU가 함수 A를 실행할 때 레지스터를 사용하고 CPU가 함수 B를 실행할 때도 레지스터를 사용한다면, 함수 A가 레지스터에 기록한 지역 변수 정보를 함수 B가 덮어쓸 수 있음
방식
- 레지스터에 새로운 지역 변수를 저장하기 전에 반드시 레지스터에 원래 저장되었던 초기값을 별도로 저장해두고, 함수 실행이 완료된 후 레지스터에 다시 그 초기값을 복원함
- 레지스터 초기값은 함수의 스택 프레임에 저장됨
큰 그림을 그려보자, 우리는 지금 어디에 있을까?
- 스택 영역은 프로세스 주소 공간의 일부
- 함수가 호출될 때마다 스택 프레임은 함수 실행 시 정보를 저장하기 위해 생성되고, 함수 호출 단계가 증가함에 따라 스택 영역이 점점 더 많은 메모리를 차지함
- 스택 영역의 크기에는 제한이 있고, 이 제한을 초과화면 stack overflow 오류가 발생함
- 따라서 아래 사항을 주의해야 함
- 너무 큰 지역 변수를 만들면 안된다.
- 함수 호출 단계가 너무 많으면 안된다.
- 참고) 유휴 영역(free segment)
- 프로그램이 사용하는 동적 라이브러리가 이 영역에 적재됨
'Study > 컴퓨터 밑바닥의 비밀' 카테고리의 다른 글
[컴퓨터 밑바닥의 비밀] 6. 입출력 (0) 2025.03.24 [컴퓨터 밑바닥의 비밀] 2.7 블로킹과 논블로킹 (0) 2025.03.02 [컴퓨터 밑바닥의 비밀] 2.3 스레드 안전 코드 (0) 2025.03.01 [컴퓨터 밑바닥의 비밀] 2.2 스레드 간 공유되는 프로세스 리소스 (0) 2025.03.01 [컴퓨터 밑바닥의 비밀] 2.1 운영체제, 프로세스, 스레드 (0) 2025.03.01