UNIT-SPECIFIC ACTIVE LESSON · 4a

다섯 ABI 위반 찾기

잘못된 magicBox에서 모든 convention 위반을 찾고 공식 지적을 독립 검산하세요.

학습 목표: 함수 호출 전후의 register lifetime과 stack invariant를 따라가며 공식 p21의 다섯 지적을 찾고, +14 항목은 독립 오류가 아니라 -16 교정과 연동된 수정임을 구분할 수 있다.
공식 근거 범위: Probeklausur.pdf 시험 p9의 magicBox 오류 code와 Probeklausur Musterlösung und Hinweise.pdf 공식 해설 p21 Teilaufgabe a, ABI 설명 p22.

왜 이 소문제를 따로 배우는가

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입니다.
  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 중 하나에 정확히 대응하고 같은 오류를 중복 계산하지 않았는지 확인합니다.

잘못된 code를 line별로 감사하기

  1. addi sp,sp,-14: 16-byte alignment를 깨고 새 sp를 word boundary에서도 벗어나게 함
  2. mv t0,a0: helper 호출 뒤에도 필요한 a를 caller-saved t0에만 둠
  3. addi s1,a0,10: 기존 s1 값을 save/restore하지 않음
  4. add a1,a0,t0: return value를 a0가 아닌 a1에 둠
  5. addi sp,sp,14: 공식은 별도 항목으로 지적하지만 원본 -14를 산술적으로 복원함. prolog를 -16으로 교정하면 epilog도 +16으로 함께 교정해야 하는 연동 수정임

이제 실제 시험 문제를 micro-work로 풀기

공식 시험이 요구하는 것

잘못된 magicBox에서 모든 convention 위반을 찾고 공식 지적을 독립 검산하세요.

공식 답을 보기 전, 내 답 먼저 남기기

완성 문장이 아니어도 좋습니다. 중간값·register·cycle·cache state처럼 채점 가능한 흔적을 먼저 적으세요.

각 작업의 중간 산출물을 직접 적고 완료 조건을 만족한 뒤 체크하세요. 단계별 이유·산출물·오류가 현재 소문제에 맞게 따로 작성되어 있습니다.

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보다 크다는 이유로 정렬됐다고 판정합니다.

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이므로 저장 없이 마음대로 써도 된다고 해석합니다.

원본 -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 위반까지 없다고 결론냅니다.

C return 값이 a0에 놓였는지 봅니다.

왜 하는가
RISC-V 정수 반환값은 a0로 전달되므로 a1의 결과는 호출자가 표준 방식으로 받을 수 없습니다.
종이 산출물
ret 직전 a0와 a1의 값을 써서 결과가 a1에 잘못 놓였음을 표시합니다.
완료 조건
최종 계산 결과를 a0로 옮겨야 한다는 수정까지 제시합니다.
막혔을 때 단계 힌트·대표 오류

힌트: 함수 argument register와 return register가 겹치지만 반환은 첫 번째인 a0입니다.

이 단계의 대표 오류: a-register이면 어느 것이든 반환값으로 사용할 수 있다고 생각합니다.

공식 답을 열기 전 마지막 회상

원본 -14/+14와 교정안 -16/+16에서 각각 sp가 원상복구되는지와 4/16-byte alignment가 맞는지를 구분해 설명하세요.

내 풀이 후 공식 결론·이유·대표 함정 확인

공식 결론

공식 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이어야 한다는 연동 수정입니다.

대표 함정

공식 해설의 다섯 항목을 그대로 제시하되, +14는 원본에서 -14를 되돌리며 교정된 -16 frame과 짝지을 때만 +16으로 바뀐다는 점을 숨기지 마세요.

4a에서 정확히 무엇에 답하는가

이 소문제의 답안 대상: 잘못된 magicBox에서 모든 convention 위반을 찾고 공식 지적을 독립 검산하세요.

  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에 잘못 놓였음을 표시합니다.

따라서 도출되는 공식 답: 공식 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이어야 한다는 연동 수정입니다.

이 답에 붙는 주의: 공식 해설의 다섯 항목을 그대로 제시하되, +14는 원본에서 -14를 되돌리며 교정된 -16 frame과 짝지을 때만 +16으로 바뀐다는 점을 숨기지 마세요.

명령어와 식을 줄 단위로 읽기

본문 속 code를 한 줄씩 분리했습니다. 각 줄에서 source, operation, destination을 표시하세요.

sw/lw ra,0(sp)
addi sp,sp,-14
addi sp,sp,14

새 문제로 전이하기

세 문항은 앞 문장의 반복이 아닙니다. 직접 답을 입력하면 rubric의 필수 기준을 하나씩 검사하고, 첫 누락 기준을 알려 줍니다.

1. 개념 재구성

함수 호출을 포함하는 RISC-V 함수를 감사할 때 사용할 네 범주 checklist를 기억에서 재구성하세요.

제출 후 모델 답 보기

stack alignment와 복원, caller-saved 값의 호출 전 보호, 사용한 callee-saved register의 save/restore, 반환값 a0를 검사합니다.

2. 변형 문제

frame을 24 Byte 줄인 함수가 s2를 저장하지 않고 사용하며, 다른 함수를 부른 뒤 t3의 이전 값을 다시 읽습니다. 반환값은 a0에 있습니다. 독립 위반을 모두 쓰세요.

제출 후 모델 답 보기

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입니다.

이 소문제를 끝냈다고 말할 수 있는 기준

이 소문제의 정확한 공식 페이지와 대조하기

왼쪽은 문제를 읽을 때, 오른쪽은 자신의 풀이를 끝낸 뒤에 확인하세요. 해설 이미지를 먼저 보면 중간 과정을 스스로 만드는 연습이 사라집니다.

4a 관련 공식 시험 또는 해설 페이지
exam-p09.png · 클릭해 원본 크기로 확인
4a 관련 공식 시험 또는 해설 페이지
solution-p21.png · 클릭해 원본 크기로 확인
4a 관련 공식 시험 또는 해설 페이지
solution-p22.png · 클릭해 원본 크기로 확인

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.