[컴퓨터구조] #7. MIPS 명령어(7)
Lec 7. MIPS Instructions_7 (Language of the Computer)
- Procedure (Function)
: 파라미터를 매개로 callee와 caller 간에 서로 필요한 task를 주고 리턴할 수 있도록 만들어진 subroutine.
-> make the program modular and easy, code to be reused(생산성)
Parameters (arguments)
: interface 역할. caller와 callee 모두 접근 가능한 특정 저장공간에 담아두고 함수 호출&인자 전달
Caller
: Passes arguments to a callee, Jumps to the callee
Callee
: Performs the procedure, Returns the result to the caller, Returns to the point of call
1. 파라미터를 callee도 접근 가능한 곳에 담아두고 함수 호출함.(제어권이 callee에게 넘어감)
2. 인자를 이용해서 task를 수행함.
3. 결과값을 caller도 접근 가능한 곳에 담아두고 리턴함.(돌아가기 위해 caller의 위치도 알고 있어야 함)
-> 인자 : $a0~$a3 (four argument registers)
반환 값 : $v0~$v1 (two value registers to return)
돌아갈 곳 : $ra (one return address register)
- jal (jump and link)
: J-format instruction
jal ProcedureAddress 주소(레이블)로 점프
-> $ra <- pc + 4
링크 : 리턴 시 pc+4로 돌아올 수 있도록 $ra에 넣어둠. caller가 callee에게 제어권 넘김.
-> pc <- jump target
점프 : 제어권이 callee에게로 넘어감.
- jr (jump register)
: J-format instruction
jr register 레지스터가 보관 중인 메모리 주소값으로 점프
ex) jr $ra
: $ra가 보관중인 주소로 점프. 즉, return (pc <- $ra)
- Arguments and Return Values
-> caller와 callee가 같은 레지스터 사용함
-> 아래 사진처럼 corruption 가능성 있음(문제 발생@_@!!)
- Register Corruption
caller와 callee가 같은 레지스터를 사용해서 덮어쓰기 되는 것을 방지하기 위해
'임시보관&복원하기'를 해야 함. -> spilling registers (해결책ㅇ0ㅇ!!!)
- Stack
: CPU가 갖고 있는 레지스터의 개수는 유한함(32개 in MIPS) -> 사용하는 모든 변수 수용 불가능
-> 백업&복원 과정이 필요함
Stack 은 temporarily save and restore data에 사용되는 메모리 공간임.
-> spilling (saving) registers to memory and filling (restoring) registers from memory
- Spilling Registers
Stack : last-in-first-out (LIFO) queue.
-> stack grows from high address to low address in MIPS
%sp ($29) : 일반 레지스터 中 used to point to the top of the stack
push : add data onto the stack
$sp = $sp-4
store data on stack at new $sp
pop : remove data from the stack
restore data from stack at $sp
$sp = $sp+4
- Preserved and NonPreserved Registers
: 앞의 예시에서 만약 caller가 $t0, $t1, $s0 를 callee 호출 후 사용하지 않는다면, spilling&restore 은 헛수고였음.
그러한 경우를 방지하기 위해, MIPS는 레지스터를 두 개의 카테고리로 분류했음.
Preserved : $s0~$s7 (saved)
-> 건드리면 callee책임. callee가 $s 쓸거면 spilling&restore 꼭 해야 함.
Non-Preserved : $t0~$t9 (temporary)
-> 건드리면 caller책임. callee가 마음껏 overwrite 해도 됨.
caller가 $t 필요하다면 spilling&restore 해야 함.
- Nested Procedure Calls
leaf procedure : 다른 함수를 호출하지 않는 함수 (caller 역할 안 함)
근데 어떤 함수가 caller이면서 callee라면 register spilling 신경 써서 해줘야 함.
ex) Recursive Procedure Call