왜 이 소문제를 따로 배우는가
ABI 문제는 register 이름을 외우는 문제가 아니라 호출 경계에서 어떤 값이 살아남아야 하는지를 증명하는 문제입니다. 한 위반을 놓치면 이후 계산이 맞아도 함수 전체가 잘못됩니다.
이 페이지는 Aufgabe 4의 공통 템플릿이 아니라 4a 다섯 ABI 위반 찾기에 필요한 내용만 담습니다. 챕터 전체 배경이 필요하면 Aufgabe 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에 둔 마지막 오류를 식별할 때 사용합니다.
이 소문제 전용 규칙과 종이 작업
호출 경계 생존 규칙
호출 전에 존재하고 호출 뒤에도 필요한 값이 caller-saved register에만 있으면 callee가 덮어쓸 수 있으므로 안전하지 않습니다.
종이에: 각 값 옆에 live-after-call 여부와 현재 보관 register를 적고, 보호되지 않은 교집합을 표시합니다.
Prolog-Epilog 역연산 규칙
Prolog에서 만든 frame 크기, 저장 offset, 저장 register는 Epilog에서 정확히 반대로 복원되어야 하며 호출 경계의 sp는 16 Byte 정렬이어야 합니다.
종이에: Prolog와 Epilog를 두 열에 나란히 쓰고 sp 변화와 save/load 쌍을 선으로 연결합니다.
ABI 반환 위치 규칙
정수 반환값은 함수 종료 시 a0에 있어야 호출자가 정해진 위치에서 값을 읽을 수 있습니다.
종이에: ret 직전의 a0를 마지막으로 추적하고 실제 계산 결과가 그곳에 있는지 확인합니다.
Aufgabe 전체 흐름은 챕터 흐름도에서 확인할 수 있습니다. 여기서는 현재 판단에 직접 필요한 규칙만 적용합니다.
이 소문제 전용 작은 예제
함수 demo가 sp를 12 Byte 줄이고, s2를 저장하지 않은 채 사용하며, leaf 호출 뒤에도 필요한 값을 t1에만 둔 뒤 결과를 a1에 놓고 반환한다. 위반을 분류하세요.
주어진 것
- 호출 경계에서 stack은 16 Byte 정렬을 요구합니다.
- t1은 caller-saved이고 s2는 callee-saved입니다.
- 정수 반환값 위치는 a0입니다.
- sp 변화 -12를 16 Byte 정렬 조건과 비교합니다.
frame 크기가 호출 경계의 ABI invariant를 깨는지 먼저 분리해야 합니다.
종이 산출물: -12 mod 16 ≠ 0, alignment 위반
- 호출 뒤에도 필요한 값을 t1에 둔 사실과 s2의 save/restore 유무를 각각 검사합니다.
caller-saved 생존 오류와 callee-saved 복원 오류는 서로 다른 위반입니다.
종이 산출물: t1: live-after-call이지만 보호 없음; s2: 사용했지만 원값 저장 없음
- ret 직전 결과 register를 확인합니다.
내부 계산이 맞아도 ABI가 정한 반환 위치가 아니면 호출자는 결과를 받지 못합니다.
종이 산출물: 결과 a1 → a0로 수정
예제 답과 독립 검산 보기
stack alignment, caller-saved 값 보호, callee-saved s2 보존, 반환값 a0의 네 범주에서 위반이 있습니다.
독립 검산: 각 지적이 alignment, lifetime, preservation, return 중 하나에 정확히 대응하고 같은 오류를 중복 계산하지 않았는지 확인합니다.
잘못된 code를 line별로 감사하기
addi sp,sp,-14: 16-byte alignment 위반mv t0,a0: helper 호출 뒤에도 필요한 a를 caller-saved t0에만 둠addi s1,a0,10: s1의 기존 값을 save/restore하지 않음add a1,a0,t0: return value를 a0가 아닌 a1에 둠addi sp,sp,14: 잘못된 frame 크기를 그대로 복원
이제 실제 시험 문제를 micro-work로 풀기
공식 시험이 요구하는 것
잘못된 magicBox에서 모든 convention 위반을 찾으세요.
공식 답을 보기 전, 내 답 먼저 남기기
완성 문장이 아니어도 좋습니다. 중간값·register·cycle·cache state처럼 채점 가능한 흔적을 먼저 적으세요.
각 작업의 중간 산출물을 직접 적고 완료 조건을 만족한 뒤 체크하세요. 단계별 이유·산출물·오류가 현재 소문제에 맞게 따로 작성되어 있습니다.
sp 변화가 16의 배수인지 봅니다.
- 왜 하는가
- 공식 해설의 첫 오류는 -14 Byte frame이 호출 경계의 16 Byte 정렬을 깨는 것입니다.
- 종이 산출물
- prolog 옆에 -14 mod 16 ≠ 0과 필요한 frame -16을 적습니다.
- 완료 조건
- 현재 frame이 왜 정렬되지 않는지 나머지 계산으로 설명할 수 있습니다.
막혔을 때 단계 힌트·대표 오류
힌트: 저장한 word 수가 아니라 호출 시점의 sp mod 16을 확인하세요.
이 단계의 대표 오류: 14가 짝수이거나 4보다 크다는 이유로 정렬됐다고 판정합니다.
helper 뒤에도 쓰는 값이 t/a에만 남았는지 봅니다.
- 왜 하는가
- t0는 caller-saved라 helper가 자유롭게 덮어쓸 수 있으므로 원래 a를 호출 뒤 계산에 사용할 수 없습니다.
- 종이 산출물
- a 값의 lifetime을 helper 전→후 화살표로 그리고 t0 옆에 보호 없음이라고 적습니다.
- 완료 조건
- 어느 값이 어느 line 이후에도 필요한지와 왜 t0만으로 부족한지 말할 수 있습니다.
막혔을 때 단계 힌트·대표 오류
힌트: helper 호출 다음의 add가 어떤 원래 값을 다시 읽는지 찾으세요.
이 단계의 대표 오류: t0에 값을 옮겼으므로 자동으로 보존된다고 생각합니다.
사용한 s-register를 save/restore했는지 봅니다.
- 왜 하는가
- s1은 callee-saved이므로 magicBox가 변경했다면 호출자에게 돌아가기 전에 기존 s1을 되돌려야 합니다.
- 종이 산출물
- s1 사용 line과 누락된 sw/lw s1 쌍을 표시합니다.
- 완료 조건
- callee-saved 책임의 주체가 magicBox임을 설명할 수 있습니다.
막혔을 때 단계 힌트·대표 오류
힌트: ra만 저장되어 있다고 ABI 보존이 끝난 것은 아닙니다.
이 단계의 대표 오류: s-register는 안전한 register이므로 저장 없이 마음대로 써도 된다고 해석합니다.
prolog와 epilog의 sp 변화가 정확히 반대인지 봅니다.
- 왜 하는가
- 함수가 반환될 때 sp는 진입 전 값으로 돌아와야 하며 잘못된 14 Byte frame 자체도 16 Byte로 교정되어야 합니다.
- 종이 산출물
- prolog -14, epilog +14를 연결한 뒤 교정안 -16/+16을 나란히 적습니다.
- 완료 조건
- 단순히 부호만 반대인 것과 ABI에 맞는 frame 복원이 다른 문제임을 구분합니다.
막혔을 때 단계 힌트·대표 오류
힌트: 합이 0인지뿐 아니라 각각의 frame 크기가 정렬 조건을 만족하는지도 확인하세요.
이 단계의 대표 오류: -14와 +14가 상쇄되므로 오류가 없다고 판정합니다.
C return 값이 a0에 놓였는지 봅니다.
- 왜 하는가
- RISC-V 정수 반환값은 a0로 전달되므로 a1의 결과는 호출자가 표준 방식으로 받을 수 없습니다.
- 종이 산출물
- ret 직전 a0와 a1의 값을 써서 결과가 a1에 잘못 놓였음을 표시합니다.
- 완료 조건
- 최종 계산 결과를 a0로 옮겨야 한다는 수정까지 제시합니다.
막혔을 때 단계 힌트·대표 오류
힌트: 함수 argument register와 return register가 겹치지만 반환은 첫 번째인 a0입니다.
이 단계의 대표 오류: a-register이면 어느 것이든 반환값으로 사용할 수 있다고 생각합니다.
공식 답을 열기 전 마지막 회상
helper가 t0를 자유롭게 덮어써도 되는 이유는 무엇인가요?
내 풀이 후 공식 결론·이유·대표 함정 확인
공식 결론
오류: -14 alignment, a를 t0에만 보존, s1 미보존, +14 복원, 결과를 a1에 씀. 공식 해설은 5개를 지적합니다.
왜 이 답이 되는가
Stack frame, caller-saved 생존성, callee-saved 복원, return register를 각각 독립 checklist로 검사합니다.
대표 함정
ra만 저장했다고 호출 규약이 끝난 것이 아닙니다. 값의 lifetime과 register class를 함께 봅니다.
새 문제로 전이하기
세 문항은 앞 문장의 반복이 아닙니다. 직접 답을 입력하면 rubric의 필수 기준을 하나씩 검사하고, 첫 누락 기준을 알려 줍니다.
1. 개념 재구성
함수 호출을 포함하는 RISC-V 함수를 감사할 때 사용할 네 범주 checklist를 기억에서 재구성하세요.
sp, 호출 전후 값, s-register, ret 직전 값을 차례로 보세요.
제출 후 모델 답 보기
stack alignment와 복원, caller-saved 값의 호출 전 보호, 사용한 callee-saved register의 save/restore, 반환값 a0를 검사합니다.
2. 변형 문제
frame을 24 Byte 줄인 함수가 s2를 저장하지 않고 사용하며, 다른 함수를 부른 뒤 t3의 이전 값을 다시 읽습니다. 반환값은 a0에 있습니다. 독립 위반을 모두 쓰세요.
24 mod 16, s2의 분류, t3의 분류를 각각 검사하세요.
제출 후 모델 답 보기
24 Byte frame은 16 Byte 정렬을 깨고, s2는 callee-saved인데 보존되지 않았으며, 호출 뒤 필요한 t3는 caller-saved인데 보호되지 않았습니다. 반환 위치 a0는 맞습니다.
3. 오류 진단
학생이 'prolog -14와 epilog +14의 합이 0이므로 stack 관련 오류는 없다'고 답했습니다. 첫 오류를 고치세요.
원상복구와 호출 경계 정렬은 별도 조건입니다.
제출 후 모델 답 보기
합이 0이라 sp 값은 돌아올 수 있어도 -14 frame은 16 Byte alignment를 위반합니다. 공식 교정은 -16/+16입니다.
이 소문제를 끝냈다고 말할 수 있는 기준
이 소문제의 정확한 공식 페이지와 대조하기
왼쪽은 문제를 읽을 때, 오른쪽은 자신의 풀이를 끝낸 뒤에 확인하세요. 해설 이미지를 먼저 보면 중간 과정을 스스로 만드는 연습이 사라집니다.
Source: Probeklausur.pdf / Probeklausur Musterlösung und Hinweise.pdf · 시험 p9 · 공식 해설 p21–22 · Probeklausur.pdf 시험 p9의 magicBox 오류 code와 Probeklausur Musterlösung und Hinweise.pdf 공식 해설 p21 Teilaufgabe a, ABI 설명 p22.


