---
schema_version: 1
exam_id: "sose26-probeklausur"
aufgabe: 4
unit_id: "4a"
source_group_id: "4"
official_exam: true
official_solution: true
language: "ko"
---

# 4a — 다섯 ABI 위반 찾기

> **학습 목표:** 함수 호출 전후의 register lifetime과 stack invariant를 따라가며 공식 p21의 다섯 지적을 찾고, +14 항목은 독립 오류가 아니라 -16 교정과 연동된 수정임을 구분할 수 있다.
>
> **왜 따로 배우는가:** ABI 문제는 register 이름을 외우는 문제가 아니라 호출 경계에서 어떤 값이 살아남아야 하는지를 증명하는 문제입니다. 한 위반을 놓치면 이후 계산이 맞아도 함수 전체가 잘못됩니다.
>
> **범위:** Aufgabe 4 · 8점 Aufgabe의 최소 학습 단위 · 시험 p9 · 공식 해설 p21–22

## 1. 문제 원문 (Deutsch)

이 unit은 공식 Teilaufgabe 또는 표의 한 행·한 access를 학습 가능한 최소 단위로 다시 나눈 것입니다. 아래 전사는 source group `4`의 공식 독일어 문제 원문이며, 페이지 이미지를 바로 뒤에 함께 두어 코드·표·도식을 대조할 수 있게 했습니다.

~~~text
Aufgabe 4: Fehler identifizieren und korrigieren

Gegeben ist eine Funktion in C, sowie ihre Übersetzung in Assemblersprache.

int magicBox(int a, int b) {
    int c = a + 10;
    int d = helper(b, c);
    return d + a;
}

magicBox:
    addi sp, sp, -14
    sw ra, 0(sp)
    mv t0, a0
    addi s1, a0, 10
    mv a0, a1
    mv a1, s1
    jal ra, helper
    add a1, a0, t0
    lw ra, 0(sp)
    addi sp, sp, 14
    ret

Beantworten Sie die folgenden Fragen im Kontext der RISC-V Architektur:

a) Nennen Sie alle Konventionen, gegen die die Übersetzung des C-Codes verstößt.

b) Übersetzen Sie diese Funktion korrekt.

Gehen Sie davon aus, dass die Funktion helper bereits existiert und sich an die RISC-V-Aufrufkonventionen hält.

Lösung:
~~~

![공식 시험 원문 — exam-p09.png](../../assets/exam-p09.png)

*공식 시험 원문: `exam-p09.png` · Probeklausur.pdf · PDF p.9*

### 이 unit에서 풀 항목

잘못된 magicBox에서 모든 convention 위반을 찾고 공식 지적을 독립 검산하세요.

## 2. 쉬운 한국어 해석

문제 4: 오류 식별 및 수정

C로 작성된 함수와 이 함수를 어셈블리 언어로 번역한 코드가 주어져 있다.

int magicBox(int a, int b) {
    int c = a + 10;
    int d = helper(b, c);
    return d + a;
}

magicBox:
    addi sp, sp, -14
    sw ra, 0(sp)
    mv t0, a0
    addi s1, a0, 10
    mv a0, a1
    mv a1, s1
    jal ra, helper
    add a1, a0, t0
    lw ra, 0(sp)
    addi sp, sp, 14
    ret

RISC-V 아키텍처의 맥락에서 다음 질문에 답하시오.

a) 이 C 코드의 번역이 위반하는 모든 규약을 쓰시오.

b) 이 함수를 올바르게 번역하시오.

함수 helper는 이미 존재하며 RISC-V 호출 규약을 준수한다고 가정한다.

답안:

### 이 unit에 해당하는 최소 작업

잘못된 magicBox에서 모든 convention 위반을 찾고 공식 지적을 독립 검산하세요.

이 문제에서 최종 결과만 맞히는 것보다 중요한 것은 `4a`에 필요한 중간 판단을 답안지에 남기는 것입니다.

## 3. 무엇을 묻는 문제인가

### 공식 문제의 요구사항

- 주어진 잘못된 어셈블리에서 위반한 RISC-V 호출 규약을 모두 식별한다.
- 각 위반을 수정하여 magicBox의 C 의미와 RISC-V ABI를 모두 만족하는 완성 어셈블리 코드를 작성한다.

### 조건과 제약

- helper는 이미 구현되어 있고 RISC-V 호출 규약을 지킨다.
- 오류 분석과 수정은 RISC-V Architektur 및 Aufrufkonventionen을 기준으로 한다.
- 주어진 -14 stack 조정, t0와 s1 사용, helper 호출 뒤 값 보존, 반환 레지스터를 원문 그대로 검사해야 하며 문제 코드를 먼저 고쳐 적어서는 안 된다.

### 원문 오탈자·도식 관련 주의

- 시험지에서는 C 코드와 어셈블리 코드가 좌우 두 열로 배치되어 있다. original_de에서는 내용 손실 없이 두 코드 블록을 순서대로 직렬화했다.
- addi sp, sp, -14와 addi sp, sp, 14는 의도적으로 포함된 오류이므로 수정하지 않고 원문에 보존했다.
- PDF 텍스트 계층의 'identiﬁzieren' ligature는 시각적으로 확인한 표준 철자 'identifizieren'으로만 정규화했다.

### 도식 시각 확인 상태

- **도식 의존 여부:** 이 최소 unit의 핵심 판정은 텍스트·수식·코드로 재현할 수 있습니다.
- **공식 페이지 상태:** exam-p09.png, solution-p21.png, solution-p22.png가 원문 대조용으로 렌더되어 연결되어 있습니다.

### 이 unit의 학습 목표

- **관찰 가능한 목표:** 함수 호출 전후의 register lifetime과 stack invariant를 따라가며 공식 p21의 다섯 지적을 찾고, +14 항목은 독립 오류가 아니라 -16 교정과 연동된 수정임을 구분할 수 있다.
- **출제 의도:** ABI 문제는 register 이름을 외우는 문제가 아니라 호출 경계에서 어떤 값이 살아남아야 하는지를 증명하는 문제입니다. 한 위반을 놓치면 이후 계산이 맞아도 함수 전체가 잘못됩니다.
- **공식 근거 범위:** Probeklausur.pdf 시험 p9의 magicBox 오류 code와 Probeklausur Musterlösung und Hinweise.pdf 공식 해설 p21 Teilaufgabe a, ABI 설명 p22.
- **Aufgabe 공통 선수지식:** 함수 호출 전후를 경계로 봅니다. 호출 뒤에도 필요한 a는 caller-saved t-register가 아니라 보존된 s-register/stack에 있어야 하며, callee가 s-register를 쓰면 원래 값을 돌려줘야 합니다.

## 4. 선수 개념과 핵심 용어

### caller-saved

- **뜻:** 호출한 함수가 필요하면 호출 전에 직접 보호해야 하는 register 분류입니다.
- **이 문제에서:** helper 호출 뒤에도 필요한 a를 t0에만 두면 안 되는 이유를 설명할 때 사용합니다.

### callee-saved

- **뜻:** 호출받은 함수가 사용했다면 반환 전에 원래 값을 복원해야 하는 register 분류입니다.
- **이 문제에서:** magicBox가 s1을 쓰면서 save/restore하지 않은 오류를 찾을 때 사용합니다.

### stack alignment

- **뜻:** 함수 호출 경계에서 sp가 요구되는 byte 배수에 맞는 상태입니다.
- **이 문제에서:** 14 Byte frame이 아니라 16 Byte frame이 필요한 이유를 판정할 때 사용합니다.

### return register

- **뜻:** RISC-V ABI에서 함수 결과를 호출자에게 전달하는 a0입니다.
- **이 문제에서:** 계산 결과를 a1에 둔 마지막 오류를 식별할 때 사용합니다.

### 이 문제에 적용할 풀이 규칙

### 규칙 1. 호출 경계 생존 규칙

호출 전에 존재하고 호출 뒤에도 필요한 값이 caller-saved register에만 있으면 callee가 덮어쓸 수 있으므로 안전하지 않습니다.

- **시험지에 남길 것:** 각 값 옆에 live-after-call 여부와 현재 보관 register를 적고, 보호되지 않은 교집합을 표시합니다.

### 규칙 2. Prolog-Epilog 역연산 규칙

Prolog에서 만든 frame 크기, 저장 offset, 저장 register는 Epilog에서 정확히 반대로 복원되어야 하며 호출 경계의 sp는 16 Byte 정렬이어야 합니다.

- **시험지에 남길 것:** Prolog와 Epilog를 두 열에 나란히 쓰고 sp 변화와 save/load 쌍을 선으로 연결합니다.

### 규칙 3. ABI 반환 위치 규칙

정수 반환값은 함수 종료 시 a0에 있어야 호출자가 정해진 위치에서 값을 읽을 수 있습니다.

- **시험지에 남길 것:** ret 직전의 a0를 마지막으로 추적하고 실제 계산 결과가 그곳에 있는지 확인합니다.

### 공식 문제 전에 푸는 작은 유사 예제

**문제:** 함수 demo가 sp를 12 Byte 줄이고, s2를 저장하지 않은 채 사용하며, leaf 호출 뒤에도 필요한 값을 t1에만 둔 뒤 결과를 a1에 놓고 반환한다. 위반을 분류하세요.

**주어진 것**

- 호출 경계에서 stack은 16 Byte 정렬을 요구합니다.
- t1은 caller-saved이고 s2는 callee-saved입니다.
- 정수 반환값 위치는 a0입니다.

### 예제 단계 1. sp 변화 -12를 16 Byte 정렬 조건과 비교합니다.

- **왜:** frame 크기가 호출 경계의 ABI invariant를 깨는지 먼저 분리해야 합니다.
- **종이에:** -12 mod 16 ≠ 0, alignment 위반

### 예제 단계 2. 호출 뒤에도 필요한 값을 t1에 둔 사실과 s2의 save/restore 유무를 각각 검사합니다.

- **왜:** caller-saved 생존 오류와 callee-saved 복원 오류는 서로 다른 위반입니다.
- **종이에:** t1: live-after-call이지만 보호 없음; s2: 사용했지만 원값 저장 없음

### 예제 단계 3. ret 직전 결과 register를 확인합니다.

- **왜:** 내부 계산이 맞아도 ABI가 정한 반환 위치가 아니면 호출자는 결과를 받지 못합니다.
- **종이에:** 결과 a1 → a0로 수정

**예제 정답:** stack alignment, caller-saved 값 보호, callee-saved s2 보존, 반환값 a0의 네 범주에서 위반이 있습니다.

**독립 검산:** 각 지적이 alignment, lifetime, preservation, return 중 하나에 정확히 대응하고 같은 오류를 중복 계산하지 않았는지 확인합니다.

## 5. 공식 정답 요약

**공식 결론:** 공식 p21은 ① `addi sp,sp,-14`의 alignment 위반, ② a를 caller-saved t0에만 둠, ③ s1 미보존, ④ `addi sp,sp,14`, ⑤ 결과를 a1에 씀을 다섯 오류로 지적합니다. ①은 16-byte ABI alignment를 깨고 새 sp를 4-byte boundary에서도 벗어나게 해 `sw/lw ra,0(sp)`를 misaligned로 만듭니다. 독립 검산상 ①②③⑤는 실제 root 오류입니다. 원본의 -14와 +14는 서로 상쇄하므로 ④는 단독 복원 오류라기보다 ①을 -16으로 교정할 때 반드시 +16으로 함께 바꿔야 한다는 연동 수정입니다.

### 시험지 문장별 정답 해설

아래는 시험지의 항목 순서를 그대로 유지합니다. 각 항목에서 원문 → 한국어 번역 → 정답 → 판단 근거 → 실제로 쓸 답을 바로 이어서 읽으세요.



### 현재 소문제의 요구·판단·답을 한 흐름으로 연결

### `4a`에서 정확히 답할 대상

- **시험지가 요구하는 답:** 잘못된 magicBox에서 모든 convention 위반을 찾고 공식 지적을 독립 검산하세요.
- **이 소문제의 공식 답:** 공식 p21은 ① `addi sp,sp,-14`의 alignment 위반, ② a를 caller-saved t0에만 둠, ③ s1 미보존, ④ `addi sp,sp,14`, ⑤ 결과를 a1에 씀을 다섯 오류로 지적합니다. ①은 16-byte ABI alignment를 깨고 새 sp를 4-byte boundary에서도 벗어나게 해 `sw/lw ra,0(sp)`를 misaligned로 만듭니다. 독립 검산상 ①②③⑤는 실제 root 오류입니다. 원본의 -14와 +14는 서로 상쇄하므로 ④는 단독 복원 오류라기보다 ①을 -16으로 교정할 때 반드시 +16으로 함께 바꿔야 한다는 연동 수정입니다.

### 판단 1. sp 변화가 4-byte word 정렬과 16-byte ABI 정렬을 모두 만족하는지 봅니다.

- **왜:** 진입 sp가 16-byte aligned라면 -14 뒤 새 sp는 4의 배수도 아니므로 `sw/lw ra,0(sp)`가 word-misaligned이고, 호출 경계의 16-byte ABI invariant도 깨집니다.
- **이 판단에서 답안지에 남길 것:** 새 sp mod 16=2, 따라서 mod 4=2; frame은 -16으로 교정한다고 적습니다.

### 판단 2. helper 뒤에도 쓰는 값이 t/a에만 남았는지 봅니다.

- **왜:** t0는 caller-saved라 helper가 자유롭게 덮어쓸 수 있으므로 원래 a를 호출 뒤 계산에 사용할 수 없습니다.
- **이 판단에서 답안지에 남길 것:** a 값의 lifetime을 helper 전→후 화살표로 그리고 t0 옆에 보호 없음이라고 적습니다.

### 판단 3. 사용한 s-register를 save/restore했는지 봅니다.

- **왜:** s1은 callee-saved이므로 magicBox가 변경했다면 호출자에게 돌아가기 전에 기존 s1을 되돌려야 합니다.
- **이 판단에서 답안지에 남길 것:** s1 사용 line과 누락된 sw/lw s1 쌍을 표시합니다.

### 판단 4. 원본 -14/+14의 원상복구와 교정안 -16/+16을 구분합니다.

- **왜:** 원본 두 명령의 합은 0이므로 sp 자체는 복구됩니다. 공식 해설의 +14 지적은 잘못된 -14 frame을 -16으로 고친 뒤 epilog도 +16으로 바꾸어야 한다는 연동 수정으로 읽어야 합니다.
- **이 판단에서 답안지에 남길 것:** 원본: -14+14=0(복구 O, alignment X). 교정: -16+16=0(복구 O, alignment O)를 나란히 적습니다.

### 판단 5. C return 값이 a0에 놓였는지 봅니다.

- **왜:** RISC-V 정수 반환값은 a0로 전달되므로 a1의 결과는 호출자가 표준 방식으로 받을 수 없습니다.
- **이 판단에서 답안지에 남길 것:** ret 직전 a0와 a1의 값을 써서 결과가 a1에 잘못 놓였음을 표시합니다.

### 위 판단이 최종 답으로 이어지는 이유

Stack frame, caller-saved 생존성, callee-saved 복원, return register를 각각 독립 checklist로 검사합니다. 진입 sp가 16-byte aligned라면 -14 뒤 sp는 4의 배수조차 아니어서 `sw/lw ra,0(sp)`도 word-misaligned입니다. 공식 p21은 +14도 별도 오류로 세지만, 원본 -14/+14는 산술적으로 sp를 원상복구하므로 이는 frame을 -16으로 고친 뒤 epilog도 +16이어야 한다는 연동 수정입니다.

### 답안 작성 시 주의

공식 해설의 다섯 항목을 그대로 제시하되, +14는 원본에서 -14를 되돌리며 교정된 -16 frame과 짝지을 때만 +16으로 바뀐다는 점을 숨기지 마세요.

![공식 Musterlösung/Hinweise — solution-p21.png](../../assets/solution-p21.png)

*공식 Musterlösung/Hinweise: `solution-p21.png` · Probeklausur Musterlösung und Hinweise.pdf · PDF p.21*

![공식 Musterlösung/Hinweise — solution-p22.png](../../assets/solution-p22.png)

*공식 Musterlösung/Hinweise: `solution-p22.png` · Probeklausur Musterlösung und Hinweise.pdf · PDF p.22*

## 6. 풀이 전략

1. sp 변화가 4/16의 배수 조건을 모두 만족하는지 봅니다.
2. helper 뒤에도 쓰는 값이 t/a에만 남았는지 봅니다.
3. 사용한 s-register를 save/restore했는지 봅니다.
4. 원본 -14/+14의 원상복구와 교정안 -16/+16을 구분합니다.
5. C return 값이 a0에 놓였는지 봅니다.

## 7. 단계별 상세 풀이

### 단계 1. sp 변화가 4-byte word 정렬과 16-byte ABI 정렬을 모두 만족하는지 봅니다.

- **이유:** 진입 sp가 16-byte aligned라면 -14 뒤 새 sp는 4의 배수도 아니므로 `sw/lw ra,0(sp)`가 word-misaligned이고, 호출 경계의 16-byte ABI invariant도 깨집니다.
- **종이에 남길 것:** 새 sp mod 16=2, 따라서 mod 4=2; frame은 -16으로 교정한다고 적습니다.
- **완료 기준:** 공식 p21의 4-byte 지적과 실제 ABI의 16-byte 규칙을 모두 설명할 수 있습니다.
- **막힐 때 힌트:** 저장한 word 수가 아니라 호출 시점의 sp mod 16을 확인하세요.
- **가장 흔한 첫 오류:** 14가 짝수이거나 4보다 크다는 이유로 정렬됐다고 판정합니다.

### 단계 2. helper 뒤에도 쓰는 값이 t/a에만 남았는지 봅니다.

- **이유:** t0는 caller-saved라 helper가 자유롭게 덮어쓸 수 있으므로 원래 a를 호출 뒤 계산에 사용할 수 없습니다.
- **종이에 남길 것:** a 값의 lifetime을 helper 전→후 화살표로 그리고 t0 옆에 보호 없음이라고 적습니다.
- **완료 기준:** 어느 값이 어느 line 이후에도 필요한지와 왜 t0만으로 부족한지 말할 수 있습니다.
- **막힐 때 힌트:** helper 호출 다음의 add가 어떤 원래 값을 다시 읽는지 찾으세요.
- **가장 흔한 첫 오류:** t0에 값을 옮겼으므로 자동으로 보존된다고 생각합니다.

### 단계 3. 사용한 s-register를 save/restore했는지 봅니다.

- **이유:** s1은 callee-saved이므로 magicBox가 변경했다면 호출자에게 돌아가기 전에 기존 s1을 되돌려야 합니다.
- **종이에 남길 것:** s1 사용 line과 누락된 sw/lw s1 쌍을 표시합니다.
- **완료 기준:** callee-saved 책임의 주체가 magicBox임을 설명할 수 있습니다.
- **막힐 때 힌트:** ra만 저장되어 있다고 ABI 보존이 끝난 것은 아닙니다.
- **가장 흔한 첫 오류:** s-register는 안전한 register이므로 저장 없이 마음대로 써도 된다고 해석합니다.

### 단계 4. 원본 -14/+14의 원상복구와 교정안 -16/+16을 구분합니다.

- **이유:** 원본 두 명령의 합은 0이므로 sp 자체는 복구됩니다. 공식 해설의 +14 지적은 잘못된 -14 frame을 -16으로 고친 뒤 epilog도 +16으로 바꾸어야 한다는 연동 수정으로 읽어야 합니다.
- **종이에 남길 것:** 원본: -14+14=0(복구 O, alignment X). 교정: -16+16=0(복구 O, alignment O)를 나란히 적습니다.
- **완료 기준:** stack 원상복구와 16-byte alignment라는 두 조건을 따로 판정하고 공식의 다섯 번째 세기 방식을 설명합니다.
- **막힐 때 힌트:** '합이 0인가?'와 '호출 시 sp mod 16=0인가?'를 서로 다른 줄에서 검사하세요.
- **가장 흔한 첫 오류:** +14 자체가 원본 -14를 되돌리지 못한다고 말하거나, 반대로 원상복구만 보고 alignment 위반까지 없다고 결론냅니다.

### 단계 5. C return 값이 a0에 놓였는지 봅니다.

- **이유:** RISC-V 정수 반환값은 a0로 전달되므로 a1의 결과는 호출자가 표준 방식으로 받을 수 없습니다.
- **종이에 남길 것:** ret 직전 a0와 a1의 값을 써서 결과가 a1에 잘못 놓였음을 표시합니다.
- **완료 기준:** 최종 계산 결과를 a0로 옮겨야 한다는 수정까지 제시합니다.
- **막힐 때 힌트:** 함수 argument register와 return register가 겹치지만 반환은 첫 번째인 a0입니다.
- **가장 흔한 첫 오류:** a-register이면 어느 것이든 반환값으로 사용할 수 있다고 생각합니다.

### 잘못된 code의 line별 ABI 감사

- `addi sp,sp,-14`: 16-byte stack alignment 위반
- `mv t0,a0`: `helper` 호출 뒤에도 필요한 `a`를 caller-saved `t0`에만 둠
- `addi s1,a0,10`: 기존 `s1` 값을 save/restore하지 않음
- `add a1,a0,t0`: 함수 반환값을 `a0`가 아니라 `a1`에 둠
- `addi sp,sp,14`: 공식은 별도 항목으로 지적하지만 원본 `-14`는 산술적으로 복원합니다. prolog를 `-16`으로 고치면 epilog도 `+16`으로 바꿔야 하는 연동 수정입니다.

## 8. 문제와 공식 해설의 비교·검증

- **문제가 요구하는 것:** 잘못된 magicBox에서 모든 convention 위반을 찾고 공식 지적을 독립 검산하세요.
- **공식 해설이 제시하는 결론:** 공식 p21은 ① `addi sp,sp,-14`의 alignment 위반, ② a를 caller-saved t0에만 둠, ③ s1 미보존, ④ `addi sp,sp,14`, ⑤ 결과를 a1에 씀을 다섯 오류로 지적합니다. ①은 16-byte ABI alignment를 깨고 새 sp를 4-byte boundary에서도 벗어나게 해 `sw/lw ra,0(sp)`를 misaligned로 만듭니다. 독립 검산상 ①②③⑤는 실제 root 오류입니다. 원본의 -14와 +14는 서로 상쇄하므로 ④는 단독 복원 오류라기보다 ①을 -16으로 교정할 때 반드시 +16으로 함께 바꿔야 한다는 연동 수정입니다.
- **결론을 재현하는 핵심 논리:** Stack frame, caller-saved 생존성, callee-saved 복원, return register를 각각 독립 checklist로 검사합니다. 진입 sp가 16-byte aligned라면 -14 뒤 sp는 4의 배수조차 아니어서 `sw/lw ra,0(sp)`도 word-misaligned입니다. 공식 p21은 +14도 별도 오류로 세지만, 원본 -14/+14는 산술적으로 sp를 원상복구하므로 이는 frame을 -16으로 고친 뒤 epilog도 +16이어야 한다는 연동 수정입니다.
- **검증 방법:** 위 micro-step의 `종이에 남길 것`을 순서대로 만들고 각 `완료 기준`을 확인합니다. 최종 산출물이 공식 결론과 같은지 대조합니다.
- **전제와 주의 범위:** 공식 해설의 다섯 항목을 그대로 제시하되, +14는 원본에서 -14를 되돌리며 교정된 -16 frame과 짝지을 때만 +16으로 바뀐다는 점을 숨기지 마세요.
- **채택할 시험 답:** 이 가이드에서는 공식 Musterlösung의 결론을 시험 답으로 유지하며, 일반 ISA 또는 다른 구현과 달라질 수 있는 부분은 위 전제와 주의 범위에서 분리합니다.

## 9. 시험장에서 쓸 최종 답안

공식 p21은 ① `addi sp,sp,-14`의 alignment 위반, ② a를 caller-saved t0에만 둠, ③ s1 미보존, ④ `addi sp,sp,14`, ⑤ 결과를 a1에 씀을 다섯 오류로 지적합니다. ①은 16-byte ABI alignment를 깨고 새 sp를 4-byte boundary에서도 벗어나게 해 `sw/lw ra,0(sp)`를 misaligned로 만듭니다. 독립 검산상 ①②③⑤는 실제 root 오류입니다. 원본의 -14와 +14는 서로 상쇄하므로 ④는 단독 복원 오류라기보다 ①을 -16으로 교정할 때 반드시 +16으로 함께 바꿔야 한다는 연동 수정입니다.

답안지에는 결과만 쓰지 말고, 7절의 중간 산출물 가운데 판정을 증명하는 식·bit field·register 상태·cycle·cache 상태를 함께 남기세요.

## 10. 자주 하는 실수와 검산 체크리스트

### 대표 실수

- 공식 해설의 다섯 항목을 그대로 제시하되, +14는 원본에서 -14를 되돌리며 교정된 -16 frame과 짝지을 때만 +16으로 바뀐다는 점을 숨기지 마세요.
- 14가 짝수이거나 4보다 크다는 이유로 정렬됐다고 판정합니다.
- t0에 값을 옮겼으므로 자동으로 보존된다고 생각합니다.
- s-register는 안전한 register이므로 저장 없이 마음대로 써도 된다고 해석합니다.
- +14 자체가 원본 -14를 되돌리지 못한다고 말하거나, 반대로 원상복구만 보고 alignment 위반까지 없다고 결론냅니다.
- a-register이면 어느 것이든 반환값으로 사용할 수 있다고 생각합니다.

### 빠른 self-check

- **회상 질문:** 원본 -14/+14와 교정안 -16/+16에서 각각 sp가 원상복구되는지와 4/16-byte alignment가 맞는지를 구분해 설명하세요.
- [ ] 공식의 다섯 지적을 재현하되 +14 항목은 독립적인 원상복구 실패가 아니라 -16/+16 교정의 연동 항목이라고 설명할 수 있다.
- [ ] helper 호출 직전과 직후의 a, t0, s1, sp 상태를 표로 적을 수 있다.

## 11. 짧은 확인 문제와 전이 연습

### 개념 재구성

**문제:** 함수 호출을 포함하는 RISC-V 함수를 감사할 때 사용할 네 범주 checklist를 기억에서 재구성하세요.

**힌트:** sp, 호출 전후 값, s-register, ret 직전 값을 차례로 보세요.

<details>
<summary>정답과 채점 기준 보기</summary>

**모범 답:** stack alignment와 복원, caller-saved 값의 호출 전 보호, 사용한 callee-saved register의 save/restore, 반환값 a0를 검사합니다.

**채점 기준**
  - stack|sp
  - caller-saved|호출 전 보호
  - callee-saved|save/restore
  - a0|반환값

</details>

### 변형 문제

**문제:** frame을 24 Byte 줄인 함수가 s2를 저장하지 않고 사용하며, 다른 함수를 부른 뒤 t3의 이전 값을 다시 읽습니다. 반환값은 a0에 있습니다. 독립 위반을 모두 쓰세요.

**힌트:** 24 mod 16, s2의 분류, t3의 분류를 각각 검사하세요.

<details>
<summary>정답과 채점 기준 보기</summary>

**모범 답:** 24 Byte frame은 16 Byte 정렬을 깨고, s2는 callee-saved인데 보존되지 않았으며, 호출 뒤 필요한 t3는 caller-saved인데 보호되지 않았습니다. 반환 위치 a0는 맞습니다.

**채점 기준**
  - 24|정렬
  - s2|callee-saved
  - t3|caller-saved
  - a0는 맞습니다

</details>

### 오답 진단

**문제:** 학생이 'prolog -14와 epilog +14의 합이 0이므로 stack 관련 오류는 없다'고 답했습니다. 첫 오류를 고치세요.

**힌트:** 원상복구와 호출 경계 정렬은 별도 조건입니다.

<details>
<summary>정답과 채점 기준 보기</summary>

**모범 답:** 합이 0이라 sp 값은 돌아올 수 있어도 -14 frame은 16 Byte alignment를 위반합니다. 공식 교정은 -16/+16입니다.

**채점 기준**
  - 16 Byte|16-byte
  - alignment|정렬
  - -16/+16

</details>

## 12. 근거 자료

- `[문제 출처] current:Probeklausur.pdf` — 시험 p9 · 공식 해설 p21–22
- `[공식 해설] current:Probeklausur Musterlösung und Hinweise.pdf` — 시험 p9 · 공식 해설 p21–22
- `[정확한 원문 group] 4` — 시험 p.9 · 공식 해설 p.21, p.22
- `[소문항 범위] Probeklausur.pdf 시험 p9의 magicBox 오류 code와 Probeklausur Musterlösung und Hinweise.pdf 공식 해설 p21 Teilaufgabe a, ABI 설명 p22.`
- `[개념 근거 · file-level] current:Vorlesung/Rechnerorganisation - Teil 1.pdf` — RISC-V function call과 ABI
- `[개념 근거 · file-level] current:Uebung/Übung 3 Musterlösung.pdf` — callee/caller-saved register와 stack
- `[개념 근거 · file-level] current:Uebung/RISC-V Reference.pdf` — register convention과 pseudoinstruction

### 이 파일에서 직접 대조한 공식 이미지

- `exam-p09.png` — Probeklausur.pdf · PDF p.9
- `solution-p21.png` — Probeklausur Musterlösung und Hinweise.pdf · PDF p.21
- `solution-p22.png` — Probeklausur Musterlösung und Hinweise.pdf · PDF p.22

정확한 강의 슬라이드 한 페이지를 확정하지 못한 개념 자료는 `file-level`로 표시했습니다. 페이지 번호를 추측해서 만들지 않았습니다.
