UNIT-SPECIFIC ACTIVE LESSON · 4b

올바른 magicBox 재작성

공식 ABI를 지키는 code를 완성하세요.

학습 목표: magicBox의 C 의미를 유지하면서 16 Byte aligned frame, register 보존, argument 전달, a0 반환을 만족하는 RISC-V 함수를 작성할 수 있다.
공식 근거 범위: Probeklausur.pdf 시험 p9 Teilaufgabe b와 Probeklausur Musterlösung und Hinweise.pdf 공식 해설 p21의 수정 code, p22의 RISC-V convention 표.

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

오류를 찾는 것과 올바른 함수를 처음부터 구성하는 것은 다른 능력입니다. 이 소문제는 값의 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를 보존해야 합니다.
  1. p를 s0, r을 s1에 배정하고 16 Byte frame에 ra/s0/s1 위치를 정합니다.

    두 값 중 p는 확실히 호출선을 가로지르고 s-register 사용 자체도 원값 보존을 요구합니다.

    종이 산출물: sp+4:s1, sp+8:s0, sp+12:ra

  2. a0=q, a1=r을 만든 뒤 g를 호출합니다.

    callee는 ABI가 정한 argument 위치에서만 값을 받습니다.

    종이 산출물: jal 직전 a0=q, a1=p+4

  3. 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 확보 → 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을 쓰세요.

제출 후 모델 답 보기

예: 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를 수행합니다. 왜 틀렸고 어떻게 고칩니까?

제출 후 모델 답 보기

sp를 먼저 복원하면 lw가 현재 함수 frame이 아닌 호출자 쪽 주소를 읽습니다. 저장 register를 현재 sp 기준으로 먼저 load한 뒤 sp를 +16 해야 합니다.

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

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

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

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

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 표.