add hexdump
parent
3b2e88e661
commit
6b66d832cf
|
@ -3,3 +3,4 @@
|
|||
/cat
|
||||
/printstack
|
||||
/env
|
||||
/hexdump
|
||||
|
|
2
Makefile
2
Makefile
|
@ -5,7 +5,7 @@ LD = $(TARGET)-ld
|
|||
.SUFFIXES:
|
||||
|
||||
.PHONY: all
|
||||
all: true false cat env
|
||||
all: true false cat env hexdump
|
||||
#all: echo
|
||||
|
||||
%: %.o
|
||||
|
|
|
@ -0,0 +1,175 @@
|
|||
.globl _start
|
||||
.option rvc # enable compressed instructions
|
||||
|
||||
.data
|
||||
writebuf: .ascii "00000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................\n"
|
||||
.equ hexstart, 10
|
||||
.equ hexend, hexstart+3*16
|
||||
.equ charstart, hexend+3
|
||||
.equ linelen, (. - writebuf)
|
||||
.equ readlen, 16
|
||||
readbuf: .zero readlen
|
||||
|
||||
.text
|
||||
_start:
|
||||
# set up the gp register so that relaxed loads work
|
||||
.option push
|
||||
.option norelax
|
||||
la gp, __global_pointer$
|
||||
.option pop
|
||||
|
||||
# fd in s6
|
||||
# data offset in s7
|
||||
li s6, 0
|
||||
li s7, 0 #0xabad1dea
|
||||
|
||||
|
||||
loop:
|
||||
li a7, 63 # sys_read
|
||||
mv a0, s6 # fd
|
||||
la a1, readbuf # pointer to buffer
|
||||
li a2, readlen # size of buffer
|
||||
ecall
|
||||
#li a0, 0
|
||||
|
||||
# return in a0
|
||||
# negative => error code
|
||||
# positive => number of byte read
|
||||
# zero => end of input
|
||||
bltz a0, error
|
||||
beqz a0, done
|
||||
|
||||
li t5, 10
|
||||
|
||||
la s0, writebuf
|
||||
|
||||
.macro hexnibble src, shift, dest
|
||||
slli t1, \src, (64-\shift-4) # put high nibble of s7 in t1
|
||||
srli t1, t1, 64-4
|
||||
addi t2, t1, 0x30 # convert to decimal digit
|
||||
bgt t5, t1, 0f # if digit >= 10, use switch to alpha
|
||||
addi t2, t1, 0x61-10
|
||||
0:
|
||||
# copy digit to writebuf
|
||||
sb t2, \dest
|
||||
.endm
|
||||
|
||||
.macro hexbyte src, shift, dest
|
||||
hexnibble \src, (\shift+4), \dest
|
||||
hexnibble \src, \shift, 1+\dest
|
||||
.endm
|
||||
|
||||
hexbyte s7, 24, 0(s0)
|
||||
hexbyte s7, 16, 2(s0)
|
||||
hexbyte s7, 8, 4(s0)
|
||||
hexbyte s7, 0, 6(s0)
|
||||
|
||||
la s1, readbuf
|
||||
|
||||
# it's perfectly fine to process more
|
||||
# bytes than we read here, since the buffer
|
||||
# sizes are both fixed
|
||||
.macro inpbyte srcindex, dstindex
|
||||
lbu t0, \srcindex(s1)
|
||||
hexbyte t0, 0, \dstindex(s0)
|
||||
.endm
|
||||
|
||||
# TODO: load 8 bytes at a time
|
||||
# (need a way to check endianness)
|
||||
inpbyte 0, 10
|
||||
inpbyte 1, 13
|
||||
inpbyte 2, 16
|
||||
inpbyte 3, 19
|
||||
inpbyte 4, 22
|
||||
inpbyte 5, 25
|
||||
inpbyte 6, 28
|
||||
inpbyte 7, 31
|
||||
|
||||
inpbyte 8, 35
|
||||
inpbyte 9, 38
|
||||
inpbyte 10, 41
|
||||
inpbyte 11, 44
|
||||
inpbyte 12, 47
|
||||
inpbyte 13, 50
|
||||
inpbyte 14, 53
|
||||
inpbyte 15, 56
|
||||
|
||||
|
||||
li t0, 0
|
||||
li t4, 0x7e-0x20
|
||||
# the ascii printable range is 0x20-0x7e
|
||||
#
|
||||
# 0123456789ABCDEF
|
||||
# 20 !"#$%&'()*+,-./
|
||||
# 30 0123456789:;<=>?
|
||||
# 40 @ABCDEFGHIJKLMNO
|
||||
# 50 PQRSTUVWXYZ[\]^_
|
||||
# 60 `abcdefghijklmno
|
||||
# 70 pqrstuvwxyz{|}~
|
||||
printable_loop:
|
||||
add t1, s1, t0
|
||||
lbu t2, 0(t1)
|
||||
addi t3, t2, -0x20
|
||||
bleu t3, t4, 0f
|
||||
li t2, 0x2e # '.'
|
||||
0:
|
||||
add t1, s0, t0
|
||||
sb t2, 61(t1)
|
||||
addi t0, t0, 1
|
||||
blt t0, a0, printable_loop
|
||||
|
||||
li t0, readlen
|
||||
blt a0, t0, fixup
|
||||
|
||||
mv s0, a0 # save length read
|
||||
add s7, s7, s0 # file offset += s0
|
||||
|
||||
li a7, 64 # sys_write
|
||||
li a0, 1 # fd = stdout
|
||||
la a1, writebuf # pointer to string
|
||||
li a2, linelen # size of data
|
||||
ecall
|
||||
|
||||
bltz a0, error
|
||||
j loop
|
||||
|
||||
fixup:
|
||||
# we read <16 bytes, so we need to
|
||||
# 1) replace the hex bytes >a0 with spaces
|
||||
# 2) adjust the line length
|
||||
# 3) print it
|
||||
|
||||
add t0, a0, a0 # t0 = len*3
|
||||
add t0, t0, a0
|
||||
addi t0, t0, hexstart
|
||||
add t0, s0, t0
|
||||
addi t1, s0, hexend
|
||||
li t2, 0x20
|
||||
1:
|
||||
sb t2, 0(t0)
|
||||
addi t0, t0, 1
|
||||
blt t0, t1, 1b
|
||||
|
||||
addi t0, a0, charstart
|
||||
add t1, t0, s0
|
||||
li t2, 0xa # \n
|
||||
sb t2, 0(t1)
|
||||
li a7, 64 # sys_write
|
||||
li a0, 1 # fd = stdout
|
||||
la a1, writebuf # pointer to string
|
||||
addi a2, t0, 1 # size of data
|
||||
ecall
|
||||
bltz a0, error
|
||||
j done
|
||||
|
||||
error:
|
||||
li a7, 93 # exit
|
||||
li a0, 1
|
||||
ecall
|
||||
|
||||
done:
|
||||
li a7, 93 # exit
|
||||
li a0, 0
|
||||
ecall
|
||||
|
||||
|
Loading…
Reference in New Issue