Compare commits

..

9 commits

Author SHA1 Message Date
Imbus
7c0e113593 Semi-working output, still no exall 2024-04-05 18:27:41 +02:00
Imbus
6e1839892a More resources in readme 2024-04-05 18:27:18 +02:00
Imbus
8024135f25 Fixing linker entry point 2024-04-05 18:27:06 +02:00
Imbus
1712787e01 Fix linker script 2024-04-05 17:10:35 +02:00
Imbus
279fc9b754 Readme with useful resources 2024-04-05 17:05:34 +02:00
Imbus
868c032cbc Deleted dead code 2024-04-05 17:04:38 +02:00
Imbus
a63046569d Basic linker script 2024-04-05 17:04:19 +02:00
Imbus
0e259f27bd Trying to make stdout work 2024-04-05 17:02:26 +02:00
Imbus
e681b848d5 Makefile tuning 2024-04-05 17:02:16 +02:00
6 changed files with 130 additions and 31 deletions

12
README.md Normal file
View file

@ -0,0 +1,12 @@
# Risc-V Assembly Language Programming
## Resources
- [RISC-V Guru](https://risc-v.guru/) and [direct link to the instruction set](https://risc-v.guru/instructions/)
- [RISC-V Greehsheet](https://raw.githubusercontent.com/rswinkle/riscv_book/master/references/riscv_greensheet.pdf) and its [large version](https://raw.githubusercontent.com/rswinkle/riscv_book/master/references/riscv_greensheet_large.pdf)
- [RISC-V ISA Manual](https://riscv.org/wp-content/uploads/2017/05/riscv-spec-v2.2.pdf)
- [RISC-V Specifications](https://riscv.org/technical/specifications/)
### Misc
- [RISC-V Assembly Language Programming](https://github.com/rswinkle/riscv_book/)

19
end.s Normal file
View file

@ -0,0 +1,19 @@
# Just print the word 'exit' to the address 0x10000000
.globl end
end:
addi a0, x0, 0x65 # 'e'
li a1, 0x10000000
sb a0, (a1)
addi a0, x0, 0x78 # 'x'
sb a0, (a1)
addi a0, x0, 0x69 # 'i'
sb a0, (a1)
addi a0, x0, 0x74 # 't'
sb a0, (a1)
addi a0, x0, 0x0A
sb a0, (a1) # '\n'
ret

16
hello.s
View file

@ -1,16 +0,0 @@
.section .text
.globl _hello
_hello:
# Write the string "Hello, World!\n" to stdout
la a0, msg # Load the address of the string into a0
li a7, 4 # syscall number for write
li a1, 13 # Length of the string
li a2, 1 # File descriptor: stdout
ecall # Make the system call to write
ret # Return from the function
.section .data
msg:
.ascii "Hello, World!\n"

17
link.ld Normal file
View file

@ -0,0 +1,17 @@
MEMORY {
SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 1024
DRAM (rwx) : ORIGIN = 0x80000000, LENGTH = 1024
}
SECTIONS {
.text : {
main.o(.text.*)
*(.text)
} > DRAM
.data : {
*(.data)
} > DRAM AT > SRAM
.bss : {
*(.bss)
} > DRAM
}

77
main.s
View file

@ -1,12 +1,69 @@
.section .text
.globl _start
# Define variables
.data
.align 4
num1: .word 5 # First number
num2: .word 7 # Second number
result: .word 0 # Variable to store the result
msg: .ascii "Hello, World!\n"
array: .space 100 # 100 bytes of space
_start:
# Call the hello function
lui a0, %hi(_hello) # Load upper immediate of _hello address
addi a0, a0, %lo(_hello) # Add lower immediate of _hello address
jalr ra, a0, 0 # Jump and link to _hello, ra is return address
# Main program entry point
.globl start
.text
start:
call test_routine
call hello_manual
# call hello # This doesn't work
call end
ebreak
# Exit the program
li a7, 10 # syscall number for exit
ecall # Make the system call to exit
# Arbitrary test routine
test_routine:
la a0, num1 # Load the address of num1 into register a6
li a1, 10 # Load the value 10 into register a5
xori a2, a1, 0x1 # Calculate the value of a2
sw a1, 0(a0) # Store the value in memory
ret
# Prints "hello" manually
hello_manual:
addi a0, x0, 0x68
li a1, 0x10000000
sb a0, (a1) # 'h'
addi a0, x0, 0x65
sb a0, (a1) # 'e'
addi a0, x0, 0x6C
sb a0, (a1) # 'l'
addi a0, x0, 0x6C
sb a0, (a1) # 'l'
addi a0, x0, 0x6F
sb a0, (a1) # 'o'
addi a0, x0, 0x0A
sb a0, (a1) # '\n'
ret
# Is supposed to print "Hello, World!\n" to stdout via ecall, but doesn't work
hello:
# Write the string "Hello, World!\n" to stdout
la a0, msg # Load the address of the string into a0
li a7, 4 # syscall number for write
li a1, 13 # Length of the string
li a2, 1 # File descriptor: stdout
ecall # Make the system call to write
ret # Return from the function
# Another routine, presumably written for the rars emulator?
hello2:
li a0, 0x1
la a1, msg
li a2, 13
li a7, 64
ecall
# To avoid the program from exiting
loop: j loop

View file

@ -10,8 +10,10 @@ SIZE = ${CROSS}-size
TARGET = bin.elf
# QEMU command and flags
QEMU = qemu-riscv64-static
QEMU_FLAGS =
# QEMU = qemu-riscv64-static
QEMU = qemu-system-riscv64
QEMU_FLAGS += --machine virt# # Use the virt machine
QEMU_FLAGS += --nographic# # No graphical output
# Flags for compiler and assembler
CFLAGS += -static# # Use static linking
@ -23,6 +25,13 @@ CFLAGS += -march=rv64i # Use RV64I ISA, i.e., integer only
CFLAGS += -mabi=lp64 # Use LP64 ABI, i.e., 64-bit longs and pointers, 32-bit ints
CFLAGS += -Os# # Optimize for size
LDFLAGS += -T link.ld # Use the linker script
LDFLAGS += --no-dynamic-linker
LDFLAGS += -m elf64lriscv
LDFLAGS += -static
LDFLAGS += -nostdlib
LDFLAGS += -s
# Use GC=0 to disable garbage collection
ifneq ($(GC), 0)
CFLAGS += -ffreestanding
@ -43,7 +52,7 @@ OBJS := $(AS_SRCS:.s=.o)
# Default target
all: $(OBJS)
@$(CC) $(CFLAGS) -o $(TARGET) $(OBJS)
@$(LD) $(LDFLAGS) -o $(TARGET) $(OBJS)
@echo "LD $(OBJS)"
# Compile assembly sources
@ -53,7 +62,8 @@ all: $(OBJS)
# Run the binary in QEMU
run: all
$(QEMU) $(QEMU_FLAGS) ./$(TARGET)
@echo "To exit: Ctrl+A, X"
@$(QEMU) $(QEMU_FLAGS) -bios $(TARGET)
# View the text section of the binary
inspect: all