section .bss
input_char resb 1 ; Reserve 1 byte for the input character
; registers
; r12 num a
section .data
total dq 0 ; the total sum
num dq 0 ; entry integer
print_char db 0
section .text
global _start
is_digit:
; check if value of input_char is a digit
cmp byte [input_char], '0'
jl not_digit
cmp byte [input_char], '9'
jg not_digit
mov rax, 1
ret
not_digit:
xor rax, rax; set 0
ret
error:
mov rax, 60
mov rdi, 1
syscall
read_char:
; Read a single character
mov rax, 0 ; sys_read
mov rdi, 0 ; fd 0 (standard input)
mov rsi, input_char ; ptr to input
mov rdx, 1 ; number of bytes to read
syscall
ret
sum:
add [total], r12
mov r12, 0
ret
number_input:
call read_char
cmp byte [input_char], 10 ; \n
je sum
cmp byte [input_char], -1 ; EOF
je error
call is_digit
cmp rax, 0
je error
call is_digit
je append_number
append_number:
imul r12, 10
sub byte [input_char], '0' ; char to num
movzx r13, byte [input_char] ; zero-extend the byte to 64 bits
add r12, r13
call number_input
ret
reverse_number:
mov r13, rdi ; r13 = input number
xor r14, r14 ; r14 = 0
call reverse_loop
mov rax, r14
ret
reverse_loop:
imul r14, r14, 10
mov rax, r13
xor rdx, rdx
mov rcx, 10
div rcx
add r14, rdx
mov r13, rax
cmp r13, 0
jg reverse_loop ; continue loop if r13 > 0
ret
print_number:
call reverse_number
mov r13, rax ; number to print/decrement
call print_number_loop
ret
print_number_loop:
; divide r13 and puts it back with 1 less digit on right
mov rax, r13
mov rcx, 10
mov rdx, 0
div rcx
mov r13, rax
; print remainder
mov [print_char], rdx;
add byte [print_char], '0'
mov rax, 1 ; sys_write system call number
mov rdi, 1 ; file descriptor 1 (stdout)
mov rsi, print_char ; pointer to the character
mov rdx, 1 ; number of bytes to write
syscall
cmp r13, 0
jg print_number_loop ; continue loop if r13 > 0
ret
_start:
call number_input
call number_input
call sum
mov rdi, [total]
call print_number
mov [print_char], byte 10 ; newline
mov rax, 1
mov rdi, 1
mov rsi, print_char
mov rdx, 1
syscall
mov rax, 60 ; System call number for sys_exit
mov rdi, 0 ; Exit code 0
syscall