Add linker script to make bss work
This commit is contained in:
parent
ba9abb1cc0
commit
4c4d7bdbf7
4 changed files with 136 additions and 3 deletions
6
Makefile
6
Makefile
|
@ -1,13 +1,13 @@
|
||||||
AS=riscv64-unknown-elf-as
|
AS=riscv64-unknown-elf-as
|
||||||
LD=riscv64-unknown-elf-ld
|
LD=riscv64-unknown-elf-ld
|
||||||
|
|
||||||
all: main.x
|
all: calc.elf
|
||||||
|
|
||||||
hello.elf: hello.o
|
hello.elf: hello.o
|
||||||
$(LD) -m elf32lriscv $^ -o $@
|
$(LD) -m elf32lriscv $^ -o $@
|
||||||
|
|
||||||
main.x: main.o exit.o
|
calc.elf: calc.o
|
||||||
$(LD) -m elf32lriscv $^ -o main.x
|
$(LD) -m elf32lriscv -T link.ld $^ -o $@
|
||||||
|
|
||||||
%.o : %.s
|
%.o : %.s
|
||||||
$(AS) -mabi=ilp32e -march=rv32ec $< -o $@
|
$(AS) -mabi=ilp32e -march=rv32ec $< -o $@
|
||||||
|
|
|
@ -11,6 +11,14 @@ Notes
|
||||||
|
|
||||||
riscv64-unknown-elf-objdump -D main.o
|
riscv64-unknown-elf-objdump -D main.o
|
||||||
|
|
||||||
|
### List Symbols
|
||||||
|
|
||||||
|
riscv64-unknown-elf-nm calc.o
|
||||||
|
|
||||||
|
### List segment info
|
||||||
|
|
||||||
|
readelf -l calc.elf
|
||||||
|
|
||||||
Resources
|
Resources
|
||||||
---------
|
---------
|
||||||
|
|
||||||
|
|
110
calc.s
Normal file
110
calc.s
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
# RISC-V assembly program implementing a calculator.
|
||||||
|
|
||||||
|
.org 0
|
||||||
|
# Provide program starting address to linker
|
||||||
|
.global _start
|
||||||
|
|
||||||
|
/* newlib system calls */
|
||||||
|
.set SYSEXIT, 93
|
||||||
|
.set SYSWRITE, 64
|
||||||
|
|
||||||
|
.section .rodata
|
||||||
|
str: .ascii "Hello World!\n"
|
||||||
|
.set str_size, .-str
|
||||||
|
str2: .ascii "regdump\n"
|
||||||
|
.set str2_size, .-str2
|
||||||
|
|
||||||
|
|
||||||
|
.section .bss
|
||||||
|
buf: .skip 20 # room for 20 byte string
|
||||||
|
# x10: ABCDEFG\n is 23 chars
|
||||||
|
|
||||||
|
.section .data
|
||||||
|
buflen: .byte 0 # length of buf string
|
||||||
|
|
||||||
|
|
||||||
|
.text
|
||||||
|
_start:
|
||||||
|
li t1, 0
|
||||||
|
li t2, 5
|
||||||
|
|
||||||
|
# dummy test for jal instruction
|
||||||
|
.L1:
|
||||||
|
jal x0, .L2
|
||||||
|
.L2:
|
||||||
|
nop
|
||||||
|
|
||||||
|
loop:
|
||||||
|
beq t1, t2, end
|
||||||
|
|
||||||
|
li t0, SYSWRITE # "write" syscall
|
||||||
|
li a0, 1 # 1 = standard output (stdout)
|
||||||
|
la a1, str # load address of hello string
|
||||||
|
li a2, str_size # length of hello string
|
||||||
|
ecall # invoke syscall to print the string
|
||||||
|
addi t1, t1, 1
|
||||||
|
j loop
|
||||||
|
|
||||||
|
end:
|
||||||
|
# do some adding
|
||||||
|
li a0, 0x80000000 # 0.5
|
||||||
|
li a1, 1 # 1
|
||||||
|
li a2, 0x80000000 # 0.5
|
||||||
|
li a3, 1 # 1
|
||||||
|
jal add64
|
||||||
|
#add t1, a0, 0 # copy a0 to t0 as end with overwrite it
|
||||||
|
jal regdump
|
||||||
|
|
||||||
|
li t0, SYSEXIT # "exit" syscall
|
||||||
|
add a0, x0, 0 # Use 0 return code
|
||||||
|
ecall # invoke syscall to terminate the program
|
||||||
|
|
||||||
|
# 64-bit integer addition
|
||||||
|
# arguments:
|
||||||
|
# a0: x lower 32 bits
|
||||||
|
# a1: x upper 32 bits
|
||||||
|
# a2: y lower 32 bits
|
||||||
|
# a3: y upper 32 bits
|
||||||
|
# return:
|
||||||
|
# a0: x+y lower 32 bits
|
||||||
|
# a1: x+y upper 32 bits
|
||||||
|
#
|
||||||
|
add64:
|
||||||
|
add a0, a0, a2 # add lower 32 bits
|
||||||
|
add t0, a1, a3 # add upper 32 bits
|
||||||
|
sltu t1, a0, a2 # if lower 32-bit sum < a2 then set t1=1 (carry bit)
|
||||||
|
add a1, t0, t1 # upper 32 bits of answer (upper sum + carry bit)
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
# Print values of all registers (in hex)
|
||||||
|
# write syscall uses t0, a0, a1, a2
|
||||||
|
regdump:
|
||||||
|
addi sp, sp, -16 # allocate stack space
|
||||||
|
sw a0, 12(sp) # save contents of a0
|
||||||
|
sw a1, 8(sp) # save contents of a0
|
||||||
|
sw a2, 4(sp) # save contents of a0
|
||||||
|
sw t0, 0(sp) # save contents of a0
|
||||||
|
|
||||||
|
li t0, SYSWRITE # "write" syscall
|
||||||
|
li a0, 1 # 1 = standard output (stdout)
|
||||||
|
la a1, str2 # load address of hello string
|
||||||
|
li a2, str2_size # length of other string
|
||||||
|
ecall # invoke syscall to print the string
|
||||||
|
|
||||||
|
# as a test load something into buf and print it
|
||||||
|
la a1, buf # load address of buf into a1
|
||||||
|
li a0, 'h
|
||||||
|
sb a0, 0(a1)
|
||||||
|
li a0, '\n
|
||||||
|
sb a0, 1(a1)
|
||||||
|
li a2, 2 # length of buf
|
||||||
|
|
||||||
|
li t0, SYSWRITE # "write" syscall
|
||||||
|
li a0, 1 # 1 = standard output (stdout)
|
||||||
|
# li a2, buflen # length of hello string
|
||||||
|
ecall # invoke syscall to print the string
|
||||||
|
|
||||||
|
addi sp, sp, 16 # deallocate stack space
|
||||||
|
ret
|
||||||
|
|
15
link.ld
Normal file
15
link.ld
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
OUTPUT_ARCH( "riscv" )
|
||||||
|
|
||||||
|
ENTRY(_start)
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
. = 0x0;
|
||||||
|
.text : { *(.text) }
|
||||||
|
/* Address warning: calc.elf has a LOAD segment with RWX permissions
|
||||||
|
* https://www.redhat.com/en/blog/linkers-warnings-about-executable-stacks-and-segments
|
||||||
|
*/
|
||||||
|
. = ALIGN (CONSTANT (COMMONPAGESIZE));
|
||||||
|
.data : { *(.data) }
|
||||||
|
.bss : { *(.bss) }
|
||||||
|
}
|
Loading…
Reference in a new issue