교재처럼 순서대로 읽는 본문
이 글은 요약 카드가 아닙니다. 처음 보는 용어의 뜻부터 시작해, 왜 그런 규칙이 생겼는지와 문제에서 어떻게 사용하는지를 한 흐름으로 설명합니다.
이 장을 공부하는 이유
코드를 보며 규칙 이름을 떠올리는 대신 ‘helper 호출을 건너 살아남아야 하는 값은 무엇인가?’를 표시하면 대부분의 오류가 드러납니다.
읽고 나면 할 수 있어야 하는 것
- 함수 호출 전후 살아야 하는 값을 표시한다.
- caller-saved와 callee-saved 위반을 구분한다.
- 정렬된 stack frame과 올바른 return register를 만든다.
먼저 비유로 머릿속 구조 만들기
호텔 객실을 빌린다고 생각하면 됩니다. t/a register는 공용 탁자라 다음 손님(helper)이 치워도 되고, s-register는 사용했다면 원래 배치로 돌려놔야 합니다. stack frame은 내 물건을 잠깐 보관하는 잠금 사물함입니다.
그림은 왼쪽에서 오른쪽으로 읽습니다. 각 화살표는 앞 단계의 결과가 다음 단계의 입력이 된다는 뜻입니다. 흐름도만 크게 열기
용어를 평범한 문장으로 바꾸기
독일어와 영어 용어를 소리만 외우지 말고, 아래 설명을 자신의 말로 다시 말해 보세요.
- live across call
- 함수 호출 전의 값이 호출 후에도 필요한 상태
- caller-saved
- 호출자가 필요하면 스스로 저장해야 하는 t/a register
- callee-saved
- callee가 사용하면 원래 값을 복원해야 하는 s register
- return value
- RV32 ABI에서 보통 a0로 돌려주는 결과
- stack alignment
- 호출 경계에서 sp를 16 Byte 배수로 유지하는 규칙
개념을 처음부터 연결하기
1. 왜 t0가 위험한가
caller-saved라는 말은 helper가 t0를 보존해 준다는 약속이 없다는 뜻입니다. 현재 함수가 호출 후에도 a를 더해야 하므로 a는 호출 전에 안전한 곳에 저장해야 합니다.
2. 왜 s1도 그냥 쓰면 안 되는가
s1은 오래 보관하기 좋지만, 현재 함수가 들어오기 전 caller가 갖고 있던 s1 값을 보존해야 합니다. stack에 s1을 저장하고 return 전에 복원해야 합니다.
3. sp와 결과 register
-14는 4-byte word 저장에도 부자연스럽고 16-byte alignment를 깨뜨립니다. 결과는 C의 return value이므로 마지막 합을 a0에 둬야 합니다.
이 챕터에서 계속 사용할 손풀이 표
아래 표는 정답표가 아니라 작업 기억을 외부에 꺼내 놓는 worksheet입니다. 소문제를 풀 때마다 빈 칸을 직접 채우세요.
| 검사 대상 | 질문 | 정상 조건 |
|---|---|---|
| sp | frame 크기는? | 호출 경계에서 16-byte aligned |
| ra | 다른 함수를 부르는가? | 필요하면 save/restore |
| t/a | call 뒤에도 값이 필요한가? | caller가 보호 |
| s-register | 이 함수가 사용했는가? | callee가 원값 복원 |
| return | 최종 값은 어디인가? | a0 |
수식은 위아래 구조로 읽기
평문으로 제곱과 분수를 이어 쓰면 구조를 놓치기 쉽습니다. 아래 수식은 브라우저의 MathML로 렌더되며, 지수·아래첨자·분수를 실제 수학 표기처럼 보여 줍니다.
보존해야 할 값의 조건
호출 전에 존재하고 호출 뒤에도 필요한 값은 stack 또는 보존 규칙이 있는 register로 지켜야 합니다.
stack 정렬
prolog에서 줄인 크기와 epilog에서 되돌리는 크기는 정확히 같아야 합니다.
작은 숫자로 한 번 직접 해보기
`f(a){ x=g(); return x+a; }`에서 a는 g 호출을 가로질러 살아야 합니다. `mv t0,a0; jal g; add a0,a0,t0`는 g가 t0를 바꾸면 틀립니다. a를 stack이나 보존된 s-register에 둡니다.
이 예제에서 중요한 것은 숫자 자체가 아니라, 어떤 값을 먼저 구하고 그 결과를 다음 계산에 넣는지입니다. 종이에 중간값을 생략하지 않고 적어 보세요.
초보자가 자주 멈추는 지점
s-register를 쓰면 자동으로 안전한가요?
helper로부터 현재 값을 지키는 데는 유용하지만, 현재 함수도 caller에게는 callee입니다. s-register의 입장 전 원래 값을 stack에 저장하고 나갈 때 복원해야 안전합니다.
왜 14 Byte만 필요해 보여도 16 Byte를 잡나요?
개별 저장 공간 합계와 ABI의 stack alignment는 다른 조건입니다. 함수 호출 경계에서 sp가 16 Byte 정렬을 유지하도록 frame 크기를 올림합니다.
helper 결과는 어디에 있나요?
호출 직후 helper의 return value는 a0에 있습니다. 원래 a도 다시 필요하므로 보호해 둔 a와 새 a0를 더하고, 최종 결과 역시 a0에 남겨야 합니다.
시험지에서 손으로 쓰는 순서
- 각 값을 ‘호출 전만 필요 / 호출 후도 필요’로 표시합니다.
- jal 때문에 ra를 저장해야 하는지 확인합니다.
- 호출 후 필요한 caller-saved 값을 보호합니다.
- 사용한 s-register의 원래 값을 저장·복원합니다.
- sp 변화량, load/store offset, return a0를 마지막에 대칭 검산합니다.
이 순서를 외우는 목적은 답을 암기하는 것이 아닙니다. 중간 과정을 답안지에 남겨 부분점수를 얻고, 어디에서 잘못됐는지 스스로 찾기 위한 체크포인트입니다.
2개 소문제로 개념 적용하기
각 소문제에는 이 장의 설명을 다시 포함한 독립 수업 페이지가 있습니다. 따라서 링크로 바로 들어가도 선행지식 없이 읽을 수 있습니다.
- 4a다섯 ABI 위반 찾기독립 수업 열기 →
잘못된 magicBox에서 모든 convention 위반을 찾으세요. · 5 micro-work
- 4b올바른 magicBox 재작성독립 수업 열기 →
공식 ABI를 지키는 code를 완성하세요. · 6 micro-work
출처
Source: Probeklausur.pdf / Probeklausur Musterlösung und Hinweise.pdf · 시험 p9 · 공식 해설 p21–22. 공식 답의 숫자와 course-specific datapath/FSM 가정은 변경하지 않았습니다.