Lecture notes on RISC-V assembly

(eecs.utk.edu)

160 points | by azhenley 8 days ago

2 comments

  • fwsgonzo 8 days ago

    The base RISC-V ISA is pretty simple, so you could learn it by writing your own emulator. I ended up writing one, and now I'm using it for scripting in game engines :)

    There are very few instructions for RV32I and RV64I - and you don't have to support both. Just pick one and implement the basic instructions. Then compile a cross-compiler from https://github.com/riscv/riscv-gnu-toolchain that is configured for either rv32i or rv64, like so:

        ./configure --prefix=$HOME/riscv --with-arch=rv32i
        make
    
    The toolchain repo is pretty big so make sure you do a shallow clone.
    • Do you also cross-compile the C standard library? How do you work out the IO? Do you also emulate a basic OS to run scripts on it?

      I am interested in taking on such project :). Is it enough to emulate registers and operators?

      • fwsgonzo 8 days ago

        Well, while an emulator can be anything, it can also be very little. A userspace emulator is one that just loads an ELF binary, provides hooks for system calls, and then just simulates instructions from there. You don't technically need to support page protections, but it's certainly nice to have and it help you to narrow down problems both inside and outside the guest environment.

        The riscv-gnu-toolchain does indeed build everything for you, but it has 3 "settings", so to speak:

        1. The default is newlib, which is a smaller embedded C-library, but it's enough to have most of C and C++ supported. Running "make" or "make newlib" does the same thing.

        2. "make linux" will build a static glibc, with threads support. I don't recommend it, as you will have emulate pthreads, which are very heavy. If you really want threads, I can give you some pointers on how to make your own light-weight ones. And, of course, so can many others.

        3. "make musl". Not sure if this works completely, but I do believe it's an option. It would have threads too.

        There is also a more complicated 4th option, which is to use an embedded RISC-V compiler, which you can get from here:

            $ xpm install --global @xpack-dev-tools/riscv-none-embed-gcc@latest
        
        I don't recommend it, because it has nothing. You will have to write your entry code and all the libc stuff too. That can be fun, of course. And you get to have really small binaries!

        My emulator produces debug executables which prints every instruction line by line, and it supports register-dumping too, so it could help you compare for divergences if you are having trouble with some instructions: https://github.com/fwsGonzo/libriscv

        If you want to emulate an OS you will have to write guest and host drivers (both sides), which is a very complicated thing to do. However, it's a perfect opportunity to add the first level of concurrency: Running the host and the guest in separate threads! There is also emulating interrupts, various hardware timers and having a page table in guest memory with protection levels. A lot of work!

    • mmrezaie 8 days ago

      In my undergrad studies I learned to do assembly on z80. Is there something similar one can get for educational porpuses using RISC-V?