14P by GN⁺ 1일전 | ★ favorite | 댓글 1개
  • 웹 브라우저에서 실행 가능한 에뮬레이터를 통해 RISC-V 어셈블리를 단계별로 학습할 수 있는 대화형 튜토리얼로, Nick Morgan의 Easy 6502에서 영감을 받아 제작됨
  • RV32I_Zicsr 명령어 세트의 45개 기본 명령어와 특권 아키텍처의 핵심 개념을 다루며, 컴파일러 타겟으로 충분히 완전한 명령어 세트를 교육
  • 산술/논리 연산, 분기/점프, 메모리 접근, 함수 호출 규약, 스택 관리 등 어셈블리 프로그래밍의 기초를 실습 예제와 함께 제공
  • Machine 모드와 User 모드 간 특권 레벨 전환, 예외 처리, CSR(제어 및 상태 레지스터) 조작 방법을 실전 코드로 설명
  • 튜토리얼의 최종 목표는 시스템 콜과 예외 처리를 지원하는 초소형 운영체제를 직접 작성하는 것으로, RISC-V 저수준 개발의 전체 흐름을 경험 가능

튜토리얼 구성 및 주요 학습 내용

기본 명령어 및 프로세서 개념

  • 프로세서 상태: 프로그램 카운터(pc), 31개의 범용 레지스터(x1~x31), 특수 제로 레지스터(x0) 이해
  • 산술 명령어: add, addi, sub 등을 통한 덧셈/뺄셈 연산 및 오버플로우 동작 학습
  • 비트 연산: and, or, xor, sll, srl, sra 등 비트 단위 논리 연산 및 시프트 명령어 실습
  • 비교 명령어: slt, sltu 등을 활용한 부호 있는/없는 정수 비교 및 조건 판단 로직 구현

제어 흐름 및 메모리

  • 분기와 점프: beq, bne, blt, jal, jalr 등을 사용한 조건/무조건 분기 및 함수 호출 메커니즘
  • 메모리 접근: lw, sw, lb, lh, sb, sh 명령어를 통한 워드/하프워드/바이트 단위 로드/스토어 작업
  • 메모리 매핑 I/O: 특정 주소에 대한 읽기/쓰기로 외부 장치와 통신하는 방식 이해
  • 위치 독립 코드: auipc 명령어와 PC 상대 주소 지정을 통한 재배치 가능한 코드 작성 기법

함수 및 호출 규약

  • 레지스터 별칭: a0~a7(인자), s0~s11(보존), t0~t6(임시), ra(리턴 주소), sp(스택 포인터) 등의 역할
  • 스택 관리: 함수 진입 시 레지스터 저장, 스택 공간 할당/해제, 리턴 주소 보존 및 복원 패턴
  • 재귀 함수: 피보나치 수열 구현을 통한 재귀 호출과 스택 프레임 관리 실습

특권 아키텍처 및 운영체제

  • 특권 레벨: Machine 모드(레벨 3)와 User 모드(레벨 0)의 차이 및 격리 메커니즘
  • CSR 명령어: csrrw, csrrs, csrrc 등으로 제어 레지스터 읽기/쓰기 및 비트 필드 조작
  • 예외 처리: mcause, mepc, mtval, mstatus CSR을 통한 예외 정보 확인 및 핸들러 작성
  • 모드 전환: mret 명령어로 User 모드 진입 및 복귀, mscratch를 활용한 컨텍스트 스위칭

최종 프로젝트: 초소형 OS

  • 시스템 콜 구현: ecall 명령어로 User 모드에서 Machine 모드로 트랩하여 putchar/exit 기능 제공
  • 레지스터 저장/복원: 스택에 모든 범용 레지스터를 백업하고 복원하는 트랩 핸들러 전체 구조
  • 예외 처리 로직: mcause로 예외 원인 판별, 시스템 콜 번호(a7)에 따른 디스패치 및 에러 메시지 출력
  • 실행 가능한 코드: 웹 에뮬레이터에서 직접 실행 가능한 완전한 OS 커널 진입/복귀 코드 제공

참고 자료 및 라이선스

  • 튜토리얼 및 코드 모두 CC0 퍼블릭 도메인 또는 0-clause BSD 라이선스
  • 원문 및 코드 저장소: https://github.com/dramforever/easyriscv
  • RISC-V 학습용으로 교육·연구·시뮬레이션 환경 구축에 적합
Hacker News 의견
  • 정말 좋은 가이드였음
    첫 번째 “My first RISC-V assembly program” 에뮬레이터 화면이 가이드의 맨 앞에 있었으면 좋겠음. 그렇지 않으면 독자들이 ‘interactive’라는 제목에도 불구하고 텍스트만 있는 소개라고 착각할 수도 있음
    앞으로 며칠 더 시간을 들여볼 예정임. RISC-V에 꽤 관심이 많고, 밝은 미래가 있다고 생각함
    혹시 AI 전문가가 이 글을 본다면 Replit이나 Lovable 같은 플랫폼으로 RISC-V 어셈블리로 Core War를 다시 만들어주면 정말 멋질 것 같음

    • 왜 그냥 뇌로 직접 하지 않는 거지?
  • Patterson과 Hennessy의 Computer Organization And Design으로 어셈블리를 배웠는데, RISC-V가 MIPS에서 얼마나 많은 걸 가져왔는지 확실히 느껴짐
    두 ISA 모두 같은 사람들이 관여했고, MIPS의 delay slot 같은 실수를 피했음. MIPS 경험이 있다면 RISC-V 어셈블리는 거의 비슷하게 느껴짐
    요즘은 AArch64도 살펴보고 있는데, RISC-V보다 덜 깔끔하지만 실용적인 설계가 인상적임. 오히려 RISC-V가 너무 보수적으로 설계된 게 아닌가 하는 생각도 듦

    • 아마 RISC-V는 RISC-1에 더 가까울 것임. Patterson이 직접 설명한 글이 있음: How close is RISC-V to RISC-I, RISC on a Chip
    • 나도 RISC-V와 MIPS의 유사성을 느꼈음. Nintendo 64 홈브류 개발을 하면서 “이거 예전에 Ares+Godbolt에서 만지던 거랑 거의 똑같네, delay slot만 없네”라고 자주 생각했음
    • AArch64의 설계가 어디서 비롯됐는지, 그리고 어떤 철학으로 만들어졌는지 불분명한 점이 많다는 걸 사람들이 잘 인식하지 못함
    • 명령어는 추가하기는 쉬워도 제거하기는 어려움. RISC-V는 처음에 최소한의 명령어 집합으로 시작했고, 이후 점진적으로 확장 중임. 새로운 명령어를 제안하려면 그 비용과 실질적 이득을 입증해야 함
    • Computer Architecture: A Quantitative Approach에도 RISC-V와 MIPS의 유사성에 대한 내용이 있었던 걸로 기억함. 책이 지금은 박스 속이라 정확한 페이지는 모르겠음
  • TCP Socket in RISC-V Assembly를 직접 작성했음
    RV64I ISA를 사용했고, linker relaxation 개념을 이해해야 함. 참고 자료도 함께 첨부해둠

  • Position Independence 섹션에 오류가 있는 것 같음
    예제 코드에서 auipc 대신 lui를 사용해야 0x3004가 나오는 게 아닌지 궁금함

    • 그렇지 않음. lui는 절대 주소를 생성하지만, auipc/addi 조합은 위치 독립적 주소를 만듦. auipc가 0번지에 있다면 결과는 동일하지만, 실제로는 현재 명령어 주소에 더해진 값이 됨
  • 이 콘텐츠의 인터랙티브한 구성이 정말 훌륭함
    C/C++ 개발자로서 어셈블리는 늘 어렵다고 생각했는데, 이 방식 덕분에 훨씬 명확하게 이해됨

    • RISC-V 어셈블리는 대체로 쉽지만 명령어 축약형이 너무 많아 불편함. lw 대신 load4, j 대신 jump처럼 좀 더 직관적인 이름을 쓸 수도 있을 텐데, 펀치카드 시대도 아닌데 왜 이렇게 짧게 쓰는지 모르겠음
  • 이 글을 보고 다시 저수준 프로그래밍을 해보고 싶어졌음
    대학에서 메카트로닉스를 전공하며 C와 어셈블리로 마이크로컨트롤러를 다뤘지만, 지금은 웹 개발 쪽으로 옮겼음
    RISC-V 하드웨어를 배우기 위한 신뢰할 만한 자료가 있을까 궁금함. 가능하다면 Rust로 해보고 싶음

    • Rust로 직접 하드웨어를 다루는 건 아니지만, OS 기초를 다루는 좋은 튜토리얼이 있음: Operating System in 1000 Lines
      또 Rust 기반 OS 튜토리얼도 있었는데 지금은 링크를 못 찾겠음
      실제 하드웨어를 원한다면 neorv32를 추천함 — 문서가 잘 되어 있음: 공식 문서, GitHub 저장소. VHDL로 작성된 RISC-V 코어임
  • RISC-V 하드웨어는 쉽게 구할 수 있음
    RISC-V on Raspberry Pi Pico 2 참고

    • VisionFive 2 Lite도 출시될 예정이라 기대 중임. 드라이버나 성능 면에서 약간 부족하지만 OS 개발용으로는 괜찮을 듯함
      Kickstarter 페이지 참고
      또 RISC-V와 FPGA를 함께 다루고 싶다면 PolarFireSoC도 있음. AMD/Xilinx보다 훨씬 저렴하고 쓸 만함. 개발 환경은 좀 올드하지만 빠름, 문서는 흩어져 있지만 대부분 어딘가엔 있음
      개발 키트 링크
      재밌는 점은 개발 보드가 칩보다 싸다는 것임
    • 아마 ESP-32에서 시작하는 게 더 쉬울 수도 있음. 훨씬 널리 구할 수 있으니까
  • 마침 이번 주에 C 강의에서 어셈블리 입문 단원에 들어갔는데, RISC-V로 배우면 CPU 차이 문제를 피할 수 있을 것 같았음
    그런데 누군가 이미 그걸 완벽히 정리해둔 자료를 만들어줬음. 정말 감사함

  • “0에서 빼면 음수가 된다”는 예제에서, 0x123의 음수는 0xfffffedd임
    에뮬레이터가 0xfffffccd를 보여준다고 했지만, 실제로는 0xfffffedd가 맞음. 직접 계산해봤고 에뮬레이터가 정확함

  • 좋은 RISC-V 에뮬레이터를 찾는다면 RARS를 추천함