스택은 함수가 사용하는 메모장으로 매개변수 전달과 돌아갈 주소 관리를 한다.

위 이미지처럼 스택은 높은 주소부터 시작해서 쌓여나가며 함수가 실행될 때 마다 지역 변수, 반환 주소값 매개변수가 스택에 쌓인다. 그리고 함수가 종료될 때 스택에서 소멸한다.
레지스터는 다양한 용도로 사용되는데 a b c d 같은 범용 레지스터 말고도 위치를 가리키는 포인터 레지스터가 있다.
ip (instruction pointer) : 다음 수행 명령어의 위치
sp (stack pointer) : 현재 스택 top 위치
bp (base pointer) : 스택 상대 주소 계산용
그리고 위 삼총사들을 알아놔야 한다.
함수호출 전에 매개변수들을 push하고
call 함수로 호출하면 함수가 끝나고 다음에 실행해야 할 주소(반환 주소값)을 push한다.
그리고 함수에 들어가서 먼저 mov rbp,rsp로 초기 rbp 값을 지정해준다.


스택에 push하기전 sp는 0x60fe38을 가리키고 있다.


push1 이후에 0x60fe30에 값이 들어갔고

sp는 0x60fe30으로 바뀌었다.
이렇게 반복해서 스택에 1,2을 push한다.

그런데 만약에 이렇게 push를 하고 그 값들을 이용해서 함수를 실행하려면 어떻게 해야 할까?
call Max를 실행하면 먼저 다음에 실행해야 할 주소(ip를 통해 얻는다)를 저장한다.
그럼 스택에 현재 1, 2, 실행할 주소가 쌓여있다.
그리고 함수가 실행될 때 push rbp 와 mov rbp,rsp 를 해준다.
먼저 rbp를 push하고 rsp값을 복사하는 이유는 돌아갈 위치를 계산하기 위해 bp값을 닻처럼 고정해 놓는 것이다.
sp는 유동적이기 때문에 고정된 bp에서 일정 비트만큼 올라가면 돌아갈 위치를 찾을 수 있다.
그럼 현재 스택에 1, 2, 돌아와야할 주소, 이전 bp값이 쌓여있고 1,2에 접근하기 위해서는

rbp(이전 bp아닌 현재 bp)에 16비트(2바이트) 더하면 2가 나오고 24비트(3바이트) 더하면 1이 나온다.
이 두 값을 비교하고 rax가 더 크면 L1으로 점프, 더 작으면 그대로 둔다.
이 상태로 그대로 실행을 하면 결과는 제대로 출력되지만 이내 크래시가 발생하는데
이는 우리가 멋대로 스택안에 1,2를 push해서 순서가 어긋나서 그런 것이다.
해결방법은 1,2를 MAX 실행 후 pop해주거나 add rsp,16으로 sp를 2바이트 만큼 올려주면 해결된다.
그렇다면 MAX에서 rax, rbx를 사용하는데 그 전에 중요하게 레지스터들을 사용하고 있었다면 어떻게 할까?
그것을 방지하기 위해서는 MAX실행 전에 rax, rbx를 push해놓고 실행이 끝나고 다시 pop해서 사용할 수 있다.
'CS' 카테고리의 다른 글
| [CS] SOLID 원칙 (0) | 2025.07.27 |
|---|---|
| [CS] 컴퓨터 구조와 CPU (0) | 2023.01.17 |
| [어셈블리] 배열 (0) | 2022.06.18 |
| [어셈블리] 반복문 (0) | 2022.06.18 |
| [어셈블리] 분기문 (0) | 2022.06.18 |