;
; Calculate fibonacci number
;
; Ref C code:
; https://www.programiz.com/c-programming/examples/fibonacci-series
;
.text
_main:
mov %r0, #300000 ; n = 100
mov %r9, #10 ; r9 = 10
mul %r0, %r9
mov %r1, #1 ; i = 0
mov %r3, #0 ; t1 = 0
mov %r4, #1 ; t2 = 1
mov %r6, #1 ; inc = 1
loop:
mov %r5, %r3 ; nextTerm = t1
add %r5, %r4 ; nextTerm = t1 + t2
mov %r3, %r4 ; t1 = t2
mov %r4, %r5 ; t2 = nextTerm
add %r1, %r6 ; i++
cmp %r1, %r0 ; if (i != n)
jne @loop
; print the result
mov %r0, %r5
; call @_print_number
; ; exit
; mov %r0, %r5
; ioctl Syscall_exit
ret ; TODO: program exit from ret from main
; TODO: assembler doesn't warn when label is defined twice
_print_number:
mov %r8, #0 ; r8 = 0
mov %r9, #10 ; r9 = 10
mov %r3, @zero
mov %r4, [%r3] ; r4 = '0'
mov %r2, #10000 ; r2/place = 1000000000
mul %r2, %r2 ; limited to 24-bit immediates by the vm codes
mul %r2, %r9 ; r2 = 1,000,000,000 = required amount for doing 32-bit number printing
find_non_leading_zero:
mov %r7, %r0 ; tmp = num
div %r7, %r2 ; tmp /= place
div %r2, %r9 ; place /= 10
cmp %r2, %r8
je @print_last
cmp %r7, %r8 ; tmp == 0
je @find_non_leading_zero
mul %r2, %r9
printing_rest:
mov %r6, %r0
mov %r3, %r7 ; tmp2 = tmp
add %r3, %r4 ; tmp2 += '0'
mov %r0, %r3
ioctl Syscall_putc
mov %r0, %r6
mul %r7, %r2
sub %r0, %r7
div %r2, %r9 ; place /= 10
cmp %r2, %r8
je @done
mov %r7, %r0 ; tmp = num
div %r7, %r2 ; tmp /= place
jmp @printing_rest
print_last:
mov %r0, %r7
add %r0, %r4 ; num += '0'
ioctl Syscall_putc
done:
mov %r0, @newline
mov %r0, [%r0]
ioctl Syscall_putc
ret
_print_string:
mov %r3, #1
mov %r0, [%r2]
loop3:
ioctl Syscall_putc
add %r2, %r3
mov %r0, [%r2]
cmp %r0, %r4
jne @loop3
ret
.data
zero:
db "0" ; TODO: work around for not being able to assign a char literal to a register
newline:
db "\n"
str:
db "hello world\n" ; comment test