section .data
A dq 1
B dq -30
C dq 200
D dq 2
msg_single_root db "Single root: ", 0
msg_single_len equ $ - msg_single_root
msg_two_roots db "The roots: ", 0
msg_two_lens equ $ - msg_two_roots
msg_no_real_roots db "No real roots", 0
msg_no_len equ $ - msg_no_real_roots
msg_delimiter db ",", 0
msg_delimiter_len equ $ - msg_delimiter
section .bss
buf resb 20 ; 用于存储 ASCII 码的缓冲区
digit 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, msg_two_roots
mov rdx, msg_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 [buf + r10], dl ; 存储到缓冲区
inc r10
cmp rax, 0 ; 检查商是否为 0
jnz cont_loop_start ; 如果不为 0,则继续循环
mov rcx, r10 ; 将位数存储在 RCX 中
prin_loop_start:
dec r10 ; 到最后一个处理的数位
mov al, [buf + r10] ; 将 [buf+r8] 移动到 AL 寄存器
mov [digit], al ; 将 AL 存储到 digit 变量(用于打印)
mov rax, 1 ; 'write' 系统调用号
mov rdi, 1 ; 标准输出描述符
mov rsi, digit ; 字符串地址
mov rdx, 1 ; 字符串长度(字节数)
syscall
cmp r10, 0 ; 检查是否到达第一位
jnz prin_loop_start ; 如果不是第一位,则继续循环
mov rax, 1
mov rdi, 1
mov rsi, msg_delimiter
mov rdx, msg_delimiter_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, msg_single_root
mov rdx, msg_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 [buf + r10], dl ; 存储到缓冲区
inc r10
cmp rax, 0 ; 检查商是否为 0
jnz conv_loop_start ; 如果不为 0,则继续循环
mov rcx, r10 ; 将位数存储在 RCX 中
print_loop_start:
dec r10 ; 到最后一个处理的数位
mov al, [buf + r10] ; 将 [buf+r8] 移动到 AL 寄存器
mov [digit], al ; 将 AL 存储到 digit 变量(用于打印)
mov rax, 1 ; 'write' 系统调用号
mov rdi, 1 ; 标准输出描述符
mov rsi, digit ; 字符串地址
mov rdx, 1 ; 字符串长度(字节数)
syscall
cmp r10, 0 ; 检查是否到达第一位
jnz print_loop_start ; 如果不是第一位,则继续循环
jmp end
no_real_roots:
mov rax, 1
mov rdi, 1
mov rsi, msg_no_real_roots
mov rdx, msg_no_len
syscall
end:
mov rax, 60
xor rdi, rdi
syscall