스택 메모리

namu·2022년 6월 29일

인자 뿐만 아니라 내부에서 사용하는 변수를 저장하는 용도로도 사용한다.

파일 실행 -> 램에 올라감

메모리 저장구조
컴파일 시 크기가 결정
CODE : 함수, 제어문, 상수 영역
DATA : 전역 변수
BSS : 전역 변수

Run time 시 크기가 결정
HEAP : 동적 할당
STACK : 지역 변수

스택 프레임
높은 주소부터 사용한다.
지역 변수, 반환 주소값, 매개변수를 저장한다.

레지스터는 다양한 용도로 사용

  • a b c d 범용 레지스터
  • 포인터 레지스터 (포인터 = 위치를 가리키는)
    -- ip (Instruction Pointer) : 다음 수행 명령어의 위치
    -- sp (Stack Pointer) : 현재 스택 top 위치 (일종의 cursor)
    -- bp (Base Pointer) : 스택 상대주소 계산용
; rsp : 0x60fe38
;  push는 8바이트 단위
push 1 ; rsp : 0x60fe30, 0x60fe30 -> {0x1, 0x0, 0x0, ...}
push 2 ; rsp : 0x60fe28, {0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}
push 3 ; rsp : 0x60fe20, {0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}

pop rax
pop rbx
pop rcx ; rsp : 0x60fe38

MAX함수를 다시 만들어보자.
MAX함수 호출 시,
Stack Memory에는 매개변수 1, 2, 돌아가서 실행할 주소값(rip를 이용), 이전 BP값, 내부 변수를 저장한다.

BP를 SP로 세팅하는 이유는 스택 메모리에 수월하게 접근하기 위해서인데, SP는 동적으로 움직일 수 있기 때문에 SP를 이용하여 상대 주소를 계산하면, 코드가 어려워진다는 문제가 있다. 그래서 BP에 현재 SP를 고정해두고 상대 주소를 계산하여 스택 메모리에 접근하는 개념이다. 함수 진입 시 상위 호출의 BP를 스택에 저장해두고, 함수 반환 전 스택에서 상위 호출의 BP를 복원한다.

BP는 SP를 고정시켜서 스택의 상대 주소를 계산하는 데 쓰인다.

	push rax
    push rbx
	push 1 ; 매개 변수
    push 2 ; 매개 변수
    call MAX
    PRINT_DEC 8, rax
    NEWLINE
    add rsp, 16 ; push 1, push 2 복원
    pop rbx
    pop rax

MAX:
	push rbp ; 이전 BP값 스택에 저장
    mov rbp, rsp ; rsp를 rbp에 저장
    
    mov rax, [rbp+16]
    mov rbx, [rbp+24]
    cmp rax, rbx
    jg L1
    mov rax, rbx ; 여기서는 반환값을 rax에 담는다.
L1: 
    pop rbp ; 스택에 저장되어 있는 이전 BP값을 다시 rbp로
	ret

위 코드에서 add rsp, 16 명령을 실행하는 이유는 push 1, push 2로 인해 16바이트만큼 감소한 sp값을 되돌려 주기 위함이며, 그렇지 않으면 메인 함수에서 반환할 때 돌아갈 주소 값을 잘못 읽게 되므로 프로그램이 크래시가 난다.

push rax
push rbx
...
pop rbx
pop rax
는 rax, rbx 레지스터가 MAX 함수 호출 전에 유용하게 쓰이고 있는 경우, 값을 스택에 저장했다가 복원하는 코드이다.

profile
안녕하세요

0개의 댓글