
<aside> 💡 목차
</aside>
Week 2 Tutorial - Building an ALU
ALU , MUX , Full Adder , 각 기본 연산 등 자세히 설명
| 0 | $ zero |
상수 0 고정 | |
|---|---|---|---|
| 1 | $ at |
어셈블러가 명령어 번역하거나 데이터 처리할때 씀 | |
| 2 | $ v0 |
caller saves |
상위 32비트 리턴값 |
| 3 | $ v1 |
하위 32비트 리턴값 | |
| 4 | $ a0 |
caller saves |
caller saves |
| 5 | $ a1 |
인수 (arguments) | |
| 6 | $ a2 |
print(a) ← a 가 인수 | |
| 7 | $ a3 |
||
| 8 | $ t0 |
caller saves |
임시값 1 (temporary) |
| ~ | 함수 내에서 함수가 실행되었을때, 원래 지점으로 돌아가기 위함 (체크포인트 아닌듯) | ||
| 15 | $ t7 |
2 + 3 할때 5를 표현할때 5를 저장할 필요는 없으니 그냥 출력하는개념 | |
| 16 | $ s0 |
callee saves |
전역변수, 상수 (permanent) |
| ~ | |||
| 23 | $ s7 |
||
| 24 | $ t8 |
caller saves |
임시값 2 (temporary) |
| 25 | $ t9 |
||
| 26 | $ k0 |
reserved |
운영체제 (OS kernel) |
| 27 | $ k1 |
||
| 28 | $ gp |
caller saves |
(Global Pointer) malloc 이나 array같이 배열의 시작 위치를 담는 포인터 |
| 29 | $ sp |
preserved |
(Stack Pointer) 스택의 현재 위치를 담는 포인터 |
| 30 | $ fp |
callee saves |
(Frame Pointer) 멀티태스킹할때 각 task들이 저장될 프레임들 |
| 31 | $ ra |
caller saves |
(Return Address) |
| 특정 함수가 종료되고 함수가 실행되기 직전 실행 위치로 돌아가기 위해 사용되는 | |||
| 이전 작업 주소 포인터 |
<aside> 💡 main 함수 내부에서 sub함수를 실행하면?
아래 그림처럼 sub 함수가 위치한 장소에서 연산을 수행 후, 다시 main으로 돌아올 것이다.

근데 이 sub함수는 main에서만 불러오는게 아니라, 다른곳, 여러곳에서도 불러올 수 있잖아?
돌아가는 위치를 sub 함수에 저장하면, another 이라는 함수에서 sub를 실행했을때, another로 돌아와야하는데, 엉뚱하게 main함수로 이동할 수도 있겠네?

그래서 원래 실행되었던 함수로 돌아가기 위해 $ ra 가 필요했던 것이다
즉. caller 와 callee 문제는 바로 원래대로 돌아갈때, 돌아가는 위치를 main 에서 sub 수행전에 자신의 주소를 sub에게 알려줄지, 아니면 sub 자체가 자신이 실행한 주소를 저장하여 마지막 실행 분기점으로 갈 것인지 다루는 문제이다
</aside>
<aside> 💡 일반적으로 결과는 레지스터로 받는데, 이 레지스터들을 쓰기 위해서 이 레지스터들을 arguments나 temporary에서 시로 레지스터로 쓰고 return values로 출력을 하니 8~15까지 레지스터를 쓰고있었으면 이 레지스터의 값은 temporary 에 있긴 하지만,
return 하고 원래 함수로 되돌아 오더라도 값이 변하지않고 연속성을 지닌채 그대로있다고 기대하고있다

기본 main()에선 이놈이 다른함수에서 뭘 하고 왔는지 알 수 없을것 아니냐
내가 쓰던값이 그대로 있다고 가정하고 프로그램이 돌아야한다
main(){
int a = 1
for( ... )
}
레지스터도 코드와 마찬가지로 함수를 호출하고 원래 자리로 돌아와도 이전 상태가 유지되는것을 기대한다
그럼 이걸 어떻게 구현할건데?
이때 쓰는거
<aside> 💡 레지스터들은 파티션에서 caller와 callee save로 나뉜다
그러면 이 값들이 연속성이 유지될려면 어쨌든 레지스터의 값은 어딘가에 저장되어야한다.
가기 전에 현재 위치를 저장해야하고 돌아오고 난 후 저장했던 저장위치를 불러와 원상복구해야한다

노랑 - sub함수를 부르기 전에 내가 현재 저장 위치를 저장해둘것이냐 초록 - sub함수가 호출되면 처음에 이전 위치를 저장하고 함수가 끝나고 원래장소로 돌아갈건지 정해야한다
이 두가지 방식이 있다는것이다. 이 두가지 방법을 파티션에서 정하는건데
왜 이러는거임?
레지스터는 한번에 전부 쓰지 않잖아? 그래서 현재위치 저장을 효율적으로 하기위해 sub함수가 저장하게 만들거나 main함수로 저장되도록 적절하게 설계하자
→ 저장하는 내용을 줄이기 위해
→ 저장,복귀 (시간이 걸리는 일)
→ procedure calls
→ 한정적인 저장공간의 효율성을 높이기 위서 caller 와 callee사이를 나눠서 사용하겠다
callee가 쓸 가능성이 높을 레지스터의 공간을 자신이 미리 저장하면 되는것이고
자신이 쓸 레지스터만 저장하고 함수가 끝나면 원래대로 돌려놓기만 하면 돼
</aside>
ggc로 컴파일한놈들끼리의 호환성을 위해 다음 규칙을 따름
| 4 | $ a0 |
caller saves |
만약 sub(a,b,c) 함수를 호출했다면 해당 a b c 인자는 내가 넣었으니, |
|---|---|---|---|
| 5 | $ a1 |
함수호출한놈(caller)측에서 저장해야겠지? | |
| 6 | $ a2 |
||
| 7 | $ a3 |
||
| 8 | $ t0 |
caller saves |
아, 이거 내가쓰던 레지스터니까 내가 저장해야겠구나… |
| ~ | |||
| 15 | $ t7 |
||
| 16 | $ s0 |
callee saves |
전역변수는 불려진놈도 사용하니까..? |
| ~ | 사용중에 변경이 있을 수 있으니, 사용후에 원래대로 되돌려두기 위해? | ||
| 23 | $ s7 |
