일반적으로 6가지로 나눌 수 있다.
위의 그림같이 일어난다.
용어부터 설명하자면
Caller는 callee를 부르는 주체 -> 함수를 부르는 routine을 말함.
Callee는 Calling을 당하는 대상 -> 불려지는 함수를 말함
1. 메인 루틴에 $a0부터 $a3까지 argument register에 해당 파라미터를 가져다 놓음
-> 4개의 레지스터이므로 최대 4개까지의 파라미터를 보낼 수 있음. (Callee가 이용할 수 있게)
2. Caller가 Callee에게 제어를 넘김
-> 즉 Caller 루틴이 멈추고 Callee 가 실행된다는 말이다.
3. Callee가 실행되면 Callee가 필요한 자원들을 받기 위해 메모리를 할당 받는다.
(보통 stack에 할당)
4. Callee 본연의 역할 수행
5. Callee의 수행이 끝나면 Callee 수행 결과(return value)를 Caller가 접근 가능한 레지스터에 넘긴다.
-> $v0과 $v1을 이용하여 넘김
6. Callee가 제어를 Caller에게 넘긴다.
$ra 레지스터는Callee에게 제어를 넘기기 전까지 수행했던 단계를 저장해놓고 있으므로
$ra를 사용하여 해당 주소를 Program Counter로 복사해서 $ra 부터 명령어부터 다시 실행할 수 있도록 한다.
각 레지스터는 아래와 같이 쓰인다.
위를 참고하면 더 이해가 잘 될 것이라
믿어 의심치 않는다.
그렇다면 실제로 어떻게 procedure가 호출이 되고
일어나는 과정이 어떻게 되느냐?
Procedure call은 주로 jump and link 명령으로 이루어진다.
jal 뒤에 call하고 싶은 프로시져의 label을 호출한다.
jal은 해당 프로시져로 점프하면서 동시에 원래 루틴이 해야 할 다음 명령어 주소를 $ra에 넣는다.
(때문에 다시 나중에 정상적으로 루틴이 실행될 수 있는 것이다.)
Procedure return은 jr 즉, ump register로 이루어진다.
$ra에 있는 값을 PC(program counter)에 넘겨서 다시 원래 명령어가 수행되게 한다.
예를 몇가지 보자Leaf Procedure를 보자.
Leaf란 자신을 포함한 다른 함수를 부르지 않는 Procedure를 말한다.
parameter가 4개이고 우리가 레지스터에 넣을 수 있는 레지스터도 4개니까 잘 작동한다.
SP가 4가 줄었다는 것은4바이트만큼의 메모리를 할당했다는 것이다.
스택에다 $s0의 값을 복사해서 올리고 (계산이 끝난 후에 $s0의 값을 복원하기 위함) ...연산을 한 후
결과를 $v0에 넣는다.그 후 $s0의 값을 스택에 넣어놓은 메모리에서 복원한다.다시 스택 포인터를 조정해서 메모리를 해제한다.
$ra로 보내서 Caller로 가게 된다.
당연히 Leaf가 있으면 Non-Leaf도 있겠다.
당연히 다른 함수를 부르기 때문에 Caller를 스택에 저장해두어야 다시 불러올 수 있다.
return address를 저장하고, Argument나 temporary값들 또한 그렇다.
그 후 복원하는 것이다.
예를 보자
팩토리얼 계산 함수이다. 재귀방식임을 알 수 있다.
fact 에서
1. 스택메모리를 할당한다. (8바이트)
2. 함수에서 사용하는 $ra, $a0의 값을 스택에 저장한다.
.....
다른 것과 같다.
과정이 많아서 복잡할 뿐이다.
다음은 우리가 스택포인터와 프레임 포인터를 배워보겠다.
왜 이것이 함수, Procedure에서 필요한지 알아보자
우리가 지역변수를 어디다 저장하는가? 를 생각해보면 알 수 있다.
지역변수는 스택에 할당된다.
프로시져 프레임. Procedure frame이란
프로시져가 실행될 때 해당 프로시져에 대한 스택을 할당하는 것이다.
해당 프로시져 프레임에 대한 스택의 시작주소를 frame pointer라고 한다.
sp, stack pointer는 해당 스택의 top을 가리키고 있다.
fp, frame pointer는 현재 실행하는 함수의 스택의 시작주소를 가리킨다.
때문에 해당 스택에는 argument register , ra, saved register 그리고 local 들이 순서대로 들어간다.
즉, 해당 프로시져가 끝나면 다시 이전 프로시져 프레임으로 돌아가겠구나 생각하면 된다.
참고
어떻게 되먹은 메모리이길래 저렇게 할당하느냐??
이렇게 생겼다.
Text는 프로그램 코드로 명령어들을 말한다.
전역에 선언하는 것들은 static data에 들어가며
전역 변수, 상수, 배열, 문자열 등 많이 있다.
여기서 바로 gp, global pointer가 쓰이는 것이다.
global pointer는 static data를 가리킨다고 보면 된다.
Stack(자동할당)과 Dynamic Data(heap)은 같은 공간에 있다.
'컴퓨터(Computer Science) > 컴퓨터구조(Computer Arichitecture)' 카테고리의 다른 글
컴퓨터 구조 분야에 대한 8가지 아이디어 [컴퓨터구조] (0) | 2020.05.16 |
---|---|
Integer Arithmetic 사칙연산 [컴퓨터구조] (0) | 2020.04.26 |
CPU 기본구조와 프로세서, Processor [컴퓨터구조] (0) | 2020.04.08 |
MIPS의 구조, 프로세서와 메모리 [컴퓨터구조] (0) | 2020.04.08 |
MIPS Addressing for 32-Bit [컴퓨터구조] (0) | 2020.03.31 |