I am new to assembly, but could anyone teach me how to convert strings to 64-bit integers?
The program should read integers as strings and convert them to 64-bit integers by using 2 registers. And when I input 32-bit integers, the program loads the values correctly, but if I input 64-bit integers i.e. 4294967295, it doesn't.
The commented clang output for strtou64 was copied from another SO answer, just commenting out the ret instructions to inline it.
.eqv SYS_EXITO, 10
.eqv CON_PRTSTR, 4
.eqv CON_RDSTR, 8
.eqv BUFSIZE, 100
.data
prompt:
.asciz "Input 64 bit integer:"
result:
.asciz "Output 64 bit added:"
buf:
.space BUFSIZE
.text
main:
la a0, prompt
li a7, CON_PRTSTR
ecall
la a0, buf
li a1, BUFSIZE
li a7, CON_RDSTR
ecall
# rv32gc clang 14.0 -O3
strtou64:
mv a2, a0
mv s1, a0
lbu a0, 0(a0) # load the first char
addi a3, a0, -48 # *p - '0' a3 is the each digit
li a0, 9
bltu a0, a3, .LBB0_4 # return 0 if the first char is a non-digit
li a0, 0 # should have done these before the branch
li a1, 0 # so a separate ret wouldn't be needed
addi a2, a2, 1 # p++
li a6, 10 # multiplier constant
.LBB0_2: # do{
mulhu a5, a0, a6 # high half of (lo(total) * 10)
mul a1, a1, a6 # hi(total) * 10
add a1, a1, a5 # add the high-half partial products
mul a5, a0, a6 # low half of (lo(total) * 10)
lbu a4, 0(a2) # load *p
add a0, a5, a3 # lo(total) = lo(total*10) + digit
sltu a3, a0, a5 # carry-out from that
add a1, a1, a3 # propagate carry into hi(total)
addi a3, a4, -48 # digit = *p - '0'
addi a2, a2, 1 # p++ done after the load; clang peeled one pointer increment before the loop
bltu a3, a6, .LBB0_2 # }while(digit < 10)
#ret
.LBB0_4:
li a0, 0 # return 0 special case
li a1, 0 # because clang was dumb and didn't load these regs before branching
#ret
fin:
la a0, result
li a7, CON_PRTSTR
ecall
la a0, buf
la a1, strtou64
li a7, CON_PRTSTR
ecall
li a7, SYS_EXITO
ecall