# 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. ![](https://i.imgur.com/S4xyNfc.png) - 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. ![](https://i.imgur.com/vC6hsW5.png) - 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. ![](https://i.imgur.com/sd5ayRs.png) ### 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 |