왜 이 소문제를 따로 배우는가
오류를 찾는 것과 올바른 함수를 처음부터 구성하는 것은 다른 능력입니다. 이 소문제는 값의 lifetime을 register와 stack에 실제로 배치하는 설계 능력을 평가합니다.
이 페이지는 Aufgabe 4의 공통 템플릿이 아니라 4b 올바른 magicBox 재작성에 필요한 내용만 담습니다. 챕터 전체 배경이 필요하면 Aufgabe 4 개념 수업을 먼저 읽으세요.
이 소문제에서 실제로 쓰는 용어
정의뿐 아니라 이 문제의 어느 판단에 쓰이는지까지 연결합니다.
- stack frame
- 한 함수 호출 동안 저장 register와 지역 상태를 보관하도록 sp 아래에 확보한 영역입니다.이 소문제에서: ra, s0, s1을 서로 겹치지 않는 offset에 저장하고 16 Byte 크기로 잡을 때 사용합니다.
- prolog
- 함수 시작에서 frame을 만들고 보존해야 할 register를 저장하는 부분입니다.이 소문제에서: addi sp,sp,-16과 sw ra/s0/s1의 순서를 구성할 때 사용합니다.
- epilog
- 반환 전에 저장 register와 sp를 원상복구하는 부분입니다.이 소문제에서: lw s1/s0/ra, addi sp,sp,16, ret의 역순 복원을 검산할 때 사용합니다.
- argument register
- 호출 직전 함수 인수를 배치하는 a0–a7 register입니다.이 소문제에서: helper의 첫 인수 b를 a0, 둘째 인수 c를 a1에 놓을 때 사용합니다.
이 소문제 전용 규칙과 종이 작업
오래 사는 값은 보존 register에 둔다
helper 호출 뒤에도 필요한 원래 a는 caller-saved t-register가 아니라 save/restore한 s0처럼 호출을 견디는 위치에 있어야 합니다.
종이에: 변수 a, b, c, d의 lifetime을 그리고 호출선을 가로지르는 값에 s-register 또는 stack 위치를 배정합니다.
frame layout을 먼저 확정한다
save와 restore offset을 즉흥적으로 쓰면 겹치거나 누락되므로 code 전에 frame 표를 정해야 합니다.
종이에: sp+4=s1, sp+8=s0, sp+12=ra처럼 offset 표를 먼저 작성합니다.
호출 직전 argument, 반환 직전 a0
내부에서 어떤 register를 사용했든 helper 호출 직전에는 인수가 a0/a1에, magicBox 반환 직전에는 결과가 a0에 있어야 합니다.
종이에: jal 바로 위와 ret 바로 위에 a0/a1의 의미를 주석으로 적습니다.
Aufgabe 전체 흐름은 챕터 흐름도에서 확인할 수 있습니다. 여기서는 현재 판단에 직접 필요한 규칙만 적용합니다.
이 소문제 전용 작은 예제
함수 wrap(int p, int q)가 r=p+4를 계산하고 g(q,r)를 호출한 뒤 g의 반환값에 p를 더해 반환한다. ABI를 지키는 register 계획을 세우세요.
주어진 것
- g의 인수는 a0=q, a1=r입니다.
- p는 g 호출 뒤에도 필요합니다.
- wrap은 ra와 사용하는 s-register를 보존해야 합니다.
- p를 s0, r을 s1에 배정하고 16 Byte frame에 ra/s0/s1 위치를 정합니다.
두 값 중 p는 확실히 호출선을 가로지르고 s-register 사용 자체도 원값 보존을 요구합니다.
종이 산출물: sp+4:s1, sp+8:s0, sp+12:ra
- a0=q, a1=r을 만든 뒤 g를 호출합니다.
callee는 ABI가 정한 argument 위치에서만 값을 받습니다.
종이 산출물: jal 직전 a0=q, a1=p+4
- g의 a0 반환값에 s0의 p를 더하고 frame을 역순 복원합니다.
최종 결과가 a0에 남고 호출자의 s0/s1/ra/sp가 모두 원상태가 되어야 합니다.
종이 산출물: a0=g(q,r)+p; lw s1,s0,ra; sp+16
예제 답과 독립 검산 보기
16 Byte frame에 ra/s0/s1을 저장하고 p를 s0, r을 s1에 둔 뒤 a0=q, a1=r로 g를 호출합니다. 반환 a0에 s0를 더하고 register와 sp를 복원합니다.
독립 검산: 호출 전후 p가 같은지, ret 직전 a0가 C 식과 같은지, sp와 s-register가 진입 전 값인지 확인합니다.
이제 실제 시험 문제를 micro-work로 풀기
공식 시험이 요구하는 것
공식 ABI를 지키는 code를 완성하세요.
공식 답을 보기 전, 내 답 먼저 남기기
완성 문장이 아니어도 좋습니다. 중간값·register·cycle·cache state처럼 채점 가능한 흔적을 먼저 적으세요.
각 작업의 중간 산출물을 직접 적고 완료 조건을 만족한 뒤 체크하세요. 단계별 이유·산출물·오류가 현재 소문제에 맞게 따로 작성되어 있습니다.
sp를 -16 합니다.
- 왜 하는가
- ra, s0, s1 세 word를 저장하면서 호출 경계의 16 Byte alignment를 만족하는 최소 frame입니다.
- 종이 산출물
- frame 크기 16 Byte와 사용 offset 4,8,12를 그립니다.
- 완료 조건
- 세 저장 slot이 겹치지 않고 sp mod 16 invariant가 유지됩니다.
막혔을 때 단계 힌트·대표 오류
힌트: 필요한 12 Byte를 그대로 빼지 말고 다음 16 Byte 경계로 올리세요.
이 단계의 대표 오류: -12를 사용해 저장 공간은 맞지만 호출 경계 정렬을 깨뜨립니다.
ra,s0,s1을 서로 겹치지 않는 offset에 저장합니다.
- 왜 하는가
- helper가 ra를 바꾸고 magicBox가 s0/s1을 사용하므로 세 기존 값을 모두 복원할 수 있어야 합니다.
- 종이 산출물
- sw ra,12(sp); sw s0,8(sp); sw s1,4(sp)와 frame 그림을 대응시킵니다.
- 완료 조건
- 각 store에 정확히 하나의 대응 load 위치가 정해져 있습니다.
막혔을 때 단계 힌트·대표 오류
힌트: 공식 해설 p21의 4,8,12 offset 배치를 기준으로 검산하세요.
이 단계의 대표 오류: ra만 저장하거나 두 register를 같은 offset에 저장합니다.
s0=a, s1=a+10을 만듭니다.
- 왜 하는가
- 원래 a는 helper 뒤 최종 덧셈에 필요하고 c=a+10은 helper의 둘째 argument로 필요합니다.
- 종이 산출물
- s0 옆에 a/live-after-call, s1 옆에 c=a+10을 적습니다.
- 완료 조건
- helper 호출이 t/a register를 덮어써도 a와 c의 필요한 값이 설명됩니다.
막혔을 때 단계 힌트·대표 오류
힌트: 호출 뒤에도 다시 읽는 C 변수부터 s-register에 배정하세요.
이 단계의 대표 오류: a를 t0에 두어 helper 뒤 값이 보장된다고 가정합니다.
a0=b, a1=c로 helper를 부릅니다.
- 왜 하는가
- helper(int b,int c)의 첫 두 인수는 호출 직전 a0와 a1에 있어야 합니다.
- 종이 산출물
- mv a0,a1로 원래 b를 옮긴 뒤 mv a1,s1, jal ra,helper 순서를 적습니다.
- 완료 조건
- jal 직전 a0와 a1의 의미가 각각 b와 c입니다.
막혔을 때 단계 힌트·대표 오류
힌트: 원래 magicBox의 a1에는 b가 들어오며, c는 이미 s1에 있습니다.
이 단계의 대표 오류: a0를 덮기 전에 b의 위치를 잊거나 helper 인수 순서를 뒤집습니다.
helper return a0에 s0를 더합니다.
- 왜 하는가
- helper의 결과 d는 a0에 돌아오고 C 함수의 최종 식은 d+a이므로 보존한 a를 더해야 합니다.
- 종이 산출물
- add a0,a0,s0 옆에 d+a라고 주석을 적습니다.
- 완료 조건
- 최종 계산값과 ABI 반환 위치가 동시에 a0로 일치합니다.
막혔을 때 단계 힌트·대표 오류
힌트: helper 직후 a0의 의미는 argument가 아니라 반환값입니다.
이 단계의 대표 오류: 결과를 a1에 써서 표준 반환 위치를 어깁니다.
s1,s0,ra를 복원하고 sp+16, ret합니다.
- 왜 하는가
- 저장한 callee state와 return address를 되돌린 뒤에만 호출자 환경으로 안전하게 복귀할 수 있습니다.
- 종이 산출물
- lw s1,4(sp); lw s0,8(sp); lw ra,12(sp); addi sp,sp,16; ret를 적습니다.
- 완료 조건
- 모든 store가 같은 offset의 load와 짝을 이루고 sp가 진입 전 값입니다.
막혔을 때 단계 힌트·대표 오류
힌트: sp를 올리기 전에 현재 frame 주소로 load해야 합니다.
이 단계의 대표 오류: sp를 먼저 +16한 뒤 잘못된 주소에서 register를 load합니다.
공식 답을 열기 전 마지막 회상
s1을 쓰지 않고 c를 곧바로 a1에 만든 더 짧은 해법도 가능한지 생각해 보세요.
내 풀이 후 공식 결론·이유·대표 함정 확인
공식 결론
`addi sp,sp,-16; sw ra,12(sp); sw s0,8(sp); sw s1,4(sp); mv s0,a0; addi s1,a0,10; mv a0,a1; mv a1,s1; jal ra,helper; add a0,a0,s0; lw s1,4(sp); lw s0,8(sp); lw ra,12(sp); addi sp,sp,16; ret`.
왜 이 답이 되는가
s0에 원래 a, s1에 c를 보관하고 두 register의 이전 값과 ra를 16-byte aligned frame에 저장합니다.
대표 함정
return 값을 a0에서 다른 register로 옮겼다가 a1로 반환하지 마세요.
명령어와 식을 줄 단위로 읽기
본문 속 code를 한 줄씩 분리했습니다. 각 줄에서 source, operation, destination을 표시하세요.
addi sp,sp,-16;
sw ra,12(sp);
sw s0,8(sp);
sw s1,4(sp);
mv s0,a0;
addi s1,a0,10;
mv a0,a1;
mv a1,s1;
jal ra,helper;
add a0,a0,s0;
lw s1,4(sp);
lw s0,8(sp);
lw ra,12(sp);
addi sp,sp,16;
ret;새 문제로 전이하기
세 문항은 앞 문장의 반복이 아닙니다. 직접 답을 입력하면 rubric의 필수 기준을 하나씩 검사하고, 첫 누락 기준을 알려 줍니다.
1. 개념 재구성
다른 함수를 호출하는 non-leaf 함수의 prolog부터 epilog까지 작성 순서를 여섯 동사로 재구성하세요.
frame, save, long-lived 값, args, call/result, restore 순서입니다.
제출 후 모델 답 보기
frame 확보 → ra/s-register 저장 → 호출 뒤 필요한 값 보존 → argument 배치 → jal과 a0 결과 계산 → register/sp 복원 후 ret.
2. 변형 문제
h(int x,int y)가 k(y)를 호출한 뒤 k의 반환값+x를 반환합니다. x를 s0에 둔다면 필요한 최소 16 Byte frame의 한 가지 layout과 jal 전후 핵심 instruction을 쓰세요.
ra와 s0 두 word를 저장하고 y는 호출 직전 a0로 옮기세요.
제출 후 모델 답 보기
예: addi sp,sp,-16; sw s0,8(sp); sw ra,12(sp); mv s0,a0; mv a0,a1; jal ra,k; add a0,a0,s0; lw s0,8(sp); lw ra,12(sp); addi sp,sp,16; ret.
3. 오류 진단
학생 code가 모든 register를 올바른 offset에 저장했지만 epilog에서 addi sp,sp,16을 먼저 실행한 뒤 lw를 수행합니다. 왜 틀렸고 어떻게 고칩니까?
load 주소의 기준 sp가 어느 frame을 가리키는지 보세요.
제출 후 모델 답 보기
sp를 먼저 복원하면 lw가 현재 함수 frame이 아닌 호출자 쪽 주소를 읽습니다. 저장 register를 현재 sp 기준으로 먼저 load한 뒤 sp를 +16 해야 합니다.
이 소문제를 끝냈다고 말할 수 있는 기준
이 소문제의 정확한 공식 페이지와 대조하기
왼쪽은 문제를 읽을 때, 오른쪽은 자신의 풀이를 끝낸 뒤에 확인하세요. 해설 이미지를 먼저 보면 중간 과정을 스스로 만드는 연습이 사라집니다.
Source: Probeklausur.pdf / Probeklausur Musterlösung und Hinweise.pdf · 시험 p9 · 공식 해설 p21–22 · Probeklausur.pdf 시험 p9 Teilaufgabe b와 Probeklausur Musterlösung und Hinweise.pdf 공식 해설 p21의 수정 code, p22의 RISC-V convention 표.


