86 lines
2.0 KiB
ArmAsm
86 lines
2.0 KiB
ArmAsm
.intel_syntax noprefix
|
|
|
|
.section .data
|
|
INum: .quad 12
|
|
DNum: .quad 0
|
|
DBy: .quad 1
|
|
Erg: .quad 0
|
|
One: .quad 1
|
|
Zero: .quad 0
|
|
|
|
.section .bss
|
|
.lcomm output_buffer, 32
|
|
|
|
.section .text
|
|
.global _start
|
|
|
|
_start:
|
|
mov rax, [rip + One] # LDA One
|
|
call print_number # OUT
|
|
|
|
NEX:
|
|
mov rax, [rip + INum] # LDA INum
|
|
mov [rip + DNum], rax # STA DNum
|
|
|
|
mov rax, [rip + DBy] # LDA DBy
|
|
add rax, [rip + One] # ADD One
|
|
mov [rip + DBy], rax # STA DBy
|
|
|
|
mov rax, [rip + INum] # LDA INum
|
|
sub rax, [rip + DBy] # SUB DBy
|
|
|
|
jns mod_loop # BRP mod_loop
|
|
jmp halt # HLT
|
|
|
|
mod_loop:
|
|
mov rax, [rip + DNum] # LDA DNum
|
|
sub rax, [rip + DBy] # SUB DBy
|
|
mov [rip + DNum], rax # STA DNum
|
|
|
|
jz PRT # BRZ PRT
|
|
jns mod_loop # BRP mod_loop
|
|
jmp NEX # BRA NEX
|
|
|
|
PRT:
|
|
mov rax, [rip + DBy] # LDA DBy
|
|
call print_number # OUT
|
|
jmp NEX # BRA NEX
|
|
|
|
halt:
|
|
mov rax, 60 # Linux exit syscall
|
|
xor rdi, rdi # Exit status 0
|
|
syscall
|
|
|
|
|
|
# ------------------------------------------------------------
|
|
# print_number
|
|
#
|
|
# Input:
|
|
# RAX = unsigned integer to print
|
|
#
|
|
# Output:
|
|
# Number followed by a newline
|
|
# ------------------------------------------------------------
|
|
print_number:
|
|
lea rsi, [rip + output_buffer + 31]
|
|
mov byte ptr [rsi], 10 # Newline
|
|
mov rcx, 1 # Output length
|
|
mov rbx, 10
|
|
|
|
.convert:
|
|
xor rdx, rdx
|
|
div rbx # RAX / 10; remainder in RDX
|
|
add dl, '0'
|
|
dec rsi
|
|
mov [rsi], dl
|
|
inc rcx
|
|
|
|
test rax, rax
|
|
jne .convert
|
|
|
|
mov rax, 1 # Linux write syscall
|
|
mov rdi, 1 # stdout
|
|
mov rdx, rcx # Number of bytes
|
|
syscall
|
|
ret
|