이론/기초

컴퓨터 구조 기초 - 3

tsyang 2023. 7. 9. 21:25

스택 프레임

 

함수 선언된 변수는 스택에 할당됨.

 

함수 호출 과정에서 할당되는 메모리 블록(지역변수 선언 등으로 할당되는) 가리켜 스택 프레임이라 한다.

스택프레임은 함수에 종속된다. 함수가 종료되면 스택프레임이 반환된다.

 

.

 

sp 레지스터

 

스택을 쌓기 위해서는 현재까지 저장한 데이터의 위치를 알아야겠지? 이를 기억하기 위해 CPU내에 sp(stack pointer)레지스터가 존재함.

 

스택 프레임이 반환되면 sp레지스터를 움직여야 하는데, 문제는 얼마나 움직여야 하는지를 모른다. 그래서 이를 기억하기 위해 프레임 포인터(FP) 존재한다.

 

.

 

 

프레임 포인터

스택프레임이 반환되면 sp fp위치로 맞추면 그만임. 그럼 fp값들은 어디에 보관?

함수가 호출되면 그때 스택에 fp값을 저장함.

 

반환될 때는 스택에 있는 fp값을 fp레지스터에 로드하면 .

 

.

 

 

함수? 프로시저?

 

함수 호출과 프로시저 호출을 구분할 있는데, 입력에 대한 반환값이 존재하면 함수 호출, 아니라면 반환 값 없는 서브 루틴의 실행을 위한 호출 = 프로시저 호출이라 한다 .

 

.

 

 

함수 호출 인자의 전달방식

 

함수 호출 전달되는 인자를 어디에다 것인가도 CPU마다 다름

 

보통은 스택에 저장된다 해도 무리는 아니지만 성능 향상을 위해서 일부 인자들은 레지스터에 저장되도록 만들기도 함.

 

.

 

 

PUSH & POP 명령어

 

스택에 변수를 할당할 , 스택에 값을 저장하고 sp값을 증가시킨다.

이건 어셈블리로 어떻게 구현?

 

예를 들어 sp 가리키는 위치에 함수 전달인자인 7 저장한다 해보자.

 

STORE 7 sp 같은 건 .

 

첫 번째는 반드시 레지스터여야 하고, 두 번째는 메모리 주소가 와야 함.

 

그러면

 

ADD r1, 7, 0 (혹은 MOV r1 7)

 

이런 식으로 스택에 저장할 값을 저장해 둬서 첫 번째에 레지스터가 오게 만들 수 있음.

 

두 번째에는 메모리 주소가 와야 하는데,

 

이걸 위해서 SP 가리키는 값을 저장할 임의의 메모리 주소를 정해야 함. 0x10이라 하자.

 

STORE sp, 0x10

 

이런 식으로 sp 값을 저장하고

 

STORE r1 [sp]

 

이렇게 indirect 모드를 쓰면? 7이라는 값을 마침내 스택에 저장할 있게 된다.

 

그다음 sp 증가시키는 연산은? 정수형은 4바이트이니까

 

ADD sp, sp, 4

 

한 번에 나타내면..

 

ADD r1, 7, 0
STORE sp, 0x10
STORE r1, [0x10]
ADD sp, sp, 4

 

 

이걸 모아서

 

PUSH 7

 

이렇게 만들 있겠지?

 

POP명령어는 그냥 아래와 같은 의미임..

 

ADD sp, sp, -4

 

인자 없이

 

POP

이렇게 쓸 수 있음.

 

 

 

이제 함수가 호출되면 fp값을 스택에 넣어야 하니까

 

PUSH fp

 

그리고 fp 스택에 올리기 위치에 sp 놓고

 

ADD fp, sp, -4

 

그다음 함수 전달인자를 넣어주면 된다.

 

PUSH 7

 

.

 

 

호출할 함수의 위치

 

코드 영역은 프로그램의 코드(컴파일된 명령어들의 집합)가 올라가 있는 위치임.

그리고 현재까지 실행한 명령어의 위치를위치를 기억하는 게 PC 레지스터

 

PC CPU에서 Fetch 할 때마다 증가함.

 

근데 if 등을 이용해서 명령어 위치를 넘어갈 있는데 PC하나 됨? ㄴㄴ

 

호출을 끝내고 나면 다시 원래 위치로 돌아와야 거임.

 

그럼 원래 위치는 어디에 쓸까? 스택에 쓴다.

 

.

 

함수 호출규약(calling convention)

함수 호출 인자를 전달하는 방식과 스택프레임을 반환하는 방식을 약속해 놓은 것을 함수 호출규약이라 .

 

 __cdecl, __stdcall

 

이런 애들이 있는데..

 

int __stdcall Foo(int a)

이런 식으로 쓸수 있음.

 

? 나는 저런거 써본 없는데? 그건 디폴트 값이 존재하기 때문임. (프로젝트 속성)

 

아무튼 이런 함수 호출규약을 통해 인자의 전달방식 (레지스터를 건지 말건지) 정해줄 수도 있고.

스택프레임을 호출자가 정리할지 아니면 호출된 함수가 반환할지도 정해줄 있음.

'이론 > 기초' 카테고리의 다른 글

OS - 프로세스  (0) 2023.07.30
아스키코드 & 유니코드  (0) 2023.07.23
컴퓨터 구조 기초 - 4  (0) 2023.07.16
컴퓨터 구조 기초 - 2  (2) 2023.07.01
컴퓨터 구조 기초 - 1  (0) 2023.06.25