---
tags: CA2020
---
# Assignment2: RISC-V Toolchain-2
contributed by < `kevin30292` >
## GCD
The following assembly program was implemented by `洪邵澤`.
```cpp
.data
num1: .word 120 # number 1 (u)
num2: .word 78 # number 2 (v)
str1: .string "\n"
nums: .word 30 10
.text
main:
lw s0, num1 # u
lw s1, num2 # v
# check u or v is 0
beqz s1, print
beqz s0, assign
# use Euclidean algorithm
loop:
mv s2, s1
rem s1, s0, s1
mv s0, s2
bnez s1, loop
j print
assign:
mv s0, s1
j print
print:
addi a7, x0, 1 # print_int ecall
add a0, s0, x0 # integer
ecall
exit:
```
## Rewrite into C implementation
`gcd.c`
```c=
#include <stdio.h>
int _start() {
int s0 = 120;
int s1 = 78;
if(s1 == 0){
;
} else if(s0 == 0){
s0 = s1;
} else {
while(s1) {
int s2 = s1;
s1 = s0 % s1;
s0 = s2;
}
}
volatile char *tx = (volatile char *)0x40002000;
*tx = s0;
}
```

```c=
#include <stdio.h>
int mod(int a, int b)
{
int r = a;
while(r >= b) {
r = r - b;
}
return r;
}
int _start() {
int s0 = 120;
int s1 = 78;
if(s1 == 0){
;
} else if(s0 == 0){
s0 = s1;
} else {
int s2;
while(s1) {
s2 = s1;
s1 = mod(s0, s1);
s0 = s2;
}
}
volatile char *tx = (volatile char *)0x40002000;
*tx = (char)(s0 + '0');
return 0;
}
```
## Execute with `rv32emu`
```
$ riscv-none-embed-gcc -march=rv32i -mabi=ilp32 -O3 -nostdlib -o gcd gcd.c
```

## ELF files generated by C compiler

#### Compare the assembly
1. The ELF files generated by C compiler didn't branch back to mod.
->It merge the mod function in to _start
2. It's use stack to store the array temporary.
->It doesn't need to access memory so many times.
