---
# System prepended metadata

title: Compiler HW3 Guide

---

# Compiler HW3 Guide

簡單說明一下寫作業三需要的小技巧。

- 完整的規格書
- 指令的行為
- 64 bits environment
- toolchain 常用指令

## 完整規格書

附在作業公告的是基本指令(Base)的規格書。裡面其實有太多作業用不到的資訊了。

參考連結

[The RISC-V Instruction Set Manual](https://content.riscv.org/wp-content/uploads/2017/05/riscv-spec-v2.2.pdf)


## 指令行為

最常用的指令


- Memory load store
	- ld
		- load double word to memory
		- `ld rd, offset(rs1)`
	- sd
		- store double word to memory
		- `sd rd, offset(rs1)`
	- lw
		- load word to memory
		- `lw rd, offset(rs1)`
	- sw
		- store word to memory
		- `sw rd, offset(rs1)`
> 這裡指的 word 為 32 bits
- Arithmetic
	- add
		- `add rd, rs1, rs2`
	- sub
		- `sub rd, rs1, rs2`
	- mul
		- `mul rd, rs1, rs2`
	- div
		- `div rd, rs1, rs2`
> 就是字面上的意思
- Jump
	- bne
		- if rs1 != rs2 then jump to label
		- `bne rs1, rs2, label`
	- blt
		- if rs1 < rs2 then jump to label
		- `blt rs1, rs2, label`
	- beq
		- if rs1 == rs2 then jump to label
		- `beq rs1, rs2, label`
	- bgt
		- if rs1 > rs2 then jump to label
		- `bge rs1, rs2, label`

## 64 bits environment

有部份的指令會因為 32 bits 與 64 bits 環境的部份而有不一樣的行為。

典型的範例就是 Arithmetic 系列指令。

因為一個 Register 從 32bits -> 64bits。所以原本指令從

32bits <- 32bits + 32bits 

變成

64bits <- 64bits + 64bits

再者因為register變大。alloc 給某些變數的空間也要變大。

> 除非你有特別的需要你的變數一定要小於register的大小。像是 int 若規定只有 32 bits，那就只需要alloc 4 byte 就好。

## 常用 toolchain 指令

- `riscv64-unknown-elf-gcc`
	- 實際上就是 gcc，只是 target 被換成riscv64
- `spike`
	- 一個模擬器，可以執行riscv的執行檔
- `riscv64-unknown-elf-objdump`
	- 拆開可執行檔(elf)

```
# From assembly to elf
riscv64-unknown-elf-gcc yourfile.s -o outfile

# From .c to assembly file
riscv64-unknown-elf-gcc -S yourfile.c

# Run the elf
spike pk your_elf_file

# Check each instruction address
riscv64-unknown-elf-objdump -dC your_elf_file > log

# find with label or function name
grep -rni "main" log
less log
```

## Spike Debug mode

![](https://i.imgur.com/La4uHsg.png)

- enable debug mode
```
spike -d pk your_elf_file
```

- debug mode usage
```
# Here 0 is mean the label of cpu,
# but we run single core only

# Check reg value
reg 0

# Check Mem value
mem 0 address

# Jump to some pc
until pc 0 pc_address
```