编辑代码

section .data
    number_1 dd 25
    number_2 dd 36
    A dq 2
    msg_square_root db "The square root is: ", 0
    msg_square_root_len equ $ - msg_square_root
    newline db 0x0A

section .bss
    buf resb 20                    ; 用于存储 ASCII 码的缓冲区
    digit resb 1                   ; 存储当前数字位的 ASCII 码

section .text
    global _start

_start:
    push qword [number_1]          ;将number_1压入栈

    call single_root
    
    mov rax, 1                  ; 'write' 系统调用号
    mov rdi, 1                  ; 标准输出描述符
    mov rsi, newline             ; 字符串地址
    mov rdx, 1                  ; 字符串长度(字节数)
    syscall
    
    push qword [number_2]          ;将number_2压入栈
    call single_root

    mov rax, 60
    xor rdi, rdi
    syscall

single_root:
    push rbp             ; 保存调用者的基址指针
    mov rbp, rsp         ; 设置当前的基址指针
    sub rsp, 8           ; 为局部变量分配空间

    push r9              ;保存用于计算的寄存器r9
    push r10             ;保存用于计算的寄存器r10
    push r13             ;保存用于计算的寄存器r13
    push r15             ;保存用于计算的寄存器r15

    mov r9d, [rbp+16]      ;把第一个数存储到r9中
    mov r10d, [rbp+16]     ;把第一个数存储到r10中
    shr r9, 1    ; initial guess for sqrt(D) is D/2, quicker search
    call single_root_iteration
    ret

single_root_iteration:
    mov rax, r10
    mov r15, r9
    xor rdx, rdx
    idiv r9    
    add rax, r9
    mov r13, [A]
    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
    mov [rbp-8], r9
    call print_any_digits_numbers

    pop r9		    ; restore r9
	pop r10         ; restore r10
    pop r13         ; restore r13
    pop r15         ; restorer 15
	mov	rsp, rbp	; restore stack pointer. It's equal to removing local variables from the stack
	pop rbp			; restore RBP
    ret

print_any_digits_numbers:
    mov rax, [rbp-8]
    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 中

        mov rax, 1
        mov rdi, 1
        mov rsi, msg_square_root
        mov rdx, msg_square_root_len
        syscall

    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        ; 如果不是第一位,则继续循环
    ret