section .data
A dq 1
B dq -60
C dq 900
D dq 2
single_root db "Single root: ", 0
single_len equ $ - single_root
two_roots db "The roots: ", 0
two_lens equ $ - two_roots
no_real_roots db "No real roots", 0
no_len equ $ - no_real_roots
comma db ",", 0
comma_len equ $ - comma
section .bss
buffer resb 20 ; 用于存储 ASCII 码的缓冲区
number resb 1 ; 存储当前数字位的 ASCII 码
section .text
global _start
_start:
mov rax, [B]
imul rax, [B]
mov rbx, rax
mov rax, 4
imul rax, [A]
imul rax, [C]
mov rcx, rax
sub rbx, rcx
mov rax, rbx
cmp rax, 0
je single_root
jl no_real_roots
mov r9, rax ;guess value
mov r10, rax ;original value
single_root_iteration:
mov rax, r10
mov r15, r9
xor rdx, rdx
idiv r9
add rax, r9
mov r13, [D]
xor rdx, rdx
idiv r13
mov r9, rax ;quotient in rax gives to r9
neg rax
add rax, r15
cmp rax, 0
jg single_root_iteration
two_roots:
mov rax, 1
mov rdi, 1
mov rsi, two_roots
mov rdx, two_lens
syscall
mov r8, r9
mov rbx, [B]
neg rbx
add r9, rbx
mov rax, r9
mov rcx, [A]
imul rcx, 2
xor rdx, rdx
idiv rcx
mov rbx, rax
mov rax, rbx
mov r10, 0 ; 数位计数器和缓冲区偏移量,同时指向空闲单元
mov rbx, 10 ; 除数
cont_loop_start:
cqo ; 将 RAX 扩展为 RDX:RAX 以进行除法运算
idiv rbx ; RAX = RDX:RAX / RBX,商存储在 RAX 中,余数存储在 RDX 中
add dl, '0' ; 将余数转换为 ASCII 码
mov [buffer + r10], dl ; 存储到缓冲区
inc r10
cmp rax, 0 ; 检查商是否为 0
jnz cont_loop_start ; 如果不为 0,则继续循环
mov rcx, r10 ; 将位数存储在 RCX 中
prin_loop_start:
dec r10 ; 到最后一个处理的数位
mov al, [buffer + r10] ; 将 [buf+r8] 移动到 AL 寄存器
mov [number], al ; 将 AL 存储到 digit 变量(用于打印)
mov rax, 1 ; 'write' 系统调用号
mov rdi, 1 ; 标准输出描述符
mov rsi, number ; 字符串地址
mov rdx, 1 ; 字符串长度(字节数)
syscall
cmp r10, 0 ; 检查是否到达第一位
jnz prin_loop_start ; 如果不是第一位,则继续循环
mov rax, 1
mov rdi, 1
mov rsi, comma
mov rdx, comma_len
syscall
mov rbx, [B]
neg rbx
neg r8
add r8, rbx
mov rax, r8
mov rcx, [A]
imul rcx, 2
xor rdx, rdx
idiv rcx
mov rbx, rax
jmp print_any_digits_numbers
jmp end
single_root:
mov rbx, [B]
neg rbx
mov rax, rbx
mov rcx, [A]
imul rcx, 2
xor rdx, rdx
idiv rcx
mov rbx, rax
mov rax, 1
mov rdi, 1
mov rsi, single_root
mov rdx, single_len
syscall
jmp print_any_digits_numbers
print_any_digits_numbers:
mov rax, rbx
mov r10, 0 ; 数位计数器和缓冲区偏移量,同时指向空闲单元
mov rbx, 10 ; 除数
conv_loop_start:
cqo ; 将 RAX 扩展为 RDX:RAX 以进行除法运算
idiv rbx ; RAX = RDX:RAX / RBX,商存储在 RAX 中,余数存储在 RDX 中
add dl, '0' ; 将余数转换为 ASCII 码
mov [buffer + r10], dl ; 存储到缓冲区
inc r10
cmp rax, 0 ; 检查商是否为 0
jnz conv_loop_start ; 如果不为 0,则继续循环
mov rcx, r10 ; 将位数存储在 RCX 中
print_loop_start:
dec r10 ; 到最后一个处理的数位
mov al, [buffer + r10] ; 将 [buf+r8] 移动到 AL 寄存器
mov [number], al ; 将 AL 存储到 digit 变量(用于打印)
mov rax, 1 ; 'write' 系统调用号
mov rdi, 1 ; 标准输出描述符
mov rsi, number ; 字符串地址
mov rdx, 1 ; 字符串长度(字节数)
syscall
cmp r10, 0 ; 检查是否到达第一位
jnz print_loop_start ; 如果不是第一位,则继续循环
jmp end
no_real_roots:
mov rax, 1
mov rdi, 1
mov rsi, no_real_roots
mov rdx, no_len
syscall
end:
mov rax, 60
xor rdi, rdi
syscall