Skip to content

CS 631-01 Systems Foundations — Meeting Summary

  • Date: Mar 24, 2026
  • Time: 08:13 AM Pacific Time (US and Canada)
  • Meeting ID: 870 0988 0761

Quick Recap

The session introduced the transition from assembly language to machine code and previewed a RISC-V machine code emulator project in Rust. Greg:

  • Explained a Docker-based development environment that enables compiling RISC-V code locally and running it via QEMU.
  • Demonstrated how the container provides the necessary cross-compilation tools and a Linux environment for RISC-V development.
  • Reviewed RISC-V instruction formats (e.g., R-type, I-type) and how to decode 32-bit instruction words by extracting opcode, register fields, and immediate values.
  • Presented a Rust example for reading machine code from memory and decoding instruction components.
  • Noted that emulator implementation details will be covered in greater depth on Thursday.

Next Steps

  • Greg:
  • Investigate and fix GDB/Rust-GDB issues within the Docker/containerized environment for Project 3.
  • Publish new RISC-V resources and manuals for emulator development.
  • Post a diagram on Campus Wire (Project 2) showing how the generated .s file, the preamble, and NT-lang compiler output relate, and ensure access.
  • Follow up on “the whole GDB thing” to enable container-based debugging for the next project.

  • Students:

  • Ensure their NT-lang implementation includes the provided FindGCC logic (or an equivalent) so RISC-V executables compile on both Beagle and container environments.
  • Hand-translate the provided CodeGen C code into CodeGen main.s (assembly) for Project 2.
  • Review the posted diagram on Campus Wire (Project 2) clarifying the structure of generated assembly files.

Summary

RISC-V Machine Code Emulator Project

  • Focus: Move from assembly to RISC-V machine code and build a Rust-based emulator that interprets binary instructions.
  • Purpose: Bridge software and hardware understanding before digital design/logic, while continuing to develop Rust skills and familiarity with binary formats.

Docker Setup for the RISC-V Project

  • A new Docker setup (Project 3) provides a unified way to generate and run RISC-V 64-bit code across heterogeneous host architectures and Beagle devices.
  • Rationale:
  • Enable use of cloud code locally.
  • Provide a standard vehicle for running the same code in different environments.
  • Address Rust performance limitations on Beagle hardware.
  • An alternative using FUSE for remote directory mounting was noted, but it cannot execute commands directly on the Beagle.

Dockerized RISC-V Development Environment

  • Containers supply a Linux environment with cross-build tools and QEMU for non-RISC-V hosts.
  • The riscv-run command selects the correct execution path automatically (native on RISC-V, containerized on others).
  • Upcoming tasks:
  • Extend NT-lang to support command-line arguments.
  • Implement a compile mode targeting RISC-V.

Assembly Code Writing Process

  • Topics: Hand-written assembly, loops, stack allocation, function calls, and calling conventions.
  • Emphasis on using the correct GCC toolchain string to work seamlessly inside the container.
  • Brief discussion of method chaining; a short break followed these topics.

FindGCC Setup and Compilation

  • Guidance on using Docker Desktop, Colima, or OrbStack (all free) to build and run code.
  • Workflow:
  • Create CodeGen main.s as the assembly version of codegen.c.
  • Concatenate this with compiler output to form the final .s file.
  • Greg noted he would look into the “DVV matter” and offered help with container setup during a break.

Project Website S-File Functionality

  • The website’s S-file generation and its role in exposing function names were reviewed.
  • A screenshot confirmed that describing the generated S-file as a “preamble” is accurate.
  • Related notes were posted to Campus Wire (Project 2); the sample output appeared reasonable.
  • The discussion then pivoted to machine code.

Machine Code Instruction Formats Demo

  • Demonstration of 32-bit instruction formats and conversion from assembly to binary using tools such as GCC and objdump.
  • Although GCC may default to 16-bit compressed instructions for efficiency, the course will focus on the 32-bit format.
  • Planned resources include reference materials and a possible Rust script to manually decode instructions to reinforce understanding.

RISC-V Instruction Set Architecture Overview

  • RISC-V is open-source with extensive documentation via the RISC-V consortium.
  • Reviewed instruction formats with a focus on R-type:
  • Components include opcode, destination/source registers, and func fields (e.g., add, sub, xor).
  • Key takeaway: Mastery of formats is essential for accurate emulation and navigating references.

Identifying RISC-V Instruction Types

  • Method for distinguishing R-type vs. I-type using opcode, funct3, and funct7.
  • Noted that store and branch instructions omit destination registers and use split immediates.
  • More complex encodings will be covered in detail on Thursday.

Decoding R-Type Instructions

  • Process:
  • Extract fields (opcode, rd, rs1, rs2, funct3, funct7).
  • Convert binary values to decimal where appropriate.
  • Map opcode/funct patterns to operations.
  • Emphasis on doing manual decodes to build intuition before automating.

Rust Warm-up: Interpreting Machine Code

  • Exercise:
  • Assemble and link a small assembly function with a Rust driver.
  • Bind to the function’s address, read instruction words, and use bitwise masks/shifts to extract fields.
  • Thursday’s plan:
  • Build a simple emulator with a 32-register state, stack space, and a program counter to execute basic machine operations.