CPP_RO_스택 메모리

CJB_ny·2022년 7월 6일
0

C++ 정리

목록 보기
13/95
post-thumbnail

스택 메모리, 스택 프레임.

이거 두개는 기본기임.

스택 메모리

스택 프레임

스텍 메모리와 셋트이다.

바다의 파도를 생각하면된다.

스텍 메모리도 "높은 주소" -> "낮은 주소"로 늘어났다가 줄어들었다가 한다.

왔다 갔다하는 방식으로 진행이 된다.

지금

지역변수
변환 주소값
매개변수

인 상태로 뭔가를 저장을 하고, 이상태에서 다른 함수를 호출을 하면

이 삼종세트가 계속 다시 만들어진다.

실습

스택 메모리 까보기.

레지스터

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

  • a, b, c, d 범용 레지스터

  • 특수한 목적으로 사용되는 레지스터도 있다.

    => 포인터 레지스터이다. ( 포인터 == 위치를 가르키는)

포인터 레지스터

    1. ip (Instruction Pointer) : 다음 수행 명령어의 위치
    1. sp (Stack Pointer) : 현재 스택 top위치 (일종의 cursor)

      마지막으로 저장한 위치가 어디냐? 하는 커서느낌

    1. bp (Base Pointer) : 스택의 상대주소 계산용

스택 사용방법

가장 기본적인 방법은 Push, Pop을 이용하는 방법이다.

push

이렇게하면 stack 메모리에 1, 2, 3 을 넣은 상태이다.

pop

데이터를 꺼내서 rax에 넣어주고 (3이 들어갈듯)

꺼내서 넣어주고.. 반복.

살펴보기

중간에 rbp, rsp가 있는데

이게 오늘 우리가 알아볼 (위에서 설명한 포인터 레지스터)

sp, bp이다.

r이 붙었다는 것은 64bit로 연산을 하겠다는 의미이다.

레지스터를 보면

우리가 오늘 사용할 rbp, rsp, rip가 있는것을 볼 수 있다.

rip

rip가 지금 다음 실행될 명렁어의 주소를 가르키고있는 것이다.

우리가

친 코드는 코드영역 (ROM?)에 있는 것을 rip가 가르키고있는 것이다.

rsp, rbp 👍👍👍

와 같은 스택과 관련된 주소값을 가르키는게 두개가있는 이유는

나중에 또 설명 해줄 것이다.(스택프레임 설명할 때)

mov를 해주어서 일단 같은 주소이다.

이 0x60fe38이 마지막 까지 사용하고있던 스택주소이다.

(무슨말??)

sp (Stack Pointer) : 현재 스택 top위치 (일종의 cursor)
마지막으로 저장한 위치가 어디냐? 하는 커서느낌

bp (Base Pointer) : 스택의 상대주소 계산용

rsp의 주소를 메모리에 올려보면

이런 알 수 없는게 들어있는데

마지막으로 사용한 주소이다. 0x60fe38이.

그리고 스택은 큰 주소에서 작은 주소로 간다고했다.

0x60fe38 현재 이 주소를 가르키는데

데이터가 작아지는 쪽으로 숫자가 증가를 한다.

높은 주소가 아래에있고, 낮은 주소가 위에있다.

8씩 빼면은

0 1 2 3 4 5 6 7 8 9 a b c d e f 라서

0x60fe38 -> 0x60fe30 -> 0x60fe28 -> 0x60fe20 맞다

(16진수라서)

그리고 기본적으로 push하면 8바이트로 인식을 한다.

rsp 👍

이렇게 진행을 다하고 나서 sp의 주소값을 보면은

0x60fe20을 가르킨다 -> 8씩빼서 마지막 3을 넣은 부분.

스택메모리는 동적으로 막 할당받는 메모리는 아니고
스택메모리를 한덩어째 쪼개서 준다음에
그 안에서 적당히 쓰는 것이다.

Pop

pop하게되면

스택에 있던 값이 뽑혀서

이렇게 값이 들어가게된다.

또한

메모리에는 pop을 한다고해서 어떤 변화가 있는 것은 아닌것을 볼 수 있다.

그리고 pop이 다 끝나고나면

rsp가 38을 가르키는 것을 볼 수 있다.

(다시 돌아옴)

PPT그림.

지금 1, 2 push하고 MAX함수 호출함.

MAX 호출하고 ret만나서 종료됨. -> xor rax, rax하러 다시 감.

이렇게 할 수 있는 비결이

다음에 실행해야될 위치를 스택에다가 저장을 해주기 때문이다.

(sp가 커서역할)

call MAX 하는 부분에서도 call하면 이 부분을 스택에다가 넣어주게됨.

함수 호출시 스택

return (RET) 주소를

1
2
RET

이런순으로 넣어주게됨.

RET 주소는 어떻게 아냐?

ip : 다음 수행 명령어의 위치

ip라는 레지스터가 지금 실행하고 있는 주소를 계속 저장하고있다.

그래서 ip를 이용해서 밀어 넣어주고있는 것이다.

RET에 그래서 다음에 실행되야할 주소를 넣어준다고 보면된다.

ip가 13번째 줄을 호출해야한다고 저장한 것임.

그리고 거의 대부분 이런식으로 동작을 하는데

이게 무슨 의미냐하면은

bp라는 닻을 이전 bp에 고정을 시켜놓는것임

그러면 sp는 유동적이라 어디로 움직여도 크게 상관없다.

그렇기 때문에 rbp레지스터를 사용한다고 보면된다.

그래서 pop rbp를 사용하여 이전에 작업하던 곳으로 돌아간다는 말이다.

즉 상대주소를 알기에 편리하다.

레지스터 접근방식?

1
2
RET
이전 BP값

rbp기준으로 위로 두칸(16바이트) 올라가야 2가 있고

rbp기준으로 위로 세칸(24바이트) 올라가야 1이 있기 때문에 이렇게 해준다.

이런식으로 만들어준다.

스택프레임


이런 닻 bp들을 관리하는 것을 "스택프레임"이라 하는데

즉, 내가 어떤 함수를 호출하느냐에 따라서 스택의 공간이 왔다갔다 하는데

이것을 "스택 프레임"이라 한다.

함수 호출하고 또 호출 하면

이전 BP는 이제 처음 호출한 이전BP의 주소를 가르키게 된다는 것이다.

스택을 사용하고나서

깔끔하게 정리를 해야한다.

push 1, 2 로 강제로 조절했기 때문에

다시 돌아갈때 엉뚱한 주소를 가르킬 수 있다.

(이해는 안감)

profile
https://cjbworld.tistory.com/ <- 이사중

0개의 댓글