ZERO-BASE LESSON · AUFGABE 3

C를 RISC-V로 번역하는 다섯 가지 반복 패턴

C 문장을 한 줄씩 기계적으로 바꾸는 것이 아닙니다. 변수의 보관 장소를 먼저 정하고, array 주소, loop 탈출 조건, function call 보존 규칙을 작은 패턴으로 조립합니다.

학습 목표: 공식 시험 시험 p7–8 · 공식 해설 p8–11를 풀기 전에 필요한 개념을 처음부터 만듭니다. 이 페이지를 읽은 뒤 소문제 카드에서 실제 시험 풀이 순서를 연습하세요.

교재처럼 순서대로 읽는 본문

이 글은 요약 카드가 아닙니다. 처음 보는 용어의 뜻부터 시작해, 왜 그런 규칙이 생겼는지와 문제에서 어떻게 사용하는지를 한 흐름으로 설명합니다.

이 장을 공부하는 이유

C 문장을 한 줄씩 기계적으로 바꾸는 것이 아닙니다. 변수의 보관 장소를 먼저 정하고, array 주소, loop 탈출 조건, function call 보존 규칙을 작은 패턴으로 조립합니다.

읽고 나면 할 수 있어야 하는 것

먼저 비유로 머릿속 구조 만들기

register는 책상 위의 메모지입니다. t-register는 전화를 걸면 상대가 지워도 되는 임시 메모, s-register는 상대가 사용했다면 원상복구해야 하는 장기 메모, stack은 통화 전에 중요한 메모를 넣어 두는 서랍입니다.

C에서 RISC-V로 옮기는 순서다섯 단계의 왼쪽에서 오른쪽으로 진행하는 개념 흐름도C에서 RISC-V로 옮기는 순서 변수 표 register 배치 호출 분석 ra·live 값 보호 주소 계산 index × Byte 제어 흐름 branch와 label 복원 epilog·return

그림은 왼쪽에서 오른쪽으로 읽습니다. 각 화살표는 앞 단계의 결과가 다음 단계의 입력이 된다는 뜻입니다. 흐름도만 크게 열기

용어를 평범한 문장으로 바꾸기

독일어와 영어 용어를 소리만 외우지 말고, 아래 설명을 자신의 말로 다시 말해 보세요.

ABI / calling convention
함수끼리 register·stack을 어떻게 주고받는지 정한 약속
Prolog / Epilog
함수 시작의 저장·frame 생성 / 끝의 복원·return
leaf function
다른 함수를 호출하지 않는 함수
byte offset
원소 index를 실제 주소에 더할 Byte 수로 바꾼 값
branch inversion
계속 조건의 반대를 검사해 done label로 빠지는 구성

개념을 처음부터 연결하기

1. Array 주소 공식

`&arr[i] = base + i × sizeof(element)`입니다. int는 4 Byte이므로 `slli offset,i,2`로 ×4를 만들 수 있습니다. load/store offset은 Byte 단위입니다.

2. 함수 호출 전후

`jal`은 ra를 덮어씁니다. 호출 뒤에도 필요한 값은 caller-saved t/a에 그대로 믿고 두지 않습니다. s-register를 쓰는 함수는 caller의 원래 s값을 stack에 저장했다가 복원합니다.

3. Loop와 if

`i < n-1`이 참일 때 body로 가는 대신 `i >= n-1`이면 done으로 가도록 씁니다. 조건 반전과 branch target을 한 묶음으로 검산해야 합니다.

이 챕터에서 계속 사용할 손풀이 표

아래 표는 정답표가 아니라 작업 기억을 외부에 꺼내 놓는 worksheet입니다. 소문제를 풀 때마다 빈 칸을 직접 채우세요.

C→RISC-V 번역 worksheet
C 요소Assembly에서 정할 것검산
변수보관 registercall 뒤에도 살아 있는가
Arraybase + index×sizeByte 단위인가
Loopinit·condition·body·update탈출 조건이 반대인가
Function callargument·ra·saved valuesABI 보존 규칙
Returna0와 epilogstack이 원상복구됐는가

수식은 위아래 구조로 읽기

평문으로 제곱과 분수를 이어 쓰면 구조를 놓치기 쉽습니다. 아래 수식은 브라우저의 MathML로 렌더되며, 지수·아래첨자·분수를 실제 수학 표기처럼 보여 줍니다.

int array 원소의 주소

addr(arr[i])=base(arr)+i×4 Byte

RISC-V의 load/store offset은 원소 수가 아니라 Byte 수입니다.

함수 호출 경계의 stack 정렬

spmod16=0

저장할 값이 20 Byte여도 frame은 정렬을 만족하도록 32 Byte처럼 올림할 수 있습니다.

작은 숫자로 한 번 직접 해보기

`arr[3]`의 주소를 구해 봅시다. base=0x1000, int=4 Byte이면 offset=3×4=12=0xC, 주소=0x100C입니다. index 3을 그대로 더한 0x1003은 misaligned 주소라 틀립니다.

이 예제에서 중요한 것은 숫자 자체가 아니라, 어떤 값을 먼저 구하고 그 결과를 다음 계산에 넣는지입니다. 종이에 중간값을 생략하지 않고 적어 보세요.

초보자가 자주 멈추는 지점

C 한 줄은 Assembly 한 줄인가요?

아닙니다. `arr[i]` 하나에도 index scaling, base addition, load/store가 필요합니다. 의미가 같은지가 기준이지 줄 수가 기준이 아닙니다.

t-register는 함수 안에서 자유롭게 안전한가요?

현재 함수가 helper를 호출하면 helper가 t-register를 바꿀 수 있습니다. 호출 뒤에도 필요한 값은 반드시 따로 보호해야 합니다.

loop branch 방향이 계속 헷갈려요.

C의 계속 조건을 먼저 쓰고 그 부정을 done 조건으로 옆에 씁니다. 예: `j < limit`의 부정은 `j >= limit`, 따라서 `bge j,limit,done`입니다.

시험지에서 손으로 쓰는 순서

  1. C variable마다 register 표를 먼저 만듭니다.
  2. 호출 여부를 보고 stack frame과 저장 register를 결정합니다.
  3. array 접근마다 base + index×size를 적습니다.
  4. loop마다 init / condition / body / update / back-edge 다섯 칸을 만듭니다.
  5. epilog에서 prolog의 역순으로 정확히 복원합니다.

이 순서를 외우는 목적은 답을 암기하는 것이 아닙니다. 중간 과정을 답안지에 남겨 부분점수를 얻고, 어디에서 잘못됐는지 스스로 찾기 위한 체크포인트입니다.

6개 소문제로 개념 적용하기

각 소문제에는 이 장의 설명을 다시 포함한 독립 수업 페이지가 있습니다. 따라서 링크로 바로 들어가도 선행지식 없이 읽을 수 있습니다.

  1. 3-1
    `swap`: 두 주소 계산

    `arr[i]`와 `arr[j]`의 주소를 만드세요. · 4 micro-work

    독립 수업 열기 →
  2. 3-2
    `swap`: load 두 번, store 두 번

    두 원소를 실제로 바꾸세요. · 5 micro-work

    독립 수업 열기 →
  3. 3-3
    `bubbleSort` Prolog

    swap을 부르기 전에 무엇을 stack에 저장해야 하나요? · 4 micro-work

    독립 수업 열기 →
  4. 3-4
    바깥 loop 조건

    `i < n-1`을 branch로 구현하세요. · 3 micro-work

    독립 수업 열기 →
  5. 3-5
    안쪽 loop와 비교

    `j < n-i-1`과 `arr[j] > arr[j+1]`을 구현하세요. · 5 micro-work

    독립 수업 열기 →
  6. 3-6
    swap 호출과 Epilog

    argument를 놓고 swap을 호출한 뒤 loop와 function을 끝내세요. · 5 micro-work

    독립 수업 열기 →

출처

Source: Probeklausur.pdf / Probeklausur Musterlösung und Hinweise.pdf · 시험 p7–8 · 공식 해설 p8–11. 공식 답의 숫자와 course-specific datapath/FSM 가정은 변경하지 않았습니다.