section .data
A dq 1
B dq 0
C dq -1
D dq 0
sqrtD dq 0
root1 dq 0
root2 dq 0
msg_no_roots db "No real roots", 0
comma_space db ", ", 0
buffer: times 20 db 0
minus: db '-'
digit: db 0
section .text
global _start
_start:
; calculate discriminant: D = B*B - 4*A*C
mov rax, [B]
imul rax, rax ; rax = B*B
mov rbx, 4
imul rbx, [A]
imul rbx, [C] ; rbx = 4*A*C
sub rax, rbx ; rax = D
; if D < 0, print "No real roots" and exit
cmp rax, 0
jl no_real_roots
; calculate sqrt(D) using Newton-Raphson method
mov rcx, rax ; rcx = D
mov [D], rax
shr rcx, 1 ; initial guess for sqrt(D) is D/2
sqrt_loop:
mov rax, [D]
idiv rcx
add rax, rcx
shr rax, 1
cmp rax, rcx
jne sqrt_loop
; rax now contains sqrt(D)
; calculate roots: root1 = (-B + sqrt(D)) / (2*A), root2 = (-B - sqrt(D)) / (2*A)
mov [sqrtD], rax
mov rbx, [B]
sub rax, rbx
mov rbx, rax
mov rax, 2
imul rax, [A]
mov [D], rax
mov rax, rbx
mov rbx, [D]
idiv rbx
mov [root1], rax
mov rax, [sqrtD]
mov rbx, [B]
add rax, rbx
neg rax
mov rbx, rax
mov rax, 2
imul rax, [A]
mov [D], rax
mov rax, rbx
mov rbx, [D]
idiv rbx
mov [root2], rax
; print root1
mov R8, 19
mov rax, [root1]
cmp rax, 0
jge store_digits
mov rdi, 1
mov rsi, minus
mov rdx, 1
mov rax, 1
syscall
mov rax, [root1]
neg rax
store_digits:
mov rbx, 10
cqo
idiv rbx
add dl, '0'
mov [buffer + R8], dl
dec R8
test rax, rax
jnz store_digits
mov R8, 0
find_start:
cmp byte [buffer + R8], '0'
je increment_index
jmp print_digits
increment_index:
inc R8
jmp find_start
print_digits:
mov al, [buffer + R8]
mov [digit], al
mov r13, rax
mov r14, rdx
mov rax, 1
mov rdi, 1
mov rsi, digit
mov rdx, 1
syscall
mov rax, r13
mov rdx, r14
inc R8
cmp R8, 20
jb print_digits
; print comma and space
mov rax, 1 ; syscall number for sys_write
mov rdi, 1 ; file descriptor 1 is stdout
mov rsi, comma_space
mov rdx, 2
syscall
; print root2
mov R8, 19
mov rax, [root2]
cmp rax, 0
jge store_digits2
mov rdi, 1
mov rsi, minus
mov rdx, 1
mov rax, 1
syscall
mov rax, [root2]
neg rax
store_digits2:
mov rbx, 10
cqo
idiv rbx
add dl, '0'
mov [buffer + R8], dl
dec R8
test rax, rax
jnz store_digits2
mov R8, 0
find_start2:
cmp byte [buffer + R8], '0'
je increment_index2
jmp print_digits2
increment_index2:
inc R8
jmp find_start2
print_digits2:
mov al, [buffer + R8]
mov [digit], al
mov r13, rax
mov r14, rdx
mov rax, 1
mov rdi, 1
mov rsi, digit
mov rdx, 1
syscall
mov rax, r13
mov rdx, r14
inc R8
cmp R8, 20
jb print_digits2
jmp end
no_real_roots:
mov rax, 1 ; syscall number for sys_write
mov rdi, 1 ; file descriptor 1 is stdout
mov rsi, msg_no_roots
mov rdx, 14
syscall
jmp end
end:
; exit program
mov rax, 60 ; syscall number for sys_exit
xor rdi, rdi ; exit code 0
syscall