---
tags : Computer Architecture
---
# Assignment2: RISC-V Toolchain
[TOC]
## Introduction
This is referenced from `魏晉成` [Format printer](https://hackmd.io/@H-L-Parker/S1dMsbx8w)
Original support : `%s`, `%b`, `%c`, `%o`, `%x`, `%X`
I add `%d`
## C Code Implement
### printer.h
``` clike=
#ifndef _PRINTER_
#define _PRINTER_
extern volatile char *tx;
int div(int a, int b);
int mod(int a, int b);
int self_printf(const char* str, ...);
#endif
```
### printer.c
``` clike=
#include "printer.h"
#include <stdarg.h>
volatile char *tx = (volatile char*) 0x40002000;
////// return floor(a / b) //////
int div(int a, int b){
int counter = 0;
while(a>=0){
a = a-b;
counter++;
}
return counter-1;
}
////// return (a % b) //////
int mod(int a, int b){
int t = 0;
while(a>=0){
t = a;
a = a-b;
}
return t;
}
int self_printf(const char* str, ...){
va_list ap;
va_start(ap, str);
int status = 0;
char pr[32];
int index = 0;
while(*str != '\0'){
char t = *str;
if(status == 1){
switch(t){
case 's':{
char *s = va_arg(ap, char*);
while(*s!='\0')
*tx = *s++;
break;
}
case 'c':{
char c = (char)va_arg(ap, int);
*tx = c;
break;
}
case 'b':{
int b = va_arg(ap, int);
while(b!=0){
pr[index++] = (b&0x1) + '0';
b = b>>1;
}
if(index == 0){
*tx = '0';
break;
}
while(index > 0)
*tx = pr[--index];
break;
}
case 'o':{
int o = va_arg(ap, int);
while(o!=0){
pr[index++] = (o&0x7) + '0';
o = o>>3;
}
if(index == 0){
*tx = '0';
break;
}
while(index > 0)
*tx = pr[--index];
break;
}
case 'x':{
int x = va_arg(ap, int);
int xx = 0;
while(x!=0){
xx = (x&0xf);
if(xx > 9)
pr[index++] = xx + 87;
else
pr[index++] = xx + '0';
x = x>>4;
}
if(index == 0){
*tx = '0';
break;
}
while(index > 0)
*tx = pr[--index];
break;
}
case 'X':{
int X = va_arg(ap, int);
int XX = 0;
while(X!=0){
XX = (X&0xf);
if(XX > 9)
pr[index++] = XX + 55;
else
pr[index++] = XX + '0';
X = X>>4;
}
if(index == 0){
*tx = '0';
break;
}
while(index > 0)
*tx = pr[--index];
break;
}
case 'd':{
int d = va_arg(ap, int);
if((d>>31) != 0){
*tx = '-';
d = ~(d-1);
}
while(d != 0){
int dd = mod(d, 10);
d = div(d, 10);
pr[index++] = dd + '0';
}
if(index == 0){
*tx = '0';
break;
}
while(index>0)
*tx = pr[--index];
break;
}
default:
*tx = t;
}
status = 0;
index = 0;
}
else{
if(t != '%')
*tx = t;
else
status = 1;
}
str++;
}
va_end(ap);
return 1;
}
```
### printer_test.c (test)
``` clike=
#include <stdio.h>
#include "printer.h"
int _start()
{
char *pChr = "StringInArg";
char chr = 'c';
unsigned int testHex0 = 0x102345,
testHex1 = 0x6789AB,
testHex2 = 0xCDEF,
testOct = 012345670,
testBin = 0b00111011000101001111010100001111;
int testInt1 = -50698,
testInt2 = 2147483647,
zero;
int a = self_printf("%s\nnormalString\nCharInArg: %c\nPercentSign: %%\nNot supporting: %e%e%r%a%%%y\nHexZeroCheck: %x %X\nHex0: %x %X\nHex1: %x %X\nHex2: %x %X\nOctZeroCheck: %o\nOct: %o\nBinZeroCheck: %b\nBin: %b\nIntZeroCheck: %d\nInt: %d, %d\n", pChr, chr, zero, zero, testHex0, testHex0, testHex1, testHex1, testHex2, testHex2, zero, testOct, zero, testBin, zero, testInt1, testInt2);
return 0;
}
```
## Execute it
```
cc -O3 -Wall -std=gnu99 -o emu-rv32i emu-rv32i.c -lelf
riscv-none-embed-gcc -march=rv32i -mabi=ilp32 -O3 -nostdlib -o test printer_test.c printer.c
./emu-rv32i test
StringInArg
normalString
CharInArg: c
PercentSign: %
Not supporting: eera%y
HexZeroCheck: 0 0
Hex0: 102345 102345
Hex1: 6789ab 6789AB
Hex2: cdef CDEF
OctZeroCheck: 0
Oct: 12345670
BinZeroCheck: 0
Bin: 111011000101001111010100001111
IntZeroCheck: 0
Int: -50698, 2147483647
>>> Execution time: 40785850750 ns
>>> Instruction count: 1670308164 (IPS=40953127)
>>> Jumps: 477230284 (28.57%) - 95 forwards, 477230189 backwards
>>> Branching T=477230190 (100.00%) F=363 (0.00%)
```
## Toolchain
### $ riscv-none-embed-objdump -d test
```
test: file format elf32-littleriscv
Disassembly of section .text:
00010074 <_start>:
10074: 800006b7 lui a3,0x80000
10078: fc010113 addi sp,sp,-64
1007c: fff6c693 not a3,a3
10080: 02d12223 sw a3,36(sp)
10084: ffff46b7 lui a3,0xffff4
10088: 9f668693 addi a3,a3,-1546 # ffff39f6 <__global_pointer$+0xfffe1b22>
1008c: 02d12023 sw a3,32(sp)
10090: 3b14f6b7 lui a3,0x3b14f
10094: 50f68693 addi a3,a3,1295 # 3b14f50f <__global_pointer$+0x3b13d63b>
10098: 00d12c23 sw a3,24(sp)
1009c: 0000d7b7 lui a5,0xd
100a0: 006798b7 lui a7,0x679
100a4: 00102837 lui a6,0x102
100a8: 0029d6b7 lui a3,0x29d
100ac: 00000713 li a4,0
100b0: def78793 addi a5,a5,-529 # cdef <_start-0x3285>
100b4: 9ab88893 addi a7,a7,-1621 # 6789ab <__global_pointer$+0x666ad7>
100b8: 34580813 addi a6,a6,837 # 102345 <__global_pointer$+0xf0471>
100bc: bb868693 addi a3,a3,-1096 # 29cbb8 <__global_pointer$+0x28ace4>
100c0: 000105b7 lui a1,0x10
100c4: 00010537 lui a0,0x10
100c8: 00d12823 sw a3,16(sp)
100cc: 00f12423 sw a5,8(sp)
100d0: 00f12223 sw a5,4(sp)
100d4: 00e12e23 sw a4,28(sp)
100d8: 00e12a23 sw a4,20(sp)
100dc: 00e12623 sw a4,12(sp)
100e0: 01112023 sw a7,0(sp)
100e4: 00080793 mv a5,a6
100e8: 00070693 mv a3,a4
100ec: 06300613 li a2,99
100f0: 56458593 addi a1,a1,1380 # 10564 <self_printf+0x408>
100f4: 57050513 addi a0,a0,1392 # 10570 <self_printf+0x414>
100f8: 02112e23 sw ra,60(sp)
100fc: 060000ef jal ra,1015c <self_printf>
10100: 03c12083 lw ra,60(sp)
10104: 00000513 li a0,0
10108: 04010113 addi sp,sp,64
1010c: 00008067 ret
00010110 <div>:
10110: 00050793 mv a5,a0
10114: 02054063 bltz a0,10134 <div+0x24>
10118: 00000513 li a0,0
1011c: 0080006f j 10124 <div+0x14>
10120: 00070513 mv a0,a4
10124: 40b787b3 sub a5,a5,a1
10128: 00150713 addi a4,a0,1
1012c: fe07dae3 bgez a5,10120 <div+0x10>
10130: 00008067 ret
10134: fff00513 li a0,-1
10138: 00008067 ret
0001013c <mod>:
1013c: 00055663 bgez a0,10148 <mod+0xc>
10140: 0140006f j 10154 <mod+0x18>
10144: 00078513 mv a0,a5
10148: 40b507b3 sub a5,a0,a1
1014c: fe07dce3 bgez a5,10144 <mod+0x8>
10150: 00008067 ret
10154: 00000513 li a0,0
10158: 00008067 ret
0001015c <self_printf>:
1015c: fa010113 addi sp,sp,-96
10160: 04e12823 sw a4,80(sp)
10164: 02812e23 sw s0,60(sp)
10168: 02912c23 sw s1,56(sp)
1016c: 03212a23 sw s2,52(sp)
10170: 03312823 sw s3,48(sp)
10174: 04b12223 sw a1,68(sp)
10178: 04c12423 sw a2,72(sp)
1017c: 04d12623 sw a3,76(sp)
10180: 04f12a23 sw a5,84(sp)
10184: 05012c23 sw a6,88(sp)
10188: 05112e23 sw a7,92(sp)
1018c: 00054783 lbu a5,0(a0)
10190: 04410713 addi a4,sp,68
10194: 00e12623 sw a4,12(sp)
10198: 0a078863 beqz a5,10248 <self_printf+0xec>
1019c: 01010893 addi a7,sp,16
101a0: 00010f37 lui t5,0x10
101a4: 00100e93 li t4,1
101a8: 02500313 li t1,37
101ac: 00011837 lui a6,0x11
101b0: 02000f93 li t6,32
101b4: 650f0f13 addi t5,t5,1616 # 10650 <self_printf+0x4f4>
101b8: 03000393 li t2,48
101bc: 411e8eb3 sub t4,t4,a7
101c0: 02d00413 li s0,45
101c4: 00900e13 li t3,9
101c8: 01110293 addi t0,sp,17
101cc: 0200006f j 101ec <self_printf+0x90>
101d0: 6d46a683 lw a3,1748(a3)
101d4: 00058713 mv a4,a1
101d8: 00050593 mv a1,a0
101dc: 00f68023 sb a5,0(a3)
101e0: 00070513 mv a0,a4
101e4: 0015c783 lbu a5,1(a1)
101e8: 06078063 beqz a5,10248 <self_printf+0xec>
101ec: 00150593 addi a1,a0,1
101f0: 00080693 mv a3,a6
101f4: fc679ee3 bne a5,t1,101d0 <self_printf+0x74>
101f8: 00154603 lbu a2,1(a0)
101fc: 04060663 beqz a2,10248 <self_printf+0xec>
10200: 00c12483 lw s1,12(sp)
10204: 00000913 li s2,0
10208: 00048713 mv a4,s1
1020c: fa860793 addi a5,a2,-88
10210: 0ff7f793 andi a5,a5,255
10214: 00158513 addi a0,a1,1
10218: 2cffea63 bltu t6,a5,104ec <self_printf+0x390>
1021c: 00279793 slli a5,a5,0x2
10220: 01e787b3 add a5,a5,t5
10224: 0007a783 lw a5,0(a5)
10228: 00078067 jr a5
1022c: 00074603 lbu a2,0(a4)
10230: 6d482783 lw a5,1748(a6) # 116d4 <tx>
10234: 00470713 addi a4,a4,4
10238: 00080693 mv a3,a6
1023c: 00c78023 sb a2,0(a5)
10240: 0015c783 lbu a5,1(a1)
10244: 28079863 bnez a5,104d4 <self_printf+0x378>
10248: 03c12403 lw s0,60(sp)
1024c: 03812483 lw s1,56(sp)
10250: 03412903 lw s2,52(sp)
10254: 03012983 lw s3,48(sp)
10258: 00100513 li a0,1
1025c: 06010113 addi sp,sp,96
10260: 00008067 ret
10264: 00072783 lw a5,0(a4)
10268: 00080693 mv a3,a6
1026c: 00470713 addi a4,a4,4
10270: 6d482983 lw s3,1748(a6)
10274: 2a078863 beqz a5,10524 <self_printf+0x3c8>
10278: 00e12623 sw a4,12(sp)
1027c: 00000913 li s2,0
10280: 0080006f j 10288 <self_printf+0x12c>
10284: 00068913 mv s2,a3
10288: 00f7f713 andi a4,a5,15
1028c: 0ff77493 andi s1,a4,255
10290: 00190693 addi a3,s2,1
10294: 03048613 addi a2,s1,48
10298: 00ee5463 bge t3,a4,102a0 <self_printf+0x144>
1029c: 05748613 addi a2,s1,87
102a0: 00d88733 add a4,a7,a3
102a4: fec70fa3 sb a2,-1(a4)
102a8: 4047d793 srai a5,a5,0x4
102ac: fc079ce3 bnez a5,10284 <self_printf+0x128>
102b0: 03010793 addi a5,sp,48
102b4: 012787b3 add a5,a5,s2
102b8: fe07c783 lbu a5,-32(a5)
102bc: 00f98023 sb a5,0(s3)
102c0: f20902e3 beqz s2,101e4 <self_printf+0x88>
102c4: ffe74683 lbu a3,-2(a4)
102c8: 6d482783 lw a5,1748(a6)
102cc: fff70713 addi a4,a4,-1
102d0: 00d78023 sb a3,0(a5)
102d4: fee298e3 bne t0,a4,102c4 <self_printf+0x168>
102d8: f0dff06f j 101e4 <self_printf+0x88>
102dc: 00090463 beqz s2,102e4 <self_printf+0x188>
102e0: 00070493 mv s1,a4
102e4: 0004a703 lw a4,0(s1)
102e8: 00448493 addi s1,s1,4
102ec: 00912623 sw s1,12(sp)
102f0: 00074783 lbu a5,0(a4)
102f4: ee0788e3 beqz a5,101e4 <self_printf+0x88>
102f8: 6d482683 lw a3,1748(a6)
102fc: 00170713 addi a4,a4,1
10300: 00f68023 sb a5,0(a3)
10304: 00074783 lbu a5,0(a4)
10308: fe0798e3 bnez a5,102f8 <self_printf+0x19c>
1030c: ed9ff06f j 101e4 <self_printf+0x88>
10310: 00072783 lw a5,0(a4)
10314: 00080693 mv a3,a6
10318: 00470713 addi a4,a4,4
1031c: 6d482903 lw s2,1748(a6)
10320: 1e078a63 beqz a5,10514 <self_printf+0x3b8>
10324: 00e12623 sw a4,12(sp)
10328: 00000493 li s1,0
1032c: 0080006f j 10334 <self_printf+0x1d8>
10330: 00060493 mv s1,a2
10334: 0017f713 andi a4,a5,1
10338: 00148613 addi a2,s1,1
1033c: 00c886b3 add a3,a7,a2
10340: 03070713 addi a4,a4,48
10344: fee68fa3 sb a4,-1(a3)
10348: 4017d793 srai a5,a5,0x1
1034c: fe0792e3 bnez a5,10330 <self_printf+0x1d4>
10350: 03010793 addi a5,sp,48
10354: 009787b3 add a5,a5,s1
10358: fe07c783 lbu a5,-32(a5)
1035c: 00f90023 sb a5,0(s2)
10360: e80482e3 beqz s1,101e4 <self_printf+0x88>
10364: ffe6c703 lbu a4,-2(a3)
10368: 6d482783 lw a5,1748(a6)
1036c: fff68693 addi a3,a3,-1
10370: 00e78023 sb a4,0(a5)
10374: fe5698e3 bne a3,t0,10364 <self_printf+0x208>
10378: e6dff06f j 101e4 <self_printf+0x88>
1037c: 00072783 lw a5,0(a4)
10380: 00080693 mv a3,a6
10384: 00470713 addi a4,a4,4
10388: 6d482983 lw s3,1748(a6)
1038c: 18078c63 beqz a5,10524 <self_printf+0x3c8>
10390: 00e12623 sw a4,12(sp)
10394: 00000913 li s2,0
10398: 0080006f j 103a0 <self_printf+0x244>
1039c: 00068913 mv s2,a3
103a0: 00f7f713 andi a4,a5,15
103a4: 0ff77493 andi s1,a4,255
103a8: 00190693 addi a3,s2,1
103ac: 03048613 addi a2,s1,48
103b0: 00ee5463 bge t3,a4,103b8 <self_printf+0x25c>
103b4: 03748613 addi a2,s1,55
103b8: 00d88733 add a4,a7,a3
103bc: fec70fa3 sb a2,-1(a4)
103c0: 4047d793 srai a5,a5,0x4
103c4: fc079ce3 bnez a5,1039c <self_printf+0x240>
103c8: 03010793 addi a5,sp,48
103cc: 012787b3 add a5,a5,s2
103d0: fe07c783 lbu a5,-32(a5)
103d4: 00f98023 sb a5,0(s3)
103d8: e00906e3 beqz s2,101e4 <self_printf+0x88>
103dc: ffe74683 lbu a3,-2(a4)
103e0: 6d482783 lw a5,1748(a6)
103e4: fff70713 addi a4,a4,-1
103e8: 00d78023 sb a3,0(a5)
103ec: fee298e3 bne t0,a4,103dc <self_printf+0x280>
103f0: df5ff06f j 101e4 <self_printf+0x88>
103f4: 00072783 lw a5,0(a4)
103f8: 00080693 mv a3,a6
103fc: 00470713 addi a4,a4,4
10400: 6d482903 lw s2,1748(a6)
10404: 10078863 beqz a5,10514 <self_printf+0x3b8>
10408: 00e12623 sw a4,12(sp)
1040c: 00000493 li s1,0
10410: 0080006f j 10418 <self_printf+0x2bc>
10414: 00060493 mv s1,a2
10418: 0077f713 andi a4,a5,7
1041c: 00148613 addi a2,s1,1
10420: 00c886b3 add a3,a7,a2
10424: 03070713 addi a4,a4,48
10428: fee68fa3 sb a4,-1(a3)
1042c: 4037d793 srai a5,a5,0x3
10430: fe0792e3 bnez a5,10414 <self_printf+0x2b8>
10434: 03010793 addi a5,sp,48
10438: 009787b3 add a5,a5,s1
1043c: fe07c783 lbu a5,-32(a5)
10440: 00f90023 sb a5,0(s2)
10444: da0480e3 beqz s1,101e4 <self_printf+0x88>
10448: ffe6c703 lbu a4,-2(a3)
1044c: 6d482783 lw a5,1748(a6)
10450: fff68693 addi a3,a3,-1
10454: 00e78023 sb a4,0(a5)
10458: fe5698e3 bne a3,t0,10448 <self_printf+0x2ec>
1045c: d89ff06f j 101e4 <self_printf+0x88>
10460: 00072783 lw a5,0(a4)
10464: 00470713 addi a4,a4,4
10468: 0e07c463 bltz a5,10550 <self_printf+0x3f4>
1046c: 04078a63 beqz a5,104c0 <self_printf+0x364>
10470: 00e12623 sw a4,12(sp)
10474: 00088493 mv s1,a7
10478: 009e8933 add s2,t4,s1
1047c: 00078693 mv a3,a5
10480: 0080006f j 10488 <self_printf+0x32c>
10484: 00070693 mv a3,a4
10488: ff668713 addi a4,a3,-10
1048c: fe075ce3 bgez a4,10484 <self_printf+0x328>
10490: 00000713 li a4,0
10494: 0080006f j 1049c <self_printf+0x340>
10498: 00060713 mv a4,a2
1049c: ff678793 addi a5,a5,-10
104a0: 00170613 addi a2,a4,1
104a4: fe07dae3 bgez a5,10498 <self_printf+0x33c>
104a8: 03068693 addi a3,a3,48
104ac: 00d48023 sb a3,0(s1)
104b0: 08070263 beqz a4,10534 <self_printf+0x3d8>
104b4: 00148493 addi s1,s1,1
104b8: 00070793 mv a5,a4
104bc: fbdff06f j 10478 <self_printf+0x31c>
104c0: 6d482783 lw a5,1748(a6)
104c4: 00080693 mv a3,a6
104c8: 00778023 sb t2,0(a5)
104cc: 0015c783 lbu a5,1(a1)
104d0: d6078ce3 beqz a5,10248 <self_printf+0xec>
104d4: 00100913 li s2,1
104d8: 00258593 addi a1,a1,2
104dc: 02678663 beq a5,t1,10508 <self_printf+0x3ac>
104e0: ce0908e3 beqz s2,101d0 <self_printf+0x74>
104e4: 00e12623 sw a4,12(sp)
104e8: ce9ff06f j 101d0 <self_printf+0x74>
104ec: 6d482783 lw a5,1748(a6)
104f0: 00080693 mv a3,a6
104f4: 00c78023 sb a2,0(a5)
104f8: 0015c783 lbu a5,1(a1)
104fc: d40786e3 beqz a5,10248 <self_printf+0xec>
10500: 00258593 addi a1,a1,2
10504: fc679ee3 bne a5,t1,104e0 <self_printf+0x384>
10508: 0005c603 lbu a2,0(a1)
1050c: d00610e3 bnez a2,1020c <self_printf+0xb0>
10510: d39ff06f j 10248 <self_printf+0xec>
10514: 00790023 sb t2,0(s2)
10518: 0015c783 lbu a5,1(a1)
1051c: fa079ce3 bnez a5,104d4 <self_printf+0x378>
10520: d29ff06f j 10248 <self_printf+0xec>
10524: 00798023 sb t2,0(s3)
10528: 0015c783 lbu a5,1(a1)
1052c: fa0794e3 bnez a5,104d4 <self_printf+0x378>
10530: d19ff06f j 10248 <self_printf+0xec>
10534: 012887b3 add a5,a7,s2
10538: fff7c683 lbu a3,-1(a5)
1053c: 6d482703 lw a4,1748(a6)
10540: fff78793 addi a5,a5,-1
10544: 00d70023 sb a3,0(a4)
10548: fef898e3 bne a7,a5,10538 <self_printf+0x3dc>
1054c: c99ff06f j 101e4 <self_printf+0x88>
10550: 6d482683 lw a3,1748(a6)
10554: 00e12623 sw a4,12(sp)
10558: 40f007b3 neg a5,a5
1055c: 00868023 sb s0,0(a3)
10560: f15ff06f j 10474 <self_printf+0x318>
```
### $ riscv-none-embed-readelf -h test
```
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: 0x10074
Start of program headers: 52 (bytes into file)
Start of section headers: 2300 (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: 8
Section header string table index: 7
```
### $ riscv-none-embed-size test
```
text data bss dec hex filename
1632 4 0 1636 664 test
```