CS

Call Stack이 뭘까? 디스 어셈블리, 레지스터, 메모리를 뜯어보자!

망고와플 2025. 2. 12. 18:38

콜스택(Call Stack)은 함수의 호출, 실행, 그리고 복귀를 관리하기 위해 사용되는 스택 기반의 메모리 구조입니다 (LIFO)

 

함수가 호출될 때 해당 함수의 실행 정보를 저장하기 위해 스택프레임이 생성되며,

함수 실행이 완료되면 해당 스택프레임이 제거됩니다.

 

콜스택 안에는 함수 종료 시 돌아갈 주소, 인자, 지역변수, 함수 호출 전 상태를 복원하기 위한 레지스터 값등이 스택프레임으로 저장됩니다.

그럼 어떤식으로 생성이 되고 저장이 되는지 확인해 보겠습니다.

 

간단한 CallStack 예시코드

 

우선, 해당 코드의 main함수 내의 MyAdd함수 호출 시 어떤 식으로 동작을 하는지 디스 어셈블리를 보고 한줄씩 해석해보겠습니다.

 

x86환경에서 MyAdd를 호출 시 매개변수들이 콜스택에 어떤 과정을 거쳐 저장되는지에 보겠습니다.

사진 속에 설명을 적어 놨습니다.(화살표를 따라 천천히 읽어보시면 재밌습니다..!)

 

 

이제 Add함수의 디스 어셈블리 코드를 보고 Stack Pointer와 Base Pointer가 어떻게 변화는지 보겠습니다.

기본적으로 StackPointer은 스택의 최상단을 BasePointer의 경우 스택의 기준점을 가리킨다고 볼수 있습니다.

Stack Pointer를 통해 Stack에 값을 Push할수 있으며 Base Pointer을 통해 할당 받은 메모리를 읽고 쓸 수 있게 됩니다.

(SP는 함수 실행 중에 동적으로 변화하므로, 고정된 기준점인 BP를 사용하여 매개변수와 로컬 변수에 안정적으로 접근할수 있기 때문 입니다.)

 

 

이제 스택프레임에 저장되는 레지스터가 어디에 어떻게 저장되는지 보겠습니다.

그리고 MyAdd함수의 콜 스택을 시각적으로 그려보겠습니다.

또한 Base Pointer기준으로 데이터를 어떻게 읽고 쓰는지 보겠습니다

 

함수의 종료는 할당 순서의 역순으로 생각하면 간단합니다. 스택포인터를 기준으로 어떤식으로 값을 복구하는지

디스 어셈블리를 통해 확인할수 있습니다. 

 

저는 x86기준으로 코드를 실행했기에 x64와 레지스터명 등이 조금 다를수 있습니다. 
저도 공부하면서 너무 헷갈려서 결국 이것저것 뜯어봤었던 내용이었습니다.

위에서는 _CdeclCall 스택을 Caller(위에서는 main함수)에서 정리합니다.

추후 함수 호출규약, 스택오버플로우 등에 대해 글을 쓰며 함수의 콜스택과 엮어 설명해보겠습니다.