initial commit
This commit is contained in:
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