# Lab2: RISC-V RV32I[MA] emulator with ELF support
contributed by < [geniuseric](https://github.com/geniuseric) >
## Requirement
[Assignment2: RISC-V Toolchain](https://hackmd.io/@sysprog/2021-arch-homework2)
## Palindrome Number
- I pick up the assembly program from [黃瑋盛](https://hackmd.io/@N9qHU_eLRvKyfDfJk8cDXA/Bk3xctfBF).
- This is the question from [LeetCode 9](https://leetcode.com/problems/palindrome-number/).
- An integer is a **palindrome** when it reads the same backward as forward. For example, `121` is palindrome while `123` is not.
- The reason why I choose this question is because **palindrome** is a new vocabulary to me. The meaning of this word also sounds intersting to me.
## Implementation
- Rewrite original C code into modified C code which can execute with [rv32emu](https://github.com/sysprog21/rv32emu).
- The original C code reverses the integer by all digits, I improve the code which it only reverses the integer by half of all digits. For example, `1221` is a palindrome number. The original C code has to check `1`、`2`、`2`、`1` four digits, but the modified C code only needs to check `1`、`2` two digits to know if it is a palindrome.
- In order to execute the C code in the emulator, the first problem I encounter is how to print an integer on the terminal. Therefore, I add `printf("%d", val)` at the line **883** in `emurv32i.c` and it works fine.

- The second problem I encounter is that there are undefined reference to `__modsi3` and `__divsi3`. Therefore, I have to write `mod` and `div` functions by myself.

- The **Original C Code** and the **Modified C Code** are shown below.
### Original C Code
```clike=
#include<stdio.h>
int is_Palindrome(int x){
if(x >= 0){
int tmp = x;
int rv_Int = 0;
while(tmp){
rv_Int *= 10;
rv_Int += tmp % 10;
tmp /= 10;
}
return x == rv_Int;
}
return 0;
}
int main(){
int data[5] = {0, 123456789, 12321, -878, -789};
for(int i=0; i<(sizeof(data)/sizeof(int)); i++){
if(is_Palindrome(data[i]))
printf("%d is palindrome\n", data[i]);
else
printf("%d is not palindrome\n", data[i]);
}
return 0;
}
```
### Modified C Code
```clike=
# define SIZE 4
int div(int a, int b){ // d = a / b
int d = 0;
while (a >= b){
a -= b;
d += 1;
}
return d;
}
int mod(int a, int b){ // m = a / b
int m = a;
while (m >= b)
m -= b;
return m;
}
int isPalindrome(int x){
if (x == 0)
return 1;
else if (x < 0 || mod(x, 10) == 0)
return 0;
else{
int temp = x;
int back_x = 0;
while (temp > back_x){
back_x = back_x * 10 + mod(temp, 10);
temp = div(temp, 10);
}
return (back_x == temp) || (div(back_x, 10) == temp);
}
}
void _start(){
int data[SIZE] = {-88, 10, 12321, 258852};
volatile char *tx_char = (volatile char *) 0x40002000;
volatile int *tx_int = (volatile int *) 0x40000008;
const char *isTrue = " is a palindrome!\n";
const char *isFalse = " is not a palindrome.\n";
int counter;
for (int i = 0; i < SIZE; i++){
int res = isPalindrome(data[i]);
*tx_int = data[i];
counter = 0;
if (res == 1){
while(*isTrue){
*tx_char = *isTrue;
isTrue++;
counter++;
}
isTrue -= counter;
}
else{
while(*isFalse){
*tx_char = *isFalse;
isFalse++;
counter++;
}
isFalse -= counter;
}
}
}
```
## Disassemble the ELF
- Modify the arguments specified by RV32I_CFLAGS to experiment.
- `-O1` and `-O3` are for speed optimization and `-Os` is for size optimization.
- Since the modified C code is very different from the original C code, the comparison between original handwritten and compiler optimized assembly code is unfair.
- However, the differences between different compiler optimized assembly codes are important.
- There is a bug when I use `-Os` for optimization.

### Compiler optimized with `-O0`
#### *objdump*
```asm=
isPalindrome: file format elf32-littleriscv
Disassembly of section .text:
00010074 <div>:
10074: fd010113 addi sp,sp,-48
10078: 02812623 sw s0,44(sp)
1007c: 03010413 addi s0,sp,48
10080: fca42e23 sw a0,-36(s0)
10084: fcb42c23 sw a1,-40(s0)
10088: fe042623 sw zero,-20(s0)
1008c: 0200006f j 100ac <div+0x38>
10090: fdc42703 lw a4,-36(s0)
10094: fd842783 lw a5,-40(s0)
10098: 40f707b3 sub a5,a4,a5
1009c: fcf42e23 sw a5,-36(s0)
100a0: fec42783 lw a5,-20(s0)
100a4: 00178793 addi a5,a5,1
100a8: fef42623 sw a5,-20(s0)
100ac: fdc42703 lw a4,-36(s0)
100b0: fd842783 lw a5,-40(s0)
100b4: fcf75ee3 bge a4,a5,10090 <div+0x1c>
100b8: fec42783 lw a5,-20(s0)
100bc: 00078513 mv a0,a5
100c0: 02c12403 lw s0,44(sp)
100c4: 03010113 addi sp,sp,48
100c8: 00008067 ret
000100cc <mod>:
100cc: fd010113 addi sp,sp,-48
100d0: 02812623 sw s0,44(sp)
100d4: 03010413 addi s0,sp,48
100d8: fca42e23 sw a0,-36(s0)
100dc: fcb42c23 sw a1,-40(s0)
100e0: fdc42783 lw a5,-36(s0)
100e4: fef42623 sw a5,-20(s0)
100e8: 0140006f j 100fc <mod+0x30>
100ec: fec42703 lw a4,-20(s0)
100f0: fd842783 lw a5,-40(s0)
100f4: 40f707b3 sub a5,a4,a5
100f8: fef42623 sw a5,-20(s0)
100fc: fec42703 lw a4,-20(s0)
10100: fd842783 lw a5,-40(s0)
10104: fef754e3 bge a4,a5,100ec <mod+0x20>
10108: fec42783 lw a5,-20(s0)
1010c: 00078513 mv a0,a5
10110: 02c12403 lw s0,44(sp)
10114: 03010113 addi sp,sp,48
10118: 00008067 ret
0001011c <isPalindrome>:
1011c: fd010113 addi sp,sp,-48
10120: 02112623 sw ra,44(sp)
10124: 02812423 sw s0,40(sp)
10128: 02912223 sw s1,36(sp)
1012c: 03010413 addi s0,sp,48
10130: fca42e23 sw a0,-36(s0)
10134: fdc42783 lw a5,-36(s0)
10138: 00079663 bnez a5,10144 <isPalindrome+0x28>
1013c: 00100793 li a5,1
10140: 0b40006f j 101f4 <isPalindrome+0xd8>
10144: fdc42783 lw a5,-36(s0)
10148: 0007cc63 bltz a5,10160 <isPalindrome+0x44>
1014c: 00a00593 li a1,10
10150: fdc42503 lw a0,-36(s0)
10154: f79ff0ef jal ra,100cc <mod>
10158: 00050793 mv a5,a0
1015c: 00079663 bnez a5,10168 <isPalindrome+0x4c>
10160: 00000793 li a5,0
10164: 0900006f j 101f4 <isPalindrome+0xd8>
10168: fdc42783 lw a5,-36(s0)
1016c: fef42623 sw a5,-20(s0)
10170: fe042423 sw zero,-24(s0)
10174: 0440006f j 101b8 <isPalindrome+0x9c>
10178: fe842703 lw a4,-24(s0)
1017c: 00070793 mv a5,a4
10180: 00279793 slli a5,a5,0x2
10184: 00e787b3 add a5,a5,a4
10188: 00179793 slli a5,a5,0x1
1018c: 00078493 mv s1,a5
10190: 00a00593 li a1,10
10194: fec42503 lw a0,-20(s0)
10198: f35ff0ef jal ra,100cc <mod>
1019c: 00050793 mv a5,a0
101a0: 00f487b3 add a5,s1,a5
101a4: fef42423 sw a5,-24(s0)
101a8: 00a00593 li a1,10
101ac: fec42503 lw a0,-20(s0)
101b0: ec5ff0ef jal ra,10074 <div>
101b4: fea42623 sw a0,-20(s0)
101b8: fec42703 lw a4,-20(s0)
101bc: fe842783 lw a5,-24(s0)
101c0: fae7cce3 blt a5,a4,10178 <isPalindrome+0x5c>
101c4: fe842703 lw a4,-24(s0)
101c8: fec42783 lw a5,-20(s0)
101cc: 00f70e63 beq a4,a5,101e8 <isPalindrome+0xcc>
101d0: 00a00593 li a1,10
101d4: fe842503 lw a0,-24(s0)
101d8: e9dff0ef jal ra,10074 <div>
101dc: 00050713 mv a4,a0
101e0: fec42783 lw a5,-20(s0)
101e4: 00e79663 bne a5,a4,101f0 <isPalindrome+0xd4>
101e8: 00100793 li a5,1
101ec: 0080006f j 101f4 <isPalindrome+0xd8>
101f0: 00000793 li a5,0
101f4: 00078513 mv a0,a5
101f8: 02c12083 lw ra,44(sp)
101fc: 02812403 lw s0,40(sp)
10200: 02412483 lw s1,36(sp)
10204: 03010113 addi sp,sp,48
10208: 00008067 ret
0001020c <_start>:
1020c: fc010113 addi sp,sp,-64
10210: 02112e23 sw ra,60(sp)
10214: 02812c23 sw s0,56(sp)
10218: 04010413 addi s0,sp,64
1021c: 000107b7 lui a5,0x10
10220: 3b878793 addi a5,a5,952 # 103b8 <_start+0x1ac>
10224: 0007a603 lw a2,0(a5)
10228: 0047a683 lw a3,4(a5)
1022c: 0087a703 lw a4,8(a5)
10230: 00c7a783 lw a5,12(a5)
10234: fcc42223 sw a2,-60(s0)
10238: fcd42423 sw a3,-56(s0)
1023c: fce42623 sw a4,-52(s0)
10240: fcf42823 sw a5,-48(s0)
10244: 400027b7 lui a5,0x40002
10248: fcf42e23 sw a5,-36(s0)
1024c: 400007b7 lui a5,0x40000
10250: 00878793 addi a5,a5,8 # 40000008 <__global_pointer$+0x3ffee438>
10254: fcf42c23 sw a5,-40(s0)
10258: 000107b7 lui a5,0x10
1025c: 38c78793 addi a5,a5,908 # 1038c <_start+0x180>
10260: fef42623 sw a5,-20(s0)
10264: 000107b7 lui a5,0x10
10268: 3a078793 addi a5,a5,928 # 103a0 <_start+0x194>
1026c: fef42423 sw a5,-24(s0)
10270: fe042023 sw zero,-32(s0)
10274: 0f40006f j 10368 <_start+0x15c>
10278: fe042783 lw a5,-32(s0)
1027c: 00279793 slli a5,a5,0x2
10280: ff040713 addi a4,s0,-16
10284: 00f707b3 add a5,a4,a5
10288: fd47a783 lw a5,-44(a5)
1028c: 00078513 mv a0,a5
10290: e8dff0ef jal ra,1011c <isPalindrome>
10294: fca42a23 sw a0,-44(s0)
10298: fe042783 lw a5,-32(s0)
1029c: 00279793 slli a5,a5,0x2
102a0: ff040713 addi a4,s0,-16
102a4: 00f707b3 add a5,a4,a5
102a8: fd47a703 lw a4,-44(a5)
102ac: fd842783 lw a5,-40(s0)
102b0: 00e7a023 sw a4,0(a5)
102b4: fe042223 sw zero,-28(s0)
102b8: fd442703 lw a4,-44(s0)
102bc: 00100793 li a5,1
102c0: 06f71e63 bne a4,a5,1033c <_start+0x130>
102c4: 02c0006f j 102f0 <_start+0xe4>
102c8: fec42783 lw a5,-20(s0)
102cc: 0007c703 lbu a4,0(a5)
102d0: fdc42783 lw a5,-36(s0)
102d4: 00e78023 sb a4,0(a5)
102d8: fec42783 lw a5,-20(s0)
102dc: 00178793 addi a5,a5,1
102e0: fef42623 sw a5,-20(s0)
102e4: fe442783 lw a5,-28(s0)
102e8: 00178793 addi a5,a5,1
102ec: fef42223 sw a5,-28(s0)
102f0: fec42783 lw a5,-20(s0)
102f4: 0007c783 lbu a5,0(a5)
102f8: fc0798e3 bnez a5,102c8 <_start+0xbc>
102fc: fe442783 lw a5,-28(s0)
10300: 40f007b3 neg a5,a5
10304: fec42703 lw a4,-20(s0)
10308: 00f707b3 add a5,a4,a5
1030c: fef42623 sw a5,-20(s0)
10310: 04c0006f j 1035c <_start+0x150>
10314: fe842783 lw a5,-24(s0)
10318: 0007c703 lbu a4,0(a5)
1031c: fdc42783 lw a5,-36(s0)
10320: 00e78023 sb a4,0(a5)
10324: fe842783 lw a5,-24(s0)
10328: 00178793 addi a5,a5,1
1032c: fef42423 sw a5,-24(s0)
10330: fe442783 lw a5,-28(s0)
10334: 00178793 addi a5,a5,1
10338: fef42223 sw a5,-28(s0)
1033c: fe842783 lw a5,-24(s0)
10340: 0007c783 lbu a5,0(a5)
10344: fc0798e3 bnez a5,10314 <_start+0x108>
10348: fe442783 lw a5,-28(s0)
1034c: 40f007b3 neg a5,a5
10350: fe842703 lw a4,-24(s0)
10354: 00f707b3 add a5,a4,a5
10358: fef42423 sw a5,-24(s0)
1035c: fe042783 lw a5,-32(s0)
10360: 00178793 addi a5,a5,1
10364: fef42023 sw a5,-32(s0)
10368: fe042703 lw a4,-32(s0)
1036c: 00300793 li a5,3
10370: f0e7d4e3 bge a5,a4,10278 <_start+0x6c>
10374: 00000013 nop
10378: 00000013 nop
1037c: 03c12083 lw ra,60(sp)
10380: 03812403 lw s0,56(sp)
10384: 04010113 addi sp,sp,64
10388: 00008067 ret
```
#### *readelf*
```c =
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: 0x1020c
Start of program headers: 52 (bytes into file)
Start of section headers: 1504 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 2
Size of section headers: 40 (bytes)
Number of section headers: 9
Section header string table index: 8
```
#### *size*
```c =
text data bss dec hex filename
852 8 0 860 35c isPalindrome
```
### Compiler optimized with `-O1`
#### *objdump*
```asm=
isPalindrome: file format elf32-littleriscv
Disassembly of section .text:
00010074 <div>:
10074: 00050793 mv a5,a0
10078: 00b54c63 blt a0,a1,10090 <div+0x1c>
1007c: 00000513 li a0,0
10080: 40b787b3 sub a5,a5,a1
10084: 00150513 addi a0,a0,1
10088: feb7dce3 bge a5,a1,10080 <div+0xc>
1008c: 00008067 ret
10090: 00000513 li a0,0
10094: 00008067 ret
00010098 <mod>:
10098: 00b54663 blt a0,a1,100a4 <mod+0xc>
1009c: 40b50533 sub a0,a0,a1
100a0: feb55ee3 bge a0,a1,1009c <mod+0x4>
100a4: 00008067 ret
000100a8 <isPalindrome>:
100a8: 00050693 mv a3,a0
100ac: 0a050663 beqz a0,10158 <isPalindrome+0xb0>
100b0: 00000513 li a0,0
100b4: 0206c063 bltz a3,100d4 <isPalindrome+0x2c>
100b8: 00900793 li a5,9
100bc: 00d7de63 bge a5,a3,100d8 <isPalindrome+0x30>
100c0: 00068513 mv a0,a3
100c4: ff650513 addi a0,a0,-10
100c8: fea7cee3 blt a5,a0,100c4 <isPalindrome+0x1c>
100cc: 00000793 li a5,0
100d0: 00051663 bnez a0,100dc <isPalindrome+0x34>
100d4: 00008067 ret
100d8: 00000793 li a5,0
100dc: 00900613 li a2,9
100e0: 0140006f j 100f4 <isPalindrome+0x4c>
100e4: ff670713 addi a4,a4,-10
100e8: 00168693 addi a3,a3,1
100ec: fee64ce3 blt a2,a4,100e4 <isPalindrome+0x3c>
100f0: 02d7d863 bge a5,a3,10120 <isPalindrome+0x78>
100f4: 00279713 slli a4,a5,0x2
100f8: 00f707b3 add a5,a4,a5
100fc: 00179713 slli a4,a5,0x1
10100: 06d65063 bge a2,a3,10160 <isPalindrome+0xb8>
10104: 00068793 mv a5,a3
10108: ff678793 addi a5,a5,-10
1010c: fef64ee3 blt a2,a5,10108 <isPalindrome+0x60>
10110: 00f707b3 add a5,a4,a5
10114: 00068713 mv a4,a3
10118: 00000693 li a3,0
1011c: fc9ff06f j 100e4 <isPalindrome+0x3c>
10120: 00100513 li a0,1
10124: fad788e3 beq a5,a3,100d4 <isPalindrome+0x2c>
10128: 00900713 li a4,9
1012c: 02f75263 bge a4,a5,10150 <isPalindrome+0xa8>
10130: 00000713 li a4,0
10134: 00900613 li a2,9
10138: ff678793 addi a5,a5,-10
1013c: 00170713 addi a4,a4,1
10140: fef64ce3 blt a2,a5,10138 <isPalindrome+0x90>
10144: 40e686b3 sub a3,a3,a4
10148: 0016b513 seqz a0,a3
1014c: 00008067 ret
10150: 00000713 li a4,0
10154: ff1ff06f j 10144 <isPalindrome+0x9c>
10158: 00100513 li a0,1
1015c: 00008067 ret
10160: 00d707b3 add a5,a4,a3
10164: 00000693 li a3,0
10168: f89ff06f j 100f0 <isPalindrome+0x48>
0001016c <_start>:
1016c: fc010113 addi sp,sp,-64
10170: 02112e23 sw ra,60(sp)
10174: 02812c23 sw s0,56(sp)
10178: 02912a23 sw s1,52(sp)
1017c: 03212823 sw s2,48(sp)
10180: 03312623 sw s3,44(sp)
10184: 03412423 sw s4,40(sp)
10188: 03512223 sw s5,36(sp)
1018c: 03612023 sw s6,32(sp)
10190: 01712e23 sw s7,28(sp)
10194: fa800793 li a5,-88
10198: 00f12023 sw a5,0(sp)
1019c: 00a00793 li a5,10
101a0: 00f12223 sw a5,4(sp)
101a4: 000037b7 lui a5,0x3
101a8: 02178793 addi a5,a5,33 # 3021 <div-0xd053>
101ac: 00f12423 sw a5,8(sp)
101b0: 0003f7b7 lui a5,0x3f
101b4: 32478793 addi a5,a5,804 # 3f324 <__global_pointer$+0x2d874>
101b8: 00f12623 sw a5,12(sp)
101bc: 00010993 mv s3,sp
101c0: 01010b93 addi s7,sp,16
101c4: 00010437 lui s0,0x10
101c8: 28440413 addi s0,s0,644 # 10284 <_start+0x118>
101cc: 000104b7 lui s1,0x10
101d0: 29c48493 addi s1,s1,668 # 1029c <_start+0x130>
101d4: 40000b37 lui s6,0x40000
101d8: 00100a93 li s5,1
101dc: 40002937 lui s2,0x40002
101e0: 0400006f j 10220 <_start+0xb4>
101e4: 0004c783 lbu a5,0(s1)
101e8: 02078263 beqz a5,1020c <_start+0xa0>
101ec: 00000713 li a4,0
101f0: 00f90023 sb a5,0(s2) # 40002000 <__global_pointer$+0x3fff0550>
101f4: 00148493 addi s1,s1,1
101f8: 00170713 addi a4,a4,1
101fc: 0004c783 lbu a5,0(s1)
10200: fe0798e3 bnez a5,101f0 <_start+0x84>
10204: 40e484b3 sub s1,s1,a4
10208: 0100006f j 10218 <_start+0xac>
1020c: 00000713 li a4,0
10210: ff5ff06f j 10204 <_start+0x98>
10214: 40e40433 sub s0,s0,a4
10218: 00498993 addi s3,s3,4
1021c: 033b8e63 beq s7,s3,10258 <_start+0xec>
10220: 0009aa03 lw s4,0(s3)
10224: 000a0513 mv a0,s4
10228: e81ff0ef jal ra,100a8 <isPalindrome>
1022c: 014b2423 sw s4,8(s6) # 40000008 <__global_pointer$+0x3ffee558>
10230: fb550ae3 beq a0,s5,101e4 <_start+0x78>
10234: 00044783 lbu a5,0(s0)
10238: 00000713 li a4,0
1023c: fc078ce3 beqz a5,10214 <_start+0xa8>
10240: 00f90023 sb a5,0(s2)
10244: 00140413 addi s0,s0,1
10248: 00170713 addi a4,a4,1
1024c: 00044783 lbu a5,0(s0)
10250: fe0798e3 bnez a5,10240 <_start+0xd4>
10254: fc1ff06f j 10214 <_start+0xa8>
10258: 03c12083 lw ra,60(sp)
1025c: 03812403 lw s0,56(sp)
10260: 03412483 lw s1,52(sp)
10264: 03012903 lw s2,48(sp)
10268: 02c12983 lw s3,44(sp)
1026c: 02812a03 lw s4,40(sp)
10270: 02412a83 lw s5,36(sp)
10274: 02012b03 lw s6,32(sp)
10278: 01c12b83 lw s7,28(sp)
1027c: 04010113 addi sp,sp,64
10280: 00008067 ret
```
#### *readelf*
```c =
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: 0x1016c
Start of program headers: 52 (bytes into file)
Start of section headers: 1216 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 2
Size of section headers: 40 (bytes)
Number of section headers: 9
Section header string table index: 8
```
#### *size*
```c =
text data bss dec hex filename
571 1 0 572 23c isPalindrome
```
### Compiler optimized with `-O3`
#### *objdump*
```asm=
isPalindrome: file format elf32-littleriscv
Disassembly of section .text:
00010074 <div>:
10074: 00050793 mv a5,a0
10078: 00000513 li a0,0
1007c: 00b7ca63 blt a5,a1,10090 <div+0x1c>
10080: 40b787b3 sub a5,a5,a1
10084: 00150513 addi a0,a0,1
10088: feb7dce3 bge a5,a1,10080 <div+0xc>
1008c: 00008067 ret
10090: 00008067 ret
00010094 <mod>:
10094: 00b54663 blt a0,a1,100a0 <mod+0xc>
10098: 40b50533 sub a0,a0,a1
1009c: feb55ee3 bge a0,a1,10098 <mod+0x4>
100a0: 00008067 ret
000100a4 <isPalindrome>:
100a4: 00050693 mv a3,a0
100a8: 08050c63 beqz a0,10140 <isPalindrome+0x9c>
100ac: 00000513 li a0,0
100b0: 0006ce63 bltz a3,100cc <isPalindrome+0x28>
100b4: 00900793 li a5,9
100b8: 00d7dc63 bge a5,a3,100d0 <isPalindrome+0x2c>
100bc: 00068513 mv a0,a3
100c0: ff650513 addi a0,a0,-10
100c4: fea7cee3 blt a5,a0,100c0 <isPalindrome+0x1c>
100c8: 00051463 bnez a0,100d0 <isPalindrome+0x2c>
100cc: 00008067 ret
100d0: 00000793 li a5,0
100d4: 00900613 li a2,9
100d8: 00279593 slli a1,a5,0x2
100dc: 00f587b3 add a5,a1,a5
100e0: 00179593 slli a1,a5,0x1
100e4: 06d65663 bge a2,a3,10150 <isPalindrome+0xac>
100e8: 00068793 mv a5,a3
100ec: ff678793 addi a5,a5,-10
100f0: fef64ee3 blt a2,a5,100ec <isPalindrome+0x48>
100f4: 00068713 mv a4,a3
100f8: 00f587b3 add a5,a1,a5
100fc: 00000693 li a3,0
10100: ff670713 addi a4,a4,-10
10104: 00168693 addi a3,a3,1
10108: fee64ce3 blt a2,a4,10100 <isPalindrome+0x5c>
1010c: fcd7c6e3 blt a5,a3,100d8 <isPalindrome+0x34>
10110: 00100513 li a0,1
10114: faf68ce3 beq a3,a5,100cc <isPalindrome+0x28>
10118: 00900713 li a4,9
1011c: 02f75663 bge a4,a5,10148 <isPalindrome+0xa4>
10120: 00000713 li a4,0
10124: 00900613 li a2,9
10128: ff678793 addi a5,a5,-10
1012c: 00170713 addi a4,a4,1
10130: fef64ce3 blt a2,a5,10128 <isPalindrome+0x84>
10134: 40d70733 sub a4,a4,a3
10138: 00173513 seqz a0,a4
1013c: 00008067 ret
10140: 00100513 li a0,1
10144: 00008067 ret
10148: 00000713 li a4,0
1014c: fe9ff06f j 10134 <isPalindrome+0x90>
10150: 00b687b3 add a5,a3,a1
10154: 00000693 li a3,0
10158: fc1ff06f j 10118 <isPalindrome+0x74>
0001015c <_start>:
1015c: ff010113 addi sp,sp,-16
10160: fa800793 li a5,-88
10164: 00f12023 sw a5,0(sp)
10168: 00a00793 li a5,10
1016c: 00f12223 sw a5,4(sp)
10170: 000037b7 lui a5,0x3
10174: 02178793 addi a5,a5,33 # 3021 <div-0xd053>
10178: 00f12423 sw a5,8(sp)
1017c: 0003f7b7 lui a5,0x3f
10180: 32478793 addi a5,a5,804 # 3f324 <__global_pointer$+0x2d844>
10184: 000105b7 lui a1,0x10
10188: 00010837 lui a6,0x10
1018c: 00f12623 sw a5,12(sp)
10190: 00010e13 mv t3,sp
10194: 01010e93 addi t4,sp,16
10198: 2b458593 addi a1,a1,692 # 102b4 <_start+0x158>
1019c: 2cc80813 addi a6,a6,716 # 102cc <_start+0x170>
101a0: 400028b7 lui a7,0x40002
101a4: 40000f37 lui t5,0x40000
101a8: 00900613 li a2,9
101ac: 000e2303 lw t1,0(t3)
101b0: 0e030063 beqz t1,10290 <_start+0x134>
101b4: 00034c63 bltz t1,101cc <_start+0x70>
101b8: 0e665463 bge a2,t1,102a0 <_start+0x144>
101bc: 00030793 mv a5,t1
101c0: ff678793 addi a5,a5,-10
101c4: fef64ee3 blt a2,a5,101c0 <_start+0x64>
101c8: 02079e63 bnez a5,10204 <_start+0xa8>
101cc: 006f2423 sw t1,8(t5) # 40000008 <__global_pointer$+0x3ffee528>
101d0: 0005c783 lbu a5,0(a1)
101d4: 00000713 li a4,0
101d8: 00078e63 beqz a5,101f4 <_start+0x98>
101dc: 00f88023 sb a5,0(a7) # 40002000 <__global_pointer$+0x3fff0520>
101e0: 0015c783 lbu a5,1(a1)
101e4: 00170713 addi a4,a4,1
101e8: 00158593 addi a1,a1,1
101ec: fe0798e3 bnez a5,101dc <_start+0x80>
101f0: 40e585b3 sub a1,a1,a4
101f4: 004e0e13 addi t3,t3,4
101f8: fbce9ae3 bne t4,t3,101ac <_start+0x50>
101fc: 01010113 addi sp,sp,16
10200: 00008067 ret
10204: 00030693 mv a3,t1
10208: 00000793 li a5,0
1020c: 00279513 slli a0,a5,0x2
10210: 00f507b3 add a5,a0,a5
10214: 00179513 slli a0,a5,0x1
10218: 00050793 mv a5,a0
1021c: 08d65663 bge a2,a3,102a8 <_start+0x14c>
10220: 00068793 mv a5,a3
10224: ff678793 addi a5,a5,-10
10228: fef64ee3 blt a2,a5,10224 <_start+0xc8>
1022c: 00068713 mv a4,a3
10230: 00f507b3 add a5,a0,a5
10234: 00000693 li a3,0
10238: ff670713 addi a4,a4,-10
1023c: 00168693 addi a3,a3,1
10240: fee64ce3 blt a2,a4,10238 <_start+0xdc>
10244: fcd7c4e3 blt a5,a3,1020c <_start+0xb0>
10248: 04d78863 beq a5,a3,10298 <_start+0x13c>
1024c: 00000713 li a4,0
10250: 00f65863 bge a2,a5,10260 <_start+0x104>
10254: ff678793 addi a5,a5,-10
10258: 00170713 addi a4,a4,1
1025c: fef64ce3 blt a2,a5,10254 <_start+0xf8>
10260: 006f2423 sw t1,8(t5)
10264: f6d716e3 bne a4,a3,101d0 <_start+0x74>
10268: 00084783 lbu a5,0(a6)
1026c: 00000713 li a4,0
10270: f80782e3 beqz a5,101f4 <_start+0x98>
10274: 00f88023 sb a5,0(a7)
10278: 00184783 lbu a5,1(a6)
1027c: 00170713 addi a4,a4,1
10280: 00180813 addi a6,a6,1
10284: fe0798e3 bnez a5,10274 <_start+0x118>
10288: 40e80833 sub a6,a6,a4
1028c: f69ff06f j 101f4 <_start+0x98>
10290: 000f2423 sw zero,8(t5)
10294: fd5ff06f j 10268 <_start+0x10c>
10298: 006f2423 sw t1,8(t5)
1029c: fcdff06f j 10268 <_start+0x10c>
102a0: 00030693 mv a3,t1
102a4: 00000793 li a5,0
102a8: 00d787b3 add a5,a5,a3
102ac: 00000693 li a3,0
102b0: f9dff06f j 1024c <_start+0xf0>
```
#### *readelf*
```c =
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: 0x1015c
Start of program headers: 52 (bytes into file)
Start of section headers: 1264 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 2
Size of section headers: 40 (bytes)
Number of section headers: 9
Section header string table index: 8
```
#### *size*
```c =
text data bss dec hex filename
619 1 0 620 26c isPalindrome
```
## Check the result
- The results and statistics of execution flow are shown below.
### Compiler optimized with `-O0`
```c =
./emu-rv32i isPalindrome
-88 is not a palindrome.
10 is not a palindrome.
12321 is a palindrome!
258852 is a palindrome!
>>> Execution time: 122751361 ns
>>> Instruction count: 703301 (IPS=5729476)
>>> Jumps: 87494 (12.44%) - 57 forwards, 87437 backwards
>>> Branching T=87426 (99.96%) F=31 (0.04%)
```
### Compiler optimized with `-O1`
```c =
./emu-rv32i isPalindrome
-88 is not a palindrome.
10 is not a palindrome.
12321 is a palindrome!
258852 is a palindrome!
>>> Execution time: 58340944 ns
>>> Instruction count: 205361 (IPS=3520015)
>>> Jumps: 87417 (42.57%) - 15 forwards, 87402 backwards
>>> Branching T=87395 (99.94%) F=52 (0.06%)
```
### Compiler optimized with `-O3`
```c =
./emu-rv32i isPalindrome
-88 is not a palindrome.
10 is not a palindrome.
12321 is a palindrome!
258852 is a palindrome!
>>> Execution time: 36123699 ns
>>> Instruction count: 205306 (IPS=5683415)
>>> Jumps: 87401 (42.57%) - 4 forwards, 87397 backwards
>>> Branching T=87397 (99.95%) F=47 (0.05%)
```
## Compare different codes and results
- `-O1` has the least code lines, `-O0` has the most.
- `-O0` uses registers `s0-s1`, `a0-a5`, `sp`, `ra`. `-O1` uses registers `s0-s7`, `a0-a5`, `sp`, `ra`. `-O3` uses registers `t1, t3-t5`, `a0-a7`, `sp`.
- `-O3` uses the least stack size, `-O0` uses the most.
- `-O3` has the least instruction counts, `-O0` has the most.
- `-O3` and `-O1` have similar instruction counts, the execution time of them are also similar. `-O0` has the longest execution time.
| | -O0 | -O1 | -O3 |
| -------- | -------- | -------- | -------- |
| Code line | 202 | 136 | 148 |
| Register Number | 10 | 16 | 13 |
| Stack Size | 48 | 64 | 16 |
| Instruction count | 703301 | 205361 | 205306 |
| Execution time | 122751361 ns | 58340944 ns| 36123699 ns |