180 lines
3.1 KiB
ArmAsm
180 lines
3.1 KiB
ArmAsm
.globl _start
|
|
.option rvc # enable compressed instructions
|
|
.option norelax
|
|
|
|
.data
|
|
sigaction_ignore:
|
|
.dword 1 # sa_handler = SIG_IGN
|
|
.dword 0 # sa_flags
|
|
.dword 0 # sa_mask
|
|
|
|
.bss
|
|
.equ bufsize, 4<<10
|
|
buf: .zero bufsize
|
|
|
|
.bss
|
|
crc_table: .zero 256*4
|
|
|
|
.text
|
|
_start:
|
|
# ignore SIGPIPE
|
|
li a7, 134 # sys_rt_sigaction
|
|
li a0, 13 # SIGPIPE
|
|
la a1, sigaction_ignore # action
|
|
li a2, 0 # oldact = NULL
|
|
# if this is a non-null pointer the kernel will
|
|
# return a copy of the old action to us, but we don't care
|
|
li a3, 8 # signal set size (bytes)
|
|
ecall
|
|
|
|
# TODO: error messages
|
|
|
|
call init_table
|
|
|
|
li s1, 0 # CRC
|
|
|
|
loop:
|
|
li a7, 63 # sys_read
|
|
li a0, 0 # fd = stdin
|
|
la a1, buf # pointer to buffer
|
|
li a2, bufsize # 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
|
|
|
|
mv s0, a0
|
|
|
|
# loop over buffer and update crc
|
|
mv a0, s1
|
|
la a1, buf
|
|
mv a2, s0 # buf size
|
|
call crc_update
|
|
mv s1, a0
|
|
|
|
bnez s0, loop # loop if not end of input
|
|
|
|
error:
|
|
li a7, 93 # sys_exit
|
|
li a0, 1 # status code = failure
|
|
ecall
|
|
|
|
done:
|
|
#la a0, crc_table
|
|
#addi a0, a0, 4*0x80
|
|
#lwu a0, (a0)
|
|
#mv s1, a0
|
|
|
|
# encode crc
|
|
la a0, buf
|
|
mv a1, s1
|
|
call u32hex
|
|
|
|
# add newline
|
|
la a1, buf
|
|
li t0, 10 # '\n'
|
|
sb t0, 8(a1)
|
|
|
|
# write crc
|
|
li a7, 64 # sys_write
|
|
li a0, 1 # fd = stdout
|
|
li a2, 9 # size of data
|
|
ecall
|
|
#mv s0, a0
|
|
|
|
# check for EPIPE
|
|
li t0, -32
|
|
beq a0, t0, ok # EPIPE
|
|
bltz a0, error
|
|
|
|
ok:
|
|
li a7, 93 # sys_exit
|
|
li a0, 0 # status code = success
|
|
ecall
|
|
|
|
#............................................
|
|
|
|
.equ poly, 0xEDB88320
|
|
|
|
.text
|
|
init_table:
|
|
la s0, crc_table
|
|
li t6, 256
|
|
li a0, poly
|
|
iloop:
|
|
addi t6, t6, -1
|
|
mv t0, t6
|
|
li t2, 8
|
|
iloop2:
|
|
andi t1, t0, 1
|
|
srli t0, t0, 1
|
|
beqz t1, 0f
|
|
xor t0, t0, a0
|
|
0:
|
|
addi t2, t2, -1
|
|
bnez t2, iloop2
|
|
|
|
slli t1, t6, 2
|
|
add t1, t1, s0
|
|
sw t0, (t1)
|
|
bnez t6, iloop
|
|
ret
|
|
|
|
#............................................
|
|
|
|
# inputs:
|
|
# a0: crc
|
|
# a1: buf
|
|
# a2: buf size
|
|
#
|
|
# returns:
|
|
# a0 - new crc
|
|
#
|
|
# clobbers: t0, t1, t2, t3
|
|
.text
|
|
crc_update:
|
|
mv t1, s0
|
|
mv t2, s1
|
|
mv t3, s2
|
|
# invert crc
|
|
li t0, -1
|
|
srli t0, t0, 32
|
|
xor a0, a0, t0
|
|
|
|
mv s0, a0 # crc
|
|
mv s1, a1 # buffer
|
|
la s2, crc_table
|
|
|
|
beqz a2, udone
|
|
|
|
uloop:
|
|
lbu a1, (s1) # load byte
|
|
andi t0, a0, 0xff # a1 = crc&0xff ^ byte
|
|
xor a1, a1, t0
|
|
srli a0, a0, 8 # crc >>= 8
|
|
slli a1, a1, 2 # convert a1 to table address
|
|
add a1, a1, s2
|
|
lwu a1, (a1) # load crc table entry
|
|
xor a0, a0, a1 # crc ^= table entry
|
|
|
|
addi s1, s1, 1
|
|
addi a2, a2, -1
|
|
bnez a2, uloop
|
|
|
|
udone:
|
|
# restore saved registers
|
|
mv s0, t1
|
|
mv s1, t2
|
|
mv s2, t3
|
|
# invert crc
|
|
#li t0, -1
|
|
#srli t0, t0, 32
|
|
li t0, 0xFFFFFFFF
|
|
xor a0, a0, t0
|
|
ret
|