add hexdump
parent
3b2e88e661
commit
6b66d832cf
|
@ -3,3 +3,4 @@
|
||||||
/cat
|
/cat
|
||||||
/printstack
|
/printstack
|
||||||
/env
|
/env
|
||||||
|
/hexdump
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -5,7 +5,7 @@ LD = $(TARGET)-ld
|
||||||
.SUFFIXES:
|
.SUFFIXES:
|
||||||
|
|
||||||
.PHONY: all
|
.PHONY: all
|
||||||
all: true false cat env
|
all: true false cat env hexdump
|
||||||
#all: echo
|
#all: echo
|
||||||
|
|
||||||
%: %.o
|
%: %.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