I want to use risc-v toolchain to compile a simple c code to test my processor. And I refer to PicoRV32's firmware file for my own test.lds
:
SECTIONS {
.memory : {
. = 0x000000;
*(.init);
*(.text);
*(*);
. = ALIGN(4);
end = .;
}
}
and then test.S
.section .init
.global main
lui sp, %hi(16*1024)
addi sp, sp, %lo(16*1024)
jal ra, main
ebreak
and this is my test c prog test.c
void main()
{
volatile int x = 1;
volatile int y;
volatile int z = 1;
volatile int a = 1;
volatile int b = 1;
volatile int c = 1;
volatile int d = 1;
volatile int e = 1;
volatile int f = 1;
asm volatile(
"addi a1, zero, 250;"
"addi a2, zero, 6 ;"
"sw a1, 0(sp);"
"lw a3, 0(sp);"
"mul a4, a2, a3;"
"add a5, a3, a2;"
"ebreak ;");
}
finally the parameter I use in my compile process:
riscv32-unknown-elf-gcc -mno-relax -march=rv32im -Os -ffreestanding -nostdlib \
-o test.elf test.S test.c -static \
-Wl,-T,test.lds,-Map,test.map,--strip-debug -lgcc
riscv32-unknown-elf-objcopy -j .text -O binary test.elf test.bin
riscv32-unknown-elf-objdump -d -M no-aliases test.elf > result.txt
then the result.txt
is:
test.elf: file format elf32-littleriscv
Disassembly of section .memory:
00000000 <main-0x30>:
0: 00004137 lui sp,0x4
4: 00010113 addi sp,sp,0 # 4000 <end+0x3f50>
8: 028000ef jal ra,30 <main>
c: 00100073 ebreak
10: 1e41 c.addi t3,-16
12: 0000 c.unimp
14: 7200 c.flw fs0,32(a2)
16: 7369 c.lui t1,0xffffa
18: 01007663 bgeu zero,a6,24 <main-0xc>
1c: 0014 .2byte 0x14
1e: 0000 c.unimp
20: 7205 c.lui tp,0xfffe1
22: 3376 c.fldsp ft6,376(sp)
24: 6932 c.flwsp fs2,12(sp)
26: 7032 c.flwsp ft0,44(sp)
28: 5f30 c.lw a2,120(a4)
2a: 326d c.jal fffff9d4 <end+0xfffff924>
2c: 3070 c.fld fa2,224(s0)
...
00000030 <main>:
30: fe010113 addi sp,sp,-32
34: 00100793 addi a5,zero,1
38: 00f12023 sw a5,0(sp)
3c: 00f12223 sw a5,4(sp)
40: 00f12423 sw a5,8(sp)
44: 00f12623 sw a5,12(sp)
48: 00f12823 sw a5,16(sp)
4c: 00f12a23 sw a5,20(sp)
50: 00f12c23 sw a5,24(sp)
54: 00f12e23 sw a5,28(sp)
58: 0fa00593 addi a1,zero,250
5c: 00600613 addi a2,zero,6
60: 00b12023 sw a1,0(sp)
64: 00012683 lw a3,0(sp)
68: 02d60733 mul a4,a2,a3
6c: 00c687b3 add a5,a3,a2
70: 00100073 ebreak
74: 02010113 addi sp,sp,32
78: 00008067 jalr zero,0(ra)
7c: 3a434347 fmsub.d ft6,ft6,ft4,ft7,rmm
80: 2820 c.fld fs0,80(s0)
82: 31202967 .4byte 0x31202967
86: 2e32 c.fldsp ft8,264(sp)
88: 2e32 c.fldsp ft8,264(sp)
8a: 0030 c.addi4spn a2,sp,8
8c: 2041 c.jal 10c <end+0x5c>
8e: 0000 c.unimp
90: 7200 c.flw fs0,32(a2)
92: 7369 c.lui t1,0xffffa
94: 01007663 bgeu zero,a6,a0 <main+0x70>
98: 0016 c.slli zero,0x5
9a: 0000 c.unimp
9c: 1004 c.addi4spn s1,sp,32
9e: 7205 c.lui tp,0xfffe1
a0: 3376 c.fldsp ft6,376(sp)
a2: 6932 c.flwsp fs2,12(sp)
a4: 7032 c.flwsp ft0,44(sp)
a6: 5f30 c.lw a2,120(a4)
a8: 326d c.jal fffffa52 <end+0xfffff9a2>
aa: 3070 c.fld fa2,224(s0)
ac: 0000 c.unimp
...
Note that I've named the -march=rv32im
, but I still compile out some compressed instructions. I found these compressed instructions are useless in the final output test.elf
which the prog will never jump onto those instruction, and if I delete the segment *(*)
in lds file they are all disappear, left only my own program. But I can't figure out why these segments in lds file *(*)
will make some irrelevant instructions? I found *(.comment)
will make .4byte
or .2byte
words, and *(.riscv.attributes)
will make the rest of the compressed instruction which is only for gcc ( llvm will display <unknown>
To summerize upon questions:
- Is it necessary to use
.lds
file just to test the functionality of a processor? - Why some lds segments will cause those strange and seems useless instructions?
- Is it for OS runtime or something?