initial commit
This commit is contained in:
9
Makefile
Normal file
9
Makefile
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
CC = riscv64-linux-gnu-gcc
|
||||||
|
GCC_ARGS = -static -g -nostdlib
|
||||||
|
SOURCES = $(wildcard src/*.s src/**/*.s)
|
||||||
|
|
||||||
|
build/main: $(SOURCES)
|
||||||
|
$(CC) $(GCC_ARGS) -o build/main $(SOURCES)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -r build/*
|
||||||
BIN
build/main
Executable file
BIN
build/main
Executable file
Binary file not shown.
BIN
build/test.txt
Normal file
BIN
build/test.txt
Normal file
Binary file not shown.
13
run
Executable file
13
run
Executable file
@@ -0,0 +1,13 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
make -s || exit
|
||||||
|
cd build
|
||||||
|
|
||||||
|
if [ "$1" = "d" ]; then
|
||||||
|
qemu-riscv64 -g 1234 main &
|
||||||
|
riscv64-linux-gnu-gdb -q \
|
||||||
|
-ex "target remote :1234" \
|
||||||
|
main
|
||||||
|
else
|
||||||
|
qemu-riscv64 main
|
||||||
|
fi
|
||||||
|
|
||||||
62
src/lib/format.s
Normal file
62
src/lib/format.s
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
.align 2
|
||||||
|
.section .text
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# args:
|
||||||
|
# a0 - number
|
||||||
|
#
|
||||||
|
# returns:
|
||||||
|
# a0,a1 - hex string
|
||||||
|
.global format_hex
|
||||||
|
format_hex:
|
||||||
|
addi sp, sp, -(3*8)
|
||||||
|
sd ra, 0(sp)
|
||||||
|
sd s0, 8(sp)
|
||||||
|
sd s1, 16(sp)
|
||||||
|
|
||||||
|
move s0, a0
|
||||||
|
jal format_hex_lower
|
||||||
|
move s1, a0
|
||||||
|
|
||||||
|
srli a0, s0, 32
|
||||||
|
jal format_hex_lower
|
||||||
|
|
||||||
|
move a1, s1
|
||||||
|
|
||||||
|
ld ra, 0(sp)
|
||||||
|
ld s0, 8(sp)
|
||||||
|
ld s1, 16(sp)
|
||||||
|
addi sp, sp, +(3*8)
|
||||||
|
ret
|
||||||
|
|
||||||
|
# args:
|
||||||
|
# a0 - number
|
||||||
|
#
|
||||||
|
# returns:
|
||||||
|
# a0 - lower hex string
|
||||||
|
.global format_hex_lower
|
||||||
|
format_hex_lower:
|
||||||
|
move t0, a0
|
||||||
|
li t1, 0xffffffff
|
||||||
|
and t0, t0, t1
|
||||||
|
li a0, 0
|
||||||
|
li t1, 8*7
|
||||||
|
li t4, 16*4
|
||||||
|
0:
|
||||||
|
bltz t1, 0f
|
||||||
|
|
||||||
|
andi t2, t0, 0xf
|
||||||
|
addi t2, t2, 0x30
|
||||||
|
li t3, 0x30+9
|
||||||
|
ble t2, t3, 1f
|
||||||
|
addi t2, t2, 0x61-0x30-10
|
||||||
|
1:
|
||||||
|
sll t2, t2, t1
|
||||||
|
addi t1, t1, -8
|
||||||
|
srli t0, t0, 4
|
||||||
|
or a0, a0, t2
|
||||||
|
j 0b
|
||||||
|
0:
|
||||||
|
ret
|
||||||
|
|
||||||
225
src/lib/heap.s
Normal file
225
src/lib/heap.s
Normal file
@@ -0,0 +1,225 @@
|
|||||||
|
# This is a heap implemented with brk.
|
||||||
|
# It's slow / unoptimized, and only for
|
||||||
|
# learning how to set up a basic heap
|
||||||
|
|
||||||
|
# mask and imask are used to floor & ceil
|
||||||
|
# to get correct bounds
|
||||||
|
.equ align_imask, 0b111
|
||||||
|
.equ align_mask, ~align_imask
|
||||||
|
|
||||||
|
.equ used_mask, 0b001
|
||||||
|
.equ size_mask, align_mask
|
||||||
|
|
||||||
|
# block node
|
||||||
|
|
||||||
|
.equ bsize, 0
|
||||||
|
.equ fb_next, 8 # free only
|
||||||
|
# free also contains its address at the end
|
||||||
|
|
||||||
|
# sizes of metadata
|
||||||
|
|
||||||
|
.equ sizeof_fb, (8*3 + align_imask) & align_mask
|
||||||
|
.equ sizeof_ub, (8*1 + align_imask) & align_mask
|
||||||
|
|
||||||
|
.equ PAGE_SIZE, 4096
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.align 2
|
||||||
|
.section .rodata
|
||||||
|
|
||||||
|
.word 0f - heap_oom
|
||||||
|
heap_oom:
|
||||||
|
.string "Heap ran out of memory!\n"
|
||||||
|
0:
|
||||||
|
|
||||||
|
.section .data
|
||||||
|
|
||||||
|
.align 4
|
||||||
|
.equ heap_start, 0
|
||||||
|
.equ heap_first_free, 8 # matches fb_next
|
||||||
|
.equ heap_end, 16
|
||||||
|
.global heap_info # for testing only
|
||||||
|
heap_info:
|
||||||
|
.dword __global_pointer$
|
||||||
|
.dword 0
|
||||||
|
.dword 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.align 2
|
||||||
|
.section .text
|
||||||
|
|
||||||
|
.global heap_init
|
||||||
|
heap_init:
|
||||||
|
addi sp, sp, -8
|
||||||
|
sd ra, 0(sp)
|
||||||
|
|
||||||
|
# get heap info (t0)
|
||||||
|
|
||||||
|
la t0, heap_info
|
||||||
|
|
||||||
|
# set heap start (t1)
|
||||||
|
|
||||||
|
ld t1, heap_start(t0)
|
||||||
|
addi t1, t1, align_imask
|
||||||
|
andi t1, t1, align_mask
|
||||||
|
sd t1, heap_start(t0)
|
||||||
|
|
||||||
|
# set heap end (a0)
|
||||||
|
# also calculate heap size (t2)
|
||||||
|
|
||||||
|
li a0, 0
|
||||||
|
jal brk
|
||||||
|
andi a0, a0, align_mask
|
||||||
|
sub t2, a0, t1 # size = end - start (t2)
|
||||||
|
li t3, sizeof_fb
|
||||||
|
bgeu t2, t3, 0f # check if enough mem to start
|
||||||
|
|
||||||
|
move a1, a0
|
||||||
|
add a0, t1, t3
|
||||||
|
jal brk_or_panic # if not, get more
|
||||||
|
sub t2, a0, t1 # recalc size (t2)
|
||||||
|
0:
|
||||||
|
sd a0, heap_end(t0)
|
||||||
|
|
||||||
|
# create initial free block
|
||||||
|
|
||||||
|
ori t2, t2, 0x1 # add prev used
|
||||||
|
sd t2, bsize(t1) # store size
|
||||||
|
sd t0, fb_next(t1) # store next
|
||||||
|
sd t1, -8(a0) # store addr at end
|
||||||
|
|
||||||
|
sd t1, heap_first_free(t0)
|
||||||
|
|
||||||
|
ld ra, 0(sp)
|
||||||
|
addi sp, sp, +8
|
||||||
|
ret
|
||||||
|
|
||||||
|
# args:
|
||||||
|
# a0 - size
|
||||||
|
#
|
||||||
|
# returns:
|
||||||
|
# a0 - address
|
||||||
|
.global heap_alloc
|
||||||
|
heap_alloc:
|
||||||
|
addi sp, sp, -8
|
||||||
|
sd ra, 0(sp)
|
||||||
|
|
||||||
|
# align size properly (t0)
|
||||||
|
|
||||||
|
move t0, a0
|
||||||
|
addi t0, t0, sizeof_ub
|
||||||
|
addi t0, t0, align_imask
|
||||||
|
andi t0, t0, align_mask
|
||||||
|
|
||||||
|
# get a free block that will fit (t1)
|
||||||
|
# and its free space
|
||||||
|
|
||||||
|
la t3, heap_info
|
||||||
|
ld t4, heap_first_free(t3)
|
||||||
|
ld a1, heap_end(t3)
|
||||||
|
|
||||||
|
move t6, t3 # prev block (t6)
|
||||||
|
|
||||||
|
bne t4, t3, 0f # if no free blocks
|
||||||
|
move t4, a1 # pretend end is start
|
||||||
|
j 3f
|
||||||
|
0:
|
||||||
|
|
||||||
|
move t1, t4 # current block (t1)
|
||||||
|
|
||||||
|
0:
|
||||||
|
ld t2, bsize(t1) # size of current block (t2)
|
||||||
|
andi t2, t2, size_mask
|
||||||
|
bgeu t2, t0, 0f # is it big enough
|
||||||
|
ld t5, fb_next(t1) # if not, get the next
|
||||||
|
beq t5, t3, 1f
|
||||||
|
move t6, t1
|
||||||
|
move t1, t5
|
||||||
|
j 0b
|
||||||
|
1: # if no blocks are big enough
|
||||||
|
add t5, t1, t2 # get end of last free block
|
||||||
|
beq t5, a1, 2f # if no free block at end of heap:
|
||||||
|
move t6, t1
|
||||||
|
3:
|
||||||
|
move t1, a1 # immitate new free block at end
|
||||||
|
2:
|
||||||
|
add a0, t1, t0 # get needed heap end (a0)
|
||||||
|
jal brk_or_panic # set heap end (a0)
|
||||||
|
sd a0, heap_end(t3) # update end in info
|
||||||
|
sub t2, a0, t1 # new free space (t2)
|
||||||
|
andi t5, t2, 1 # prev used bit
|
||||||
|
sd t5, bsize(t1) # update size
|
||||||
|
sd t3, fb_next(t1) # update next (for case 3)
|
||||||
|
|
||||||
|
0:
|
||||||
|
|
||||||
|
# deal with extra free space
|
||||||
|
|
||||||
|
sub t5, t2, t0 # unneeded free space (t5)
|
||||||
|
li t4, sizeof_fb
|
||||||
|
bltu t5, t4, 0f # check if enough for a free block
|
||||||
|
|
||||||
|
add t3, t1, t0 # if so, get addr (t3)
|
||||||
|
sd t3, fb_next(t6) # set prev block next to new
|
||||||
|
add t6, t3, t5 # store addr at end
|
||||||
|
sd t3, -8(t6)
|
||||||
|
ori t6, t5, 1 # store size with prev in use
|
||||||
|
sd t6, bsize(t3)
|
||||||
|
ld t6, fb_next(t1) # copy next
|
||||||
|
sd t6, fb_next(t3)
|
||||||
|
j 1f
|
||||||
|
0:
|
||||||
|
move t0, t2 # if no space, fill in with used
|
||||||
|
ld t4, fb_next(t1)
|
||||||
|
sd t4, fb_next(t6) # set prev next to cur next
|
||||||
|
ld t4, heap_end(t3)
|
||||||
|
add t3, t1, t0
|
||||||
|
beq t3, t4, 1f # if this is not at the end
|
||||||
|
ld t4, bsize(t3) # set next's prev used to 1
|
||||||
|
ori t4, t4, 1
|
||||||
|
sd t4, bsize(t3)
|
||||||
|
1:
|
||||||
|
|
||||||
|
# create used block
|
||||||
|
|
||||||
|
add t2, t0, t1 # end of block
|
||||||
|
ori t0, t0, 1 # prev used bit
|
||||||
|
sd t0, bsize(t1) # store size
|
||||||
|
sd zero, fb_next(t1) # remove free block stuff
|
||||||
|
sd zero, -8(t2)
|
||||||
|
|
||||||
|
move a0, t1
|
||||||
|
addi a0, a0, sizeof_ub
|
||||||
|
|
||||||
|
ld ra, 0(sp)
|
||||||
|
addi sp, sp, +8
|
||||||
|
ret
|
||||||
|
|
||||||
|
# args:
|
||||||
|
# a0 - address
|
||||||
|
.global heap_free
|
||||||
|
heap_free:
|
||||||
|
ret
|
||||||
|
|
||||||
|
# args:
|
||||||
|
# a0 - min address needed
|
||||||
|
# a1 - old address
|
||||||
|
#
|
||||||
|
# returns:
|
||||||
|
# a0 - new address, aligned
|
||||||
|
brk_or_panic:
|
||||||
|
addi sp, sp, -8
|
||||||
|
sd ra, 0(sp)
|
||||||
|
|
||||||
|
jal brk
|
||||||
|
andi a0, a0, align_mask
|
||||||
|
bgtu a0, a1, 0f # make sure brk worked
|
||||||
|
la a0, heap_oom # if not, panic
|
||||||
|
lw a1, -4(a0)
|
||||||
|
j panic
|
||||||
|
0:
|
||||||
|
ld ra, 0(sp)
|
||||||
|
addi sp, sp, +8
|
||||||
|
ret
|
||||||
95
src/lib/print.s
Normal file
95
src/lib/print.s
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
.section .rodata
|
||||||
|
|
||||||
|
newline:
|
||||||
|
.half '\n'
|
||||||
|
space:
|
||||||
|
.half ' '
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.align 2
|
||||||
|
.section .text
|
||||||
|
|
||||||
|
# only uses a regs for convenience
|
||||||
|
#
|
||||||
|
# args:
|
||||||
|
# a0 - string
|
||||||
|
# a1 - length
|
||||||
|
.global print
|
||||||
|
print:
|
||||||
|
addi sp, sp, -8
|
||||||
|
sd ra, (sp)
|
||||||
|
|
||||||
|
move a2, a1
|
||||||
|
move a1, a0
|
||||||
|
li a0, 1 # stdout
|
||||||
|
jal write
|
||||||
|
|
||||||
|
ld ra, (sp)
|
||||||
|
addi sp, sp, +8
|
||||||
|
ret
|
||||||
|
|
||||||
|
# only uses a regs for convenience
|
||||||
|
.global printnl
|
||||||
|
printnl:
|
||||||
|
addi sp, sp, -8
|
||||||
|
sd ra, (sp)
|
||||||
|
|
||||||
|
la a0, newline
|
||||||
|
li a1, 1
|
||||||
|
jal print
|
||||||
|
|
||||||
|
ld ra, (sp)
|
||||||
|
addi sp, sp, +8
|
||||||
|
ret
|
||||||
|
|
||||||
|
# only uses a regs for convenience
|
||||||
|
#
|
||||||
|
# args:
|
||||||
|
# a0 - string
|
||||||
|
# a1 - length
|
||||||
|
.global println
|
||||||
|
println:
|
||||||
|
addi sp, sp, -8
|
||||||
|
sd ra, (sp)
|
||||||
|
|
||||||
|
jal print
|
||||||
|
jal printnl
|
||||||
|
|
||||||
|
ld ra, (sp)
|
||||||
|
addi sp, sp, +8
|
||||||
|
ret
|
||||||
|
|
||||||
|
.global print_space
|
||||||
|
print_space:
|
||||||
|
addi sp, sp, -8
|
||||||
|
sd ra, (sp)
|
||||||
|
|
||||||
|
la a0, space
|
||||||
|
li a1, 1
|
||||||
|
jal print
|
||||||
|
|
||||||
|
ld ra, (sp)
|
||||||
|
addi sp, sp, +8
|
||||||
|
ret
|
||||||
|
|
||||||
|
# args:
|
||||||
|
# a0 - the hex value to print
|
||||||
|
.global print_hex
|
||||||
|
print_hex:
|
||||||
|
addi sp, sp, -(8+16)
|
||||||
|
sd ra, (sp)
|
||||||
|
|
||||||
|
jal format_hex
|
||||||
|
addi t0, sp, 8
|
||||||
|
sd a0, 0(t0)
|
||||||
|
sd a1, 8(t0)
|
||||||
|
|
||||||
|
move a0, t0
|
||||||
|
li a1, 16
|
||||||
|
jal print
|
||||||
|
|
||||||
|
ld ra, (sp)
|
||||||
|
addi sp, sp, +(8+16)
|
||||||
|
ret
|
||||||
|
|
||||||
9
src/lib/start.s
Normal file
9
src/lib/start.s
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
.align 2
|
||||||
|
.section .text
|
||||||
|
|
||||||
|
.global _start
|
||||||
|
_start:
|
||||||
|
jal heap_init
|
||||||
|
jal main
|
||||||
|
j exit
|
||||||
|
|
||||||
37
src/lib/str.s
Normal file
37
src/lib/str.s
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
.align 2
|
||||||
|
.section .text
|
||||||
|
|
||||||
|
# args:
|
||||||
|
# a0 - string
|
||||||
|
#
|
||||||
|
# returns:
|
||||||
|
# a0 - length
|
||||||
|
.global strlen
|
||||||
|
strlen:
|
||||||
|
li t0, 0
|
||||||
|
0:
|
||||||
|
beq t0, a1, 0f
|
||||||
|
lb t1, (a0)
|
||||||
|
beqz t1, 0f
|
||||||
|
addi a0, a0, 1
|
||||||
|
addi t0, t0, 1
|
||||||
|
j 0b
|
||||||
|
0:
|
||||||
|
move a0, t0
|
||||||
|
ret
|
||||||
|
|
||||||
|
# args:
|
||||||
|
# a0 - dest
|
||||||
|
# a1 - src
|
||||||
|
.global strcpy
|
||||||
|
strcpy:
|
||||||
|
0:
|
||||||
|
lb t0, (a1)
|
||||||
|
beqz t0, 0f
|
||||||
|
sb t0, (a0)
|
||||||
|
addi a0, a0, 1
|
||||||
|
addi a1, a1, 1
|
||||||
|
j 0b
|
||||||
|
0:
|
||||||
|
sb t0, (a0)
|
||||||
|
ret
|
||||||
50
src/lib/sys.s
Normal file
50
src/lib/sys.s
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
# This contains all syscalls used,
|
||||||
|
# as functions for convenience.
|
||||||
|
# These are guaranteed to not modify
|
||||||
|
# any registers other than the
|
||||||
|
# arguments needed for the syscalls
|
||||||
|
|
||||||
|
.align 2
|
||||||
|
.section .text
|
||||||
|
|
||||||
|
# args:
|
||||||
|
# a0 - code
|
||||||
|
.global exit
|
||||||
|
exit:
|
||||||
|
li a7, 93
|
||||||
|
ecall
|
||||||
|
0: j 0b # loop if failed for safety
|
||||||
|
|
||||||
|
# args:
|
||||||
|
# a0 - relative dir fd;
|
||||||
|
# 0 for none, -100 for cwd
|
||||||
|
# a1 - path / name
|
||||||
|
# a2 - flags
|
||||||
|
# a3 - mode
|
||||||
|
#
|
||||||
|
# returns:
|
||||||
|
# a0 - fd
|
||||||
|
.global openat
|
||||||
|
openat:
|
||||||
|
li a7, 56
|
||||||
|
ecall
|
||||||
|
ret
|
||||||
|
|
||||||
|
# args:
|
||||||
|
# a0 - fd
|
||||||
|
# a1 - content buf
|
||||||
|
# a2 - size
|
||||||
|
.global write
|
||||||
|
write:
|
||||||
|
li a7, 64
|
||||||
|
ecall
|
||||||
|
ret
|
||||||
|
|
||||||
|
# args:
|
||||||
|
# a0 - address to end at
|
||||||
|
# returns current addr if 0
|
||||||
|
.global brk
|
||||||
|
brk:
|
||||||
|
li a7, 214
|
||||||
|
ecall
|
||||||
|
ret
|
||||||
11
src/lib/util.s
Normal file
11
src/lib/util.s
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
.align 2
|
||||||
|
.section .text
|
||||||
|
|
||||||
|
# args:
|
||||||
|
# a0 - message
|
||||||
|
# a1 - length
|
||||||
|
.global panic
|
||||||
|
panic:
|
||||||
|
jal print
|
||||||
|
li a0, 1
|
||||||
|
j exit
|
||||||
20
src/main.s
Normal file
20
src/main.s
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
.align 2
|
||||||
|
.section .text
|
||||||
|
|
||||||
|
.global main
|
||||||
|
main:
|
||||||
|
addi sp, sp, -8
|
||||||
|
sd ra, 0(sp)
|
||||||
|
|
||||||
|
# do stuff
|
||||||
|
|
||||||
|
#jal write_test
|
||||||
|
jal heap_test
|
||||||
|
|
||||||
|
# exit with code 0
|
||||||
|
|
||||||
|
ld ra, 0(sp)
|
||||||
|
addi sp, sp, +8
|
||||||
|
|
||||||
|
li a0, 0
|
||||||
|
ret
|
||||||
125
src/test/heap.s
Normal file
125
src/test/heap.s
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
.section .rodata
|
||||||
|
|
||||||
|
.word 0f - print_msg
|
||||||
|
print_msg:
|
||||||
|
.string "Current heap:"
|
||||||
|
0:
|
||||||
|
|
||||||
|
.word 0f - dots
|
||||||
|
dots:
|
||||||
|
.string "................"
|
||||||
|
0:
|
||||||
|
|
||||||
|
.word 0f - hexstr
|
||||||
|
hexstr:
|
||||||
|
.string "0x"
|
||||||
|
0:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.align 2
|
||||||
|
.section .text
|
||||||
|
|
||||||
|
.global heap_test
|
||||||
|
heap_test:
|
||||||
|
addi sp, sp, -(3*8)
|
||||||
|
sd ra, 0(sp)
|
||||||
|
sd s0, 8(sp)
|
||||||
|
sd s1, 16(sp)
|
||||||
|
|
||||||
|
# empty heap
|
||||||
|
|
||||||
|
jal print_heap
|
||||||
|
jal printnl
|
||||||
|
|
||||||
|
# put stuff on heap
|
||||||
|
|
||||||
|
li a0, 8*4
|
||||||
|
jal heap_alloc
|
||||||
|
li t0, 0x1111111111111111
|
||||||
|
sd t0, (a0)
|
||||||
|
sd t0, 8(a0)
|
||||||
|
sd t0, 24(a0)
|
||||||
|
|
||||||
|
li s0, 0x0f
|
||||||
|
0:
|
||||||
|
bltz s0, 0f
|
||||||
|
|
||||||
|
li a0, 8*3
|
||||||
|
jal heap_alloc
|
||||||
|
sd s0, (a0)
|
||||||
|
li t0, 0xf000000000000000
|
||||||
|
add t0, s0, t0
|
||||||
|
sd t0, 16(a0)
|
||||||
|
|
||||||
|
addi s0, s0, -1
|
||||||
|
j 0b
|
||||||
|
0:
|
||||||
|
|
||||||
|
li a0, 8*7
|
||||||
|
jal heap_alloc
|
||||||
|
li t0, 0xffff
|
||||||
|
sd t0, 6*8(a0)
|
||||||
|
|
||||||
|
li a0, 8*3
|
||||||
|
jal heap_alloc
|
||||||
|
|
||||||
|
jal print_heap
|
||||||
|
|
||||||
|
ld ra, 0(sp)
|
||||||
|
ld s0, 8(sp)
|
||||||
|
ld s1, 16(sp)
|
||||||
|
addi sp, sp, +(3*8)
|
||||||
|
ret
|
||||||
|
|
||||||
|
print_heap:
|
||||||
|
addi sp, sp, -(3*8)
|
||||||
|
sd ra, 0(sp)
|
||||||
|
sd s0, 8(sp)
|
||||||
|
sd s1, 16(sp)
|
||||||
|
|
||||||
|
la a0, print_msg
|
||||||
|
lw a1, -4(a0)
|
||||||
|
jal println
|
||||||
|
|
||||||
|
la t0, heap_info
|
||||||
|
ld s0, 0(t0)
|
||||||
|
ld s1, 16(t0)
|
||||||
|
0:
|
||||||
|
la a0, hexstr
|
||||||
|
lw a1, -4(a0)
|
||||||
|
jal print
|
||||||
|
move a0, s0
|
||||||
|
jal print_hex
|
||||||
|
jal print_space
|
||||||
|
|
||||||
|
ld a0, 0(s0)
|
||||||
|
jal print_hex
|
||||||
|
jal print_space
|
||||||
|
|
||||||
|
ld a0, 8(s0)
|
||||||
|
jal print_hex
|
||||||
|
jal print_space
|
||||||
|
|
||||||
|
la a0, dots
|
||||||
|
lw a1, -4(a0)
|
||||||
|
jal print
|
||||||
|
jal print_space
|
||||||
|
|
||||||
|
ld t0, 0(s0)
|
||||||
|
andi t0, t0, ~0b11
|
||||||
|
add t0, s0, t0
|
||||||
|
ld a0, -8(t0)
|
||||||
|
move s0, t0
|
||||||
|
jal print_hex
|
||||||
|
jal printnl
|
||||||
|
|
||||||
|
beq s0, s1, 0f
|
||||||
|
j 0b
|
||||||
|
0:
|
||||||
|
|
||||||
|
ld ra, 0(sp)
|
||||||
|
ld s0, 8(sp)
|
||||||
|
ld s1, 16(sp)
|
||||||
|
addi sp, sp, +(3*8)
|
||||||
|
ret
|
||||||
55
src/test/write.s
Normal file
55
src/test/write.s
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
.equ PATH_MAX, 255
|
||||||
|
|
||||||
|
.section .rodata
|
||||||
|
|
||||||
|
.word 0f - start_msg
|
||||||
|
start_msg:
|
||||||
|
.string "Writing file..."
|
||||||
|
0:
|
||||||
|
|
||||||
|
.word 0f - file_name
|
||||||
|
file_name:
|
||||||
|
.string "test.txt"
|
||||||
|
0:
|
||||||
|
|
||||||
|
.word 0f - content
|
||||||
|
content:
|
||||||
|
.string "Hello world!\n"
|
||||||
|
0:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.align 2
|
||||||
|
.section .text
|
||||||
|
|
||||||
|
.global write_test
|
||||||
|
write_test:
|
||||||
|
addi sp, sp, -8-PATH_MAX
|
||||||
|
sd ra, 0(sp)
|
||||||
|
|
||||||
|
# print msg
|
||||||
|
|
||||||
|
la a0, start_msg
|
||||||
|
lw a1, -4(a0)
|
||||||
|
jal println
|
||||||
|
|
||||||
|
# open file
|
||||||
|
|
||||||
|
li a0, -100
|
||||||
|
la a1, file_name
|
||||||
|
li a2, 01102 # TRUNC | CREAT | RDWR
|
||||||
|
li a3, 0b110100100 # -rw-r--r--
|
||||||
|
jal openat
|
||||||
|
|
||||||
|
# write to file
|
||||||
|
|
||||||
|
la a1, content
|
||||||
|
lw a2, -4(a1)
|
||||||
|
jal write
|
||||||
|
|
||||||
|
# return
|
||||||
|
|
||||||
|
ld ra, 0(sp)
|
||||||
|
addi sp, sp, +8+PATH_MAX
|
||||||
|
|
||||||
|
ret
|
||||||
Reference in New Issue
Block a user