Add linker script to make bss work

This commit is contained in:
Wesley Moore 2025-02-09 15:09:53 +10:00
parent ba9abb1cc0
commit 4c4d7bdbf7
No known key found for this signature in database
4 changed files with 136 additions and 3 deletions

View file

@ -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 $@

View file

@ -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
View 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
View 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) }
}