extern printi64

; Prints an integer to the default console
printi64:

; Check if edi is zero
cmp edi, 0
jne _no_zero

; Setup zero on stack
push 0
mov rsi, rsp
mov byte [rsi], 48
mov byte [rsi+1], 10

; Print zero
mov rax, 1
mov rdx, 2
mov rdi, 1
syscall

; remove zero from stack
add rsp, 8

; return
ret
_no_zero:

; neg flag
xor r8, r8

; Save number into rax
mov rax, rdi
; Allocate 24 bytes for the character pointer
sub rsp, 24
; Save the character pointer
mov rdi, rsp

; Set up values
; The starting offset to the allocation
; We start from the back
mov rcx, 22
; Divides rax by this value
mov rbx, 10

; Check if first bit is set = number is negative
bt rax, 63
jnc _eneg

; set neg flag
mov r8, 1
neg rax
_eneg:

; Start looping
_loop:
; End if number is zero
cmp rax, 0
je _end

; Divide by 10
xor rdx, rdx
div rbx

; Number digit in rdx
add rdx, 48
mov byte [rdi+rcx], dl
dec rcx

jmp _loop
_end:
; Get string length
mov rdx, 23
sub rdx, rcx
; Add \n
mov byte [rdi+23], 10
; If negative, add '-'
cmp r8, 0
je _neq1
; increase pointer dist
dec rcx
; increase size
inc rdx
; Add '-'
mov byte [rdi+rcx+1], 45
_neq1:
; Add the length to the pointer
add rdi, rcx
inc rdi

; Print the number
mov rax, 1
mov rsi, rdi
mov rdi, 1
syscall

; Remove allocation from stack
add rsp, 24
ret
