.text
.align 2
.include "macro.mac"
.global _start
_start:
sub sp, sp, #16
mov r0, sp
mov r2, #0
mov r1, #16
mov r7, #384
swi 0
mov r0, #0 @have to do that otherwise the display part doesn't work
ldr r5, [sp]
mov r2, #1 @ buffer length, to write one character, or a newline
mov r11, #0 @ set the digit counter
_loop:
add r11, #1 @ increment the digit counter
cmp r5, #10 @ compare the number with 10
blt _end @ branch if < 10
mov r8, r5
ldr r10, =div_10_reciprocal @ load the magic number for /10
ldr r10, [r10]
umull r3, r4, r5, r10 @ r4 = r5 / 10, r3 is overwritten
mov r5, r4 @ save the divided value
mov r10, #10
mul r9, r4, r10 @ multiply the divided value by 10
sub r8, r9 @ substract the original value to get the remainder
push {r8} @ push the remainder on the stack
b _loop @ back to loop
_end:
mov r8, r5 @ push the last digit, with the highest weight
push {r8}
ldr r1, =asciicounter @ point on =asciicounter
add r6, r11, #48 @ convert the digit counter to ascii
str r6, [r1] @ store it to be displayed
syscall sys_write
ldr r1, =asciinewline @ point on the buffer to write, \n, a newline
syscall sys_write
_reversed:
pop {r8} @ display the number, beginning with the highest weight
ldr r1, =asciicounter @ point on =asciicounter
mov r6, r8
add r6, #48 @ convert the number to ascii
str r6, [r1] @ store it to be displayed
syscall sys_write
subs r11, #1 @ the digit counter is now used for the number display loop
bne _reversed
ldr r1, =asciinewline @ point on the buffer to write, \n, a newline
syscall sys_write
syscall sys_exit
.data
asciicounter: .word 0 @ must be initialized
asciinewline: .ascii "\n" @ \n is a newline
div_10_reciprocal: .word 429496730 @ ceil((2^32)/10)