# Lab2: RISC-V `RV32I[MA]` emulator with ELF support
## Usage on Ubuntu Linux
#### Commands
If you don't use 'make' function, then you can use commands below:
After following this: https://hackmd.io/@sysprog/rJAufgHYS
Firstly, write c code(here c code file is test2).
And, run commands below.
~/rv32emu$ riscv-none-embed-gcc -march=rv32i -mabi=ilp32 -O3 -nostdlib test4.c -o test4
To check your code:
~/rv32emu$ ./emu-rv32i test4
~/rv32emu$ riscv-none-embed-gcc -Os -nostdlib test4.c -o test4
~/rv32emu$ riscv-none-embed-objdump -h test4
~/rv32emu$ riscv-none-embed-objdump -d test4
~/rv32emu$ riscv-none-embed-size test4
## Catalan number
### C code
```cpp=
void _start()
{
volatile char* tx = (volatile char*) 0x40002000;
int n = 5;
int i = 0;
int j = 0;
int catalan[11];
int tmp1 = 0;
int tmp2 = 0;
int tmp3 = 0;
catalan[0] = 1;
catalan[1] = 1;
for (i = 2; i <= n; i++) {
catalan[i] = 0;
for (j = 0; j < i; j++)
tmp1 = catalan[i];
tmp2 = catalan[j];
tmp3 = catalan[i - j - 1];
catalan[i] = tmp1 + tmp2 * tmp3;
}
for (i = 0; i < n; i++) {
char c = catalan[i];
*tx = (char)(48 + c);
}
}
```
#### Result
```
>>> Execution time: 495 ns
>>> Instruction count: 4 (IPS=8080808)
>>> Jumps: 0 (0.00%) - 0 forwards, 0 backwards
>>> Branching T=0 (-nan%) F=0 (-nan%)
```
### Assembly code after compiling c code (-O3 option)
```cpp=
soonmyun@ubuntu:~/rv32emu$ riscv-none-embed-objdump -d test5
test5: file format elf32-littleriscv
Disassembly of section .text:
00010054 <_start>:
10054: 7179 addi sp,sp,-48
10056: 4785 li a5,1
10058: c43e sw a5,8(sp)
1005a: c602 sw zero,12(sp)
1005c: c802 sw zero,16(sp)
1005e: ca02 sw zero,20(sp)
10060: 400027b7 lui a5,0x40002
10064: 03100713 li a4,49
10068: 00e78023 sb a4,0(a5) # 40002000 <__global_pointer$+0x3fff0758>
1006c: 4722 lw a4,8(sp)
1006e: 03070713 addi a4,a4,48
10072: 0ff77713 andi a4,a4,255
10076: 00e78023 sb a4,0(a5)
1007a: 4732 lw a4,12(sp)
1007c: 03070713 addi a4,a4,48
10080: 0ff77713 andi a4,a4,255
10084: 00e78023 sb a4,0(a5)
10088: 4742 lw a4,16(sp)
1008a: 03070713 addi a4,a4,48
1008e: 0ff77713 andi a4,a4,255
10092: 00e78023 sb a4,0(a5)
10096: 4752 lw a4,20(sp)
10098: 03070713 addi a4,a4,48
1009c: 0ff77713 andi a4,a4,255
100a0: 00e78023 sb a4,0(a5)
100a4: 6145 addi sp,sp,48
100a6: 8082 ret
```
#### Display the ELF file header
```
soonmyun@ubuntu:~/rv32emu$ riscv-none-embed-readelf -h test5
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: RISC-V
Version: 0x1
Entry point address: 0x10054
Start of program headers: 52 (bytes into file)
Start of section headers: 552 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 1
Size of section headers: 40 (bytes)
Number of section headers: 6
Section header string table index: 5
```
### File size
```
soonmyun@ubuntu:~/rv32emu$ riscv-none-embed-gcc -march=rv32i -mabi=ilp32 -Os -nostdlib test5.c -o test5
soonmyun@ubuntu:~/rv32emu$ riscv-none-embed-size test5
text data bss dec hex filename
88 0 0 88 58 test5
soonmyun@ubuntu:~/rv32emu$ riscv-none-embed-gcc -march=rv32i -mabi=ilp32 -O3 -nostdlib test5.c -o test5
soonmyun@ubuntu:~/rv32emu$ riscv-none-embed-size test5
text data bss dec hex filename
112 0 0 112 70 test5
```
#### -Os Option
```cpp=
soonmyun@ubuntu:~/rv32emu$ riscv-none-embed-objdump -d test5
test5: file format elf32-littleriscv
Disassembly of section .text:
00010054 <_start>:
10054: 7179 addi sp,sp,-48
10056: 4785 li a5,1
10058: c23e sw a5,4(sp)
1005a: c43e sw a5,8(sp)
1005c: 005c addi a5,sp,4
1005e: 0854 addi a3,sp,20
10060: 873e mv a4,a5
10062: 00072423 sw zero,8(a4)
10066: 0711 addi a4,a4,4
10068: fee69de3 bne a3,a4,10062 <_start+0xe>
1006c: 01478693 addi a3,a5,20
10070: 40002637 lui a2,0x40002
10074: 4398 lw a4,0(a5)
10076: 0791 addi a5,a5,4
10078: 03070713 addi a4,a4,48
1007c: 0ff77713 andi a4,a4,255
10080: 00e60023 sb a4,0(a2) # 40002000 <__global_pointer$+0x3fff0774>
10084: fef698e3 bne a3,a5,10074 <_start+0x20>
10088: 6145 addi sp,sp,48
1008a: 8082 ret
```
## Multiplier
### C code
```cpp=
int divide(int n, int div);
int remain(int n, int rem);
void _start()
{
char str[10000];
volatile char* tx = (volatile char*) 0x40002000;
int mul1 = -11;
int mul2 = 11;
int result = 0 ;
int i = 0;
int num = 0;
int div = 0;
int rem = 0;
int kk = 5;
//printNum(9);
//convertToChar(321);
for(i=0;i<32;i++)
{
if((mul2 >> i) & 0x1)
result = result + (mul1 << i);
}
if(result < 0){
*tx = '-';
result = result * -1;
}
num = result;
int div_count = 0;
while(1){
div = divide(num, 10);
rem = remain(num, 10);
if(num > 0) {
num = div;
char new_char = (char)(rem + 48);
str[div_count] = new_char;
char *ch = &str[div_count];
*tx = *ch;
div_count ++;
}
else{
break;
}
}
}
int divide(int n, int div) {
int num = n;
int result = 0;
while (num >= 0) {
num = num - div;
if (num < 0) break;
result = result + 1;
}
return result;
}
int remain(int n, int rem) {
int result = 0;
while (1) {
n = n - rem;
if (n < 0) {
result = n + rem;
break;
}
}
return result;
}
```
#### Result

### Assembly code after compiling c code
```cpp=
soonmyun@ubuntu:~/rv32emu$ riscv-none-embed-objdump -d test4
test4: file format elf32-littleriscv
Disassembly of section .text:
00010054 <_start>:
10054: 00000793 li a5,0
10058: 00000613 li a2,0
1005c: 00b00813 li a6,11
10060: ff500513 li a0,-11
10064: 02000593 li a1,32
10068: 40f85733 sra a4,a6,a5
1006c: 00177713 andi a4,a4,1
10070: 00f516b3 sll a3,a0,a5
10074: 00178793 addi a5,a5,1
10078: 00070463 beqz a4,10080 <_start+0x2c>
1007c: 00d60633 add a2,a2,a3
10080: feb794e3 bne a5,a1,10068 <_start+0x14>
10084: 06064063 bltz a2,100e4 <_start+0x90>
10088: ff660793 addi a5,a2,-10
1008c: 400025b7 lui a1,0x40002
10090: 0407c263 bltz a5,100d4 <_start+0x80>
10094: 00000693 li a3,0
10098: ff678793 addi a5,a5,-10
1009c: 00168693 addi a3,a3,1
100a0: fe07dce3 bgez a5,10098 <_start+0x44>
100a4: 00060713 mv a4,a2
100a8: 0080006f j 100b0 <_start+0x5c>
100ac: 00078713 mv a4,a5
100b0: ff670793 addi a5,a4,-10
100b4: fe07dce3 bgez a5,100ac <_start+0x58>
100b8: 02060463 beqz a2,100e0 <_start+0x8c>
100bc: 03070713 addi a4,a4,48
100c0: 0ff77713 andi a4,a4,255
100c4: 00068613 mv a2,a3
100c8: 00e58023 sb a4,0(a1) # 40002000 <__global_pointer$+0x3fff0564>
100cc: ff660793 addi a5,a2,-10
100d0: fc07d2e3 bgez a5,10094 <_start+0x40>
100d4: 00060713 mv a4,a2
100d8: 00000693 li a3,0
100dc: fe0610e3 bnez a2,100bc <_start+0x68>
100e0: 00008067 ret
100e4: 400027b7 lui a5,0x40002
100e8: 02d00713 li a4,45
100ec: 00e78023 sb a4,0(a5) # 40002000 <__global_pointer$+0x3fff0564>
100f0: 40c00633 neg a2,a2
100f4: f95ff06f j 10088 <_start+0x34>
000100f8 <convertToChar>:
100f8: ff010113 addi sp,sp,-16
100fc: 00112623 sw ra,12(sp)
10100: 00812423 sw s0,8(sp)
10104: 12054663 bltz a0,10230 <convertToChar+0x138>
10108: ff650793 addi a5,a0,-10
1010c: 1007c663 bltz a5,10218 <convertToChar+0x120>
10110: fec50793 addi a5,a0,-20
10114: 00100713 li a4,1
10118: 0007c863 bltz a5,10128 <convertToChar+0x30>
1011c: ff678793 addi a5,a5,-10
10120: 00170713 addi a4,a4,1
10124: fe07dce3 bgez a5,1011c <convertToChar+0x24>
10128: 00050413 mv s0,a0
1012c: 0080006f j 10134 <convertToChar+0x3c>
10130: 00078413 mv s0,a5
10134: ff640793 addi a5,s0,-10
10138: fe07dce3 bgez a5,10130 <convertToChar+0x38>
1013c: 0ea04463 bgtz a0,10224 <convertToChar+0x12c>
10140: 0c805463 blez s0,10208 <convertToChar+0x110>
10144: 03040713 addi a4,s0,48
10148: 0ff77713 andi a4,a4,255
1014c: 400027b7 lui a5,0x40002
10150: 00e78023 sb a4,0(a5) # 40002000 <__global_pointer$+0x3fff0564>
10154: fff40713 addi a4,s0,-1
10158: 0a070863 beqz a4,10208 <convertToChar+0x110>
1015c: 02f40713 addi a4,s0,47
10160: 0ff77713 andi a4,a4,255
10164: 00e78023 sb a4,0(a5)
10168: ffe40713 addi a4,s0,-2
1016c: 08070e63 beqz a4,10208 <convertToChar+0x110>
10170: 02e40713 addi a4,s0,46
10174: 0ff77713 andi a4,a4,255
10178: 00e78023 sb a4,0(a5)
1017c: ffd40713 addi a4,s0,-3
10180: 08070463 beqz a4,10208 <convertToChar+0x110>
10184: 02d40713 addi a4,s0,45
10188: 0ff77713 andi a4,a4,255
1018c: 00e78023 sb a4,0(a5)
10190: ffc40713 addi a4,s0,-4
10194: 06070a63 beqz a4,10208 <convertToChar+0x110>
10198: 02c40713 addi a4,s0,44
1019c: 0ff77713 andi a4,a4,255
101a0: 00e78023 sb a4,0(a5)
101a4: ffb40713 addi a4,s0,-5
101a8: 06070063 beqz a4,10208 <convertToChar+0x110>
101ac: 02b40713 addi a4,s0,43
101b0: 0ff77713 andi a4,a4,255
101b4: 00e78023 sb a4,0(a5)
101b8: ffa40713 addi a4,s0,-6
101bc: 04070663 beqz a4,10208 <convertToChar+0x110>
101c0: 02a40713 addi a4,s0,42
101c4: 0ff77713 andi a4,a4,255
101c8: 00e78023 sb a4,0(a5)
101cc: ff940713 addi a4,s0,-7
101d0: 02070c63 beqz a4,10208 <convertToChar+0x110>
101d4: 02940713 addi a4,s0,41
101d8: 0ff77713 andi a4,a4,255
101dc: 00e78023 sb a4,0(a5)
101e0: ff840713 addi a4,s0,-8
101e4: 02070263 beqz a4,10208 <convertToChar+0x110>
101e8: 02840713 addi a4,s0,40
101ec: 0ff77713 andi a4,a4,255
101f0: 00e78023 sb a4,0(a5)
101f4: ff740413 addi s0,s0,-9
101f8: 00040863 beqz s0,10208 <convertToChar+0x110>
101fc: 03040413 addi s0,s0,48
10200: 0ff47413 andi s0,s0,255
10204: 00878023 sb s0,0(a5)
10208: 00c12083 lw ra,12(sp)
1020c: 00812403 lw s0,8(sp)
10210: 01010113 addi sp,sp,16
10214: 00008067 ret
10218: fe0508e3 beqz a0,10208 <convertToChar+0x110>
1021c: 00050413 mv s0,a0
10220: 00000713 li a4,0
10224: 00070513 mv a0,a4
10228: ed1ff0ef jal ra,100f8 <convertToChar>
1022c: f15ff06f j 10140 <convertToChar+0x48>
10230: 00000713 li a4,0
10234: ef5ff06f j 10128 <convertToChar+0x30>
00010238 <printNum>:
10238: 00a05e63 blez a0,10254 <printNum+0x1c>
1023c: 40002737 lui a4,0x40002
10240: 03050793 addi a5,a0,48
10244: 0ff7f793 andi a5,a5,255
10248: 00f70023 sb a5,0(a4) # 40002000 <__global_pointer$+0x3fff0564>
1024c: fff50513 addi a0,a0,-1
10250: fe0518e3 bnez a0,10240 <printNum+0x8>
10254: 00008067 ret
00010258 <divide>:
10258: 02054463 bltz a0,10280 <divide+0x28>
1025c: 40b50533 sub a0,a0,a1
10260: 02054063 bltz a0,10280 <divide+0x28>
10264: 40b507b3 sub a5,a0,a1
10268: 00100513 li a0,1
1026c: 0007cc63 bltz a5,10284 <divide+0x2c>
10270: 40b787b3 sub a5,a5,a1
10274: 00150513 addi a0,a0,1
10278: fe07dce3 bgez a5,10270 <divide+0x18>
1027c: 00008067 ret
10280: 00000513 li a0,0
10284: 00008067 ret
00010288 <remain>:
10288: 0080006f j 10290 <remain+0x8>
1028c: 00078513 mv a0,a5
10290: 40b507b3 sub a5,a0,a1
10294: fe07dce3 bgez a5,1028c <remain+0x4>
10298: 00008067 ret
```
```
soonmyun@ubuntu:~/rv32emu$ riscv-none-embed-readelf -h test4
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: RISC-V
Version: 0x1
Entry point address: 0x10054
Start of program headers: 52 (bytes into file)
Start of section headers: 1152 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 1
Size of section headers: 40 (bytes)
Number of section headers: 6
Section header string table index: 5
```
#### Compile option: -03 (speed)
```
soonmyun@ubuntu:~/rv32emu$ riscv-none-embed-size test4
text data bss dec hex filename
584 0 0 584 248 test4
```
#### Compile option: -0s (size)
```
soonmyun@ubuntu:~/rv32emu$ riscv-none-embed-gcc -march=rv32i -mabi=ilp32 -Os -nostdlib test4.c -o test4
soonmyun@ubuntu:~/rv32emu$ riscv-none-embed-size test4
text data bss dec hex filename
316 0 0 316 13c test4
```
Size of file with 0s option is smaller than with 03 option.