diff --git a/README.md b/README.md index 54fde9a..bdbda94 100644 --- a/README.md +++ b/README.md @@ -2,27 +2,64 @@ Implementing a basic RISC-V emulator, aimed at being easily extendable. -Currently supported (but not implemented) instructions: +This emulator contains: +* RISC-V Assembly parser +* RISC-V Assembly loader +* Emulation for parts of the basic RISC-V instruction set +* Naive memory emulator +* Basic implementation of some syscalls +* A debugging environment -```` -lb, lh, lw, lbu, lhu, sb, sh, sw, sll, slli, srl, srli, sra, -srai, add, addi, sub, lui, auipc, xor, xori, or, ori, and, -andi, slt, slti, sltu, sltiu, beq, bne, blt, bge, bltu, bgeu, -j, jr, jal, jalr, ret, scall, break, nop -```` -See the docs on [asembly](docs/assembly.md) and [the cpu](docs/CPU.md) for more detail. +## Running simple Assembly: +A couple of basic assembly programs are provided inside `examples/`, such as [`exit.asm`](examples/exit.asm), which just exits with code 0 -Currently, symbols (such as `main:`) are looked-up in runtime. This allows for better debugging, I believe. +You can run it by typing `python -m riscemu examples/hello-world.asm`. It will produce output similar to: +``` +Successfully loaded: LoadedExecutable[examples/hello-world.asm](base=0x00000100, size=24bytes, sections=data text, run_ptr=0x00000110) +Hello world +Program exited with code 0 +``` + + +See the docs on [asembly](docs/assembly.md) and [the cpu](docs/CPU.md) for more detail on how to write assembly code for this emulator. +See the [list of implemented syscalls](docs/syscalls.md) for more details on how to syscall. + +Currently, symbols (such as `main:`) are looked-up at runtime. This allows for better debugging, I believe. Basic IO should work, as open, read, write and close are supported for stdin/stdout/stderr and even aribtrary file paths (if enabled) +## Using the CLI: +*Current CLI is not final, options may change frequently until a stable version is reached* + +This is how the interface is used: + +``` +riscemu [--options OPTIONS] [--syscall-option SYSCALL_OPTIONS] [--default_stack_size] file.asm [file.asm ...] + +OPTIONS and SYSCALL_OPTIONS is a list of comma-separated flags that will be enabled + + OPTIONS: +disable_debug Disable the ebreak and sbreak instructions +no_syscall_symbols Don't make syscall symbols globally available +fail_on_ex Do not launch an interactive debugger when the CPU loop catches an exception + + SYSCALL_OPTIONS: +fs_access Allow access to the filesystem +disable_io Disallow reading/writing from stdin/stdout/stderr +``` + +If multiple files are specified, all are loaded into memeory, but only the last one is executed. This might be improved +later, maybe the `_init` section of each binary is executed before the main loop starts? + ## Resources: * Pseudo ops: https://www.codetd.com/article/8981522 * RISC-V reference card: https://www.cl.cam.ac.uk/teaching/1617/ECAD+Arch/files/docs/RISCVGreenCardv8-20151013.pdf ## TODO: - * add global symbol lookup table - * better pseudo-ops - * mmu inspect methods + * Prevent tokenizer infinite loop on unknown instructions + * Move cpu instructions to different file, allow for instruction set selection and composition + * Add a cycle limit to the options and CPU to catch infinite loops + * Move away from `print` and use `logging.logger` instead + diff --git a/docs/stack.md b/docs/stack.md index e69de29..0ecd234 100644 --- a/docs/stack.md +++ b/docs/stack.md @@ -0,0 +1,10 @@ +# The stack + +The stack is a continuous region of memory, located somewhere. The stack grows "downwards", meaning new values are pushed like this: +```asm + add sp, sp, -4 + sw a0, sp, 0 + +``` + + diff --git a/docs/syscalls.md b/docs/syscalls.md index 1c76b2d..dbc1909 100644 --- a/docs/syscalls.md +++ b/docs/syscalls.md @@ -10,7 +10,8 @@ Performing a syscall is quite simple: scall ``` -In order to use the global syscall symbols, run with the `--syscall-symbols` flag (not implemented yet) +The global symbols (e.g. `SCALL_READ`) are loaded by default. If you specify the option `no_syscall_symbols`, they will be omitted. + ## Read (63) `SCALL_READ` * `a0`: source file descriptor @@ -40,7 +41,7 @@ In order to use the global syscall symbols, run with the `--syscall-symbols` fla Requires flag `--scall-fs` to be set to True -## Close (1025) `SCALL_OPEN` +## Close (1025) `SCALL_CLOSE` * `a0`: file descriptor to close * `return: a0`: 0 if closed correctly or -1 diff --git a/examples/hello-world.asm b/examples/hello-world.asm index e69de29..9588560 100644 --- a/examples/hello-world.asm +++ b/examples/hello-world.asm @@ -0,0 +1,13 @@ +; hello-world.asm +; print "hello world" to stdout and exit + .data +msg: .ascii "Hello world\n" + .text + addi a0, zero, 1 ; print to stdout + addi a1, zero, msg ; load msg address + addi a2, zero, 12 ; write 12 bytes + addi a7, zero, SCALL_WRITE ; write syscall code + scall + addi a0, zero, 0 ; set exit code to 0 + addi a7, zero, SCALL_EXIT ; exit syscall code + scall