스택 프레임이란?
쓰레드의 실행 문맥(Context)를 제공하는 스택의 추상화입니다.
다른 말로는 함수의 호출 정보를 저장하는 자료구조이고, 이 자료구조는 스택형태로 되어 있습니다.
스택 프레임에는 함수로 전달되는 매개 변수(인수)와 지역변수, 함수 호출을 마치면 돌아올 복귀 할 주소 등의 정보들이 들어갑니다.
스택프레임 형성 과정
이런식으로 호출을 하는 경우 대~충 아래처럼 스택이 쌓입니다.
sp(stack pointer)이라는 레지스터는 변수가 하나씩 할당될 때마다 증가하는데 증가하면서 다음 변수가 할당될 메모리 위치를 가르키게 됩니다.
함수가 호출이 종료되고 나서 돌아갈 곳을 기억하기 위해서 fp(frame pointer) 라는 레지스터를 사용을 합니다.
즉, sp가 돌아갈 위치를 fp가 기억을 해주는 방식입니다.
함수 호출 시 sp 레지스터에 저장된 값을 fp 레지스터에 옮기기 전에, fp 레지스터에 저장된 값을 스택에 쌓아두어 모든 스택 프레임의 경계 정보를 저장합니다.
f2함수가 호출되기 직전에 sp 레지스터에는 주소값 20이 들어가 있고 f2함수가 호출되기 직전에 fp 레지스터에는 주소값 8이 들어가 있습니다.
f2가 호출되면서 fp 레지스터에 저장된 값(주소값)을 현재 sp가 가르키는 20번지 위치에 먼저 저장하고
그다음에 fp 레지스터에 sp 레지스터값 20을 저장합니다.
위 그림 처럼 쌓였다가 fp레지스터의 값을 읽어 되돌아갈 위치를 sp가 찾습니다.
이후 스택프레임을 반환하게 되는데 이때 반환 하는 방법이 크게 두가지가 있습니다.
함수 호출 규약
첫번째는 호출자가 반환하는 방식
두번째는 호출된 함수가 반환하는 방식이 있습니다.
A함수가 B함수를 호출하는 경우 스택프레임을 정리하는 명령어들이 A함수에 존재할 수도 있고 B함수에 존재할 수도 있습니다.
이처럼 함수 호출시 인자를 전달 하는 방식과 스택 프레임을 반환하는 방식을 약속해놓은 것을 '함수 호출 규약'이라고 합니다.
C++에 가장 대표? 적인 함수호출규악은 __cdecl, __stdcall 이 있습니다.
__stdcall은 호출규약에 따라서 STDCallFunction함수의 호출과 반환을 처리하라는 뜻입니다.
이때까지 코드를 작성하면서 __stdcall과 같은 키워드를 적어준 적이 없는데 프로젝트 속성 창에 들어가면 default로 설정되어 있는것을 확인할 수 있습니다.
__cdecl은 C/C++ 의 default 호출규약으로 인자 전달 방식은 C언어 스타일을 따르고(오른쪽에 전달되는 인자가 먼저 스택에 쌓이는 방식) 스택 프레임 반환은 호출하는 호출자가 (위에서는 A가) 스택 프레임을 반환하도록 정의합니다.
__stdcall은 호출된 함수 내에서 (위에서 B가) 스택 프레임을 반환하는 방식입니다.
추가적으로 inline키워드를 함수앞에 적어서 컴파일러에게 함수를 호출하는 대신 코드를 대체하도록 '요청'할 수 있습니다.
이로 인해 함수 호출과 관련된 '오버헤드'를 피할 수 있는 장점이 있지만, 프로그램 크기가 커질 수 있기 때문에 적절히 사용해야합니다.
참고자료
https://computerscience.chemeketa.edu/armTutorial/Functions/StackFrame.html
'CS' 카테고리의 다른 글
스레드란? (1) | 2024.09.18 |
---|---|
[CS] 가상 메모리와 페이징 (0) | 2023.08.15 |
[CS] 스와핑(Swapping) (0) | 2023.08.09 |
[CS] 논리주소와 물리주소 (0) | 2023.08.07 |
[CS] Context Switching(문맥 교환) (0) | 2023.08.05 |
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!