Untitled

<aside> 💡 목차

</aside>

Week 2 Tutorial - Building an ALU

ALU , MUX , Full Adder , 각 기본 연산 등 자세히 설명

MIPS 레지스터의 Usage and Saving

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으로 돌아올 것이다.

Untitled

근데 이 sub함수는 main에서만 불러오는게 아니라, 다른곳, 여러곳에서도 불러올 수 있잖아?

돌아가는 위치를 sub 함수에 저장하면, another 이라는 함수에서 sub를 실행했을때, another로 돌아와야하는데, 엉뚱하게 main함수로 이동할 수도 있겠네?

Untitled

그래서 원래 실행되었던 함수로 돌아가기 위해 $ ra 가 필요했던 것이다

즉. caller 와 callee 문제는 바로 원래대로 돌아갈때, 돌아가는 위치를 main 에서 sub 수행전에 자신의 주소를 sub에게 알려줄지, 아니면 sub 자체가 자신이 실행한 주소를 저장하여 마지막 실행 분기점으로 갈 것인지 다루는 문제이다

</aside>

<aside> 💡 일반적으로 결과는 레지스터로 받는데, 이 레지스터들을 쓰기 위해서 이 레지스터들을 arguments나 temporary에서 시로 레지스터로 쓰고 return values로 출력을 하니 8~15까지 레지스터를 쓰고있었으면 이 레지스터의 값은 temporary 에 있긴 하지만,

return 하고 원래 함수로 되돌아 오더라도 값이 변하지않고 연속성을 지닌채 그대로있다고 기대하고있다

Untitled

기본 main()에선 이놈이 다른함수에서 뭘 하고 왔는지 알 수 없을것 아니냐

내가 쓰던값이 그대로 있다고 가정하고 프로그램이 돌아야한다

main(){
	int a = 1
	for( ... )
}

레지스터도 코드와 마찬가지로 함수를 호출하고 원래 자리로 돌아와도 이전 상태가 유지되는것을 기대한다

그럼 이걸 어떻게 구현할건데?

이때 쓰는거

<aside> 💡 레지스터들은 파티션에서 caller와 callee save로 나뉜다

그러면 이 값들이 연속성이 유지될려면 어쨌든 레지스터의 값은 어딘가에 저장되어야한다.

가기 전에 현재 위치를 저장해야하고 돌아오고 난 후 저장했던 저장위치를 불러와 원상복구해야한다

노랑 - sub함수를 부르기 전에 내가 현재 저장 위치를 저장해둘것이냐
초록 - sub함수가 호출되면 처음에 이전 위치를 저장하고 함수가 끝나고 원래장소로 돌아갈건지 정해야한다

노랑 - sub함수를 부르기 전에 내가 현재 저장 위치를 저장해둘것이냐 초록 - sub함수가 호출되면 처음에 이전 위치를 저장하고 함수가 끝나고 원래장소로 돌아갈건지 정해야한다

이 두가지 방식이 있다는것이다. 이 두가지 방법을 파티션에서 정하는건데

왜 이러는거임?

레지스터는 한번에 전부 쓰지 않잖아? 그래서 현재위치 저장을 효율적으로 하기위해 sub함수가 저장하게 만들거나 main함수로 저장되도록 적절하게 설계하자

→ 저장하는 내용을 줄이기 위해

→ 저장,복귀 (시간이 걸리는 일)

→ procedure calls

→ 한정적인 저장공간의 효율성을 높이기 위서 caller 와 callee사이를 나눠서 사용하겠다

caller 입장

callee가 쓸 가능성이 높을 레지스터의 공간을 자신이 미리 저장하면 되는것이고

callee 입장

자신이 쓸 레지스터만 저장하고 함수가 끝나면 원래대로 돌려놓기만 하면 돼

</aside>

→ GCC 레지스터 규칙

ggc로 컴파일한놈들끼리의 호환성을 위해 다음 규칙을 따름

→ → caller, callee는 어떻게 흘러가는지 간단 요약

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

Untitled

→ Caller & Callee (calling 규칙)

→ 실제 코드가 레지스터에서 컴파일링되는 과정

→ → $sp 스택 포인터 🔥🔥🔥

→ → 재귀함수