오래 못 할 짓 하지 않기
[ 컴퓨터 구조 ] 8. Procedure 본문
Procedure
: Fucntion이라고 생각하면 됨.
● Procedure call step
1. 함수를 접근할 수 있는 곳에 파라미터를 넣어준다.
2. 함수로 이동( Transfer control )
3. 함수에 필요한 정보들을 메모리에서 가져온다.
4. 함수에 있는 동작 실행
5. 접근(함수 call)한 부분에 값을 놓는다.
6. 원래 흐름대로 다시 진행
● Procedure call 에 사용되는 Register
- $a0 ~ $a3 : Arguments 전달하는데 사용되는 레지스터 4개
- $v0 ~ $v1 : 결과값 return하는데 사용되는 레지스터 2개
- $ra : 원래 PC주소로 돌아가기 위해 주소를 저장하는 레지스터 1개 ( 살작 르블랑 w 느낌임 )
● Procedure call 에서 흐름
- JAL (주소) 명령어가 실행된다면 [ 원래 흐름(메인 함수)에서 특정 함수로 넘어갈 때 사용 ]
1) PC ← JAL가 가라고 한 주소
2) $ra ← JAL없었으면 원래 가려고 했던 주소: PC or PC+4
- JR $ra 명령어가 실행된다면 [ 실행된 함수에서 Main함수로 돌아갈 때 사용 ]
1) PC ← $ra
위에 있는 그림으로 보면,
h=f(3) < PC = 100
g=h+1 < PC 104
f (int i ) << 200
이라고 했을 때, f(3)으로 함수가 call됐을 때
PC는 그 다음 값을 104로 하지 않고 200으로 한다.
PC값을 바꾼 뒤에 원래 가려고 저장해둔 104는 ra register에 저장해둠..
함수의 실행이 끝나고는 다시 PC값에 ra 값을 넣는다.
Procedures use More Registers by Stack
: Stack 구조로 Register에 있는 데이터를 다루어야 값이 섞이지 않는다.
주로 메인이 가장 아래, 그 위에 호출되는 순으로 간다.
**( 이 부분은 더 알게되는 거 있으면 업데이트 하는 걸로 ) **
예)
1. 레지스터들을 스택에 넣는다.
- 새로 호출된 f는 $s0 레지스터에 할당함.
- $t0 레지스터에 (g+h) 를 넣고, $t1 레지스터에 (i+j) 를 넣는다.
2. 명령어대로 작동하여 SUB s0 t0 t1 를 실행한다.
3. 그 값은 $s0에 남아있다.
4. Return 을 위해서 $v0에 $s0 값을 넣는다.
5. Return 하고 돌아가기 위해 JR $ra.
ㅡㅡㅡㅡㅡㅡㅡㅡ
새로 올라오는 강의에 필요한 자료
*그림 오타: 파란색 add부분 옆 주석에 $s1 -> $t0 / $s2 -> $t1
(이전)
1. 스택은 word크기로 3개 addi해서 만들어 놓는다. ( 1번줄 )
2. 각각의 register들을 1word 에 하나씩 스택에 넣어준다. ( 2 ~ 4번줄 )
3. 연산을 하고, return을 위해 v0 register에 옮겨준다.( 5~7번줄 + 8번줄 )
4. 다 load한 뒤에 sp값을 원래대로 다시 돌아오면서 12bytes = 3words ,3개를 pop한다.
5. JR을 이용하여 원래 PC값으로 돌아온다.
(이후) -- > return은 $s0만 할 거임. 나머지는 휘발성 정보들이라 t레지스터에 넣을 예정
1. 스택을 word단위로 1칸을 만든다.
2. 하나의 register ($s0) 을 넣어준다. 나머지 것들은 굳이 stack에 안 넣어도 됨
3. 연산을 하고, return을 위해 v0 register에 옮겨준다.( 파란색 + 노란색 )
4. load하고 pop
5. JR을 이용하여 원래 PC값으로 돌아온다.
그냥 연산할 때만 필요해서 잠깐 만드는 register = > $t0 ~ $t9
(지역변수 tmp라고 이해함) ( 함수 들어갔다가 나오면 값이 안 남아있음)
계속 보존되어 쓰일 register = > $s0 ~ $s7 (전역변수라고 이해함) (주로 메인에서 계속 쓸 것)
이렇게 하는 이유 ) regisetr spilling을 줄이기 위해
* register spilling : 레지스터에 값을 가져오고 저장하고 하는 것
*** Exercise ***
각 명령어 별로 ra에 뭐가 들어가는지, 어떻게 흘러가서 어디로 돌아오고 어디로 넘어가는지 알아야함
- main에서 진행하다가 PC = 200일 때 sub1 함수로 간다. ( 그 순간에 PC = 204 , Ra = X )
- sub1함수로 넘어가고 PC = 300이 된다. ( 그 순간에 PC =300, Ra는 이전에 가르키고 있는 PC값인 204)
- PC = 400인 곳에서 sub2함수를 만나서 PC=404 에서 600 으로 되고 넘어간다. ( PC=600, Ra = 404 )
- sub2 에서 ra값을 저장하고 다시 lw하고 POP을 한 뒤에 JR을 이용하여 돌아가게된다. 그럼 이전에 불렸던 함수인 sub1으로 감 ( PC = 404 , Ra = 204 )
- sub1에서 돌아갈 곳을 Load하여 POP하고 JR ( PC = 204 , Ra =X )
* Ra는 스택 형태로 저장됨
* sw $ra 4 : 돌아갈 주소를 ra register에 스택 형태로 저장함.
* lw $ra 4 -> addi $sp,$sp, 4 --> jr $ra : 돌아갈 주소 가져오고 > POP하고 > Jump
* $sp : stack pointer , $fp : frame pointer
그냥 이건 이해정도만 해라~ 하심
참고만 하기
Exercise
이거 MIPS Inst로 풀어보기
(출처)
한동대학교 용환기교수님 - 컴퓨터구조
'2학년 2학기 > 컴퓨터 구조' 카테고리의 다른 글
[ 컴퓨터 구조 ] 문제 풀기 (0) | 2023.10.05 |
---|---|
[ 컴퓨터 구조 ] 9. Overflow (Data path) (0) | 2023.10.03 |
[ 컴퓨터 구조 ] 7. MIPS Addressing Mode (0) | 2023.09.30 |
[ 컴퓨터 구조 ] 6. MIPS Instructions (0) | 2023.09.24 |
[ 컴퓨터 구조 ] 5. MIPS 에 관하여 (2) - Control branch (0) | 2023.09.23 |