Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 汇编程序中整数的Sqrt 我计划创建一个整数的平方和,所以我想我们只能考虑前逗号部分。我正在使用nasm 64位。 因此,我已经创建了一个伪代码,如下所示: a := value b := 0 while (a-b)>1 a := ((a+b)/2) b := (value/a) end_while result := min{a,b}_Assembly_64 Bit_Nasm_Sqrt - Fatal编程技术网

Assembly 汇编程序中整数的Sqrt 我计划创建一个整数的平方和,所以我想我们只能考虑前逗号部分。我正在使用nasm 64位。 因此,我已经创建了一个伪代码,如下所示: a := value b := 0 while (a-b)>1 a := ((a+b)/2) b := (value/a) end_while result := min{a,b}

Assembly 汇编程序中整数的Sqrt 我计划创建一个整数的平方和,所以我想我们只能考虑前逗号部分。我正在使用nasm 64位。 因此,我已经创建了一个伪代码,如下所示: a := value b := 0 while (a-b)>1 a := ((a+b)/2) b := (value/a) end_while result := min{a,b},assembly,64-bit,nasm,sqrt,Assembly,64 Bit,Nasm,Sqrt,从数学上看,它看起来像: x = max{x ϵ Z | x**2 <=z} x=max{xϵZ | x**2我假定您希望得到的结果也是一个整数。 对于文件: ; uname -m -o: x86_64 GNU/Linux ; Calling convention: System V AMD64 ABI ; Name: isqrt.asm ; Assemble: nasm -felf64 isqrt.as

从数学上看,它看起来像:

x = max{x ϵ Z | x**2 <=z}   

x=max{xϵZ | x**2我假定您希望得到的结果也是一个整数。
对于文件:

; uname -m -o:          x86_64 GNU/Linux
; Calling convention:   System V AMD64 ABI
; Name:                 isqrt.asm
; Assemble:             nasm -felf64 isqrt.asm
; Link:                 gcc -m64 isqrt.o
; Run:                  ./a.out

; b := value
; a := 0
; while (b-a)>1 => while b > a (integer!)
;       b := ((b+a)/2)
;       a := (value/b)
; end_while
; result := b

extern printf
%MACRO PRINT 1
;   extern printf
    mov rdi, %1
    mov rsi, rax
    xor eax, eax
    call printf
%ENDM

section .data
    value: dq 1000
    fmt1: db `isqrt32:   rax=%u\n`,0
    fmt2: db `isqrt64:   rax=%u\n`,0
    fmt3: db `isqrt_fpu: rax=%u\n`,0

section .text
global main:

main:

    mov edi, [value]
    call isqrt32
    PRINT fmt1

    mov rdi, [value]
    call isqrt64
    PRINT fmt2

    mov rdi, [value]
    call isqrt_fpu
    PRINT fmt3

    xor al,al               ; Exitcode 0
    ret

isqrt64:

    mov rbx, rdi
    xor rax, rax

    .while:
    cmp rax, rbx
    jnb .endwhile

    add rbx, rax
    shr rbx, 1

    mov rax, rdi
    xor rdx, rdx
    div rbx

    jmp .while

    .endwhile:
    mov rax, rbx
    ret

isqrt32:

    mov ebx, edi
    xor eax, eax

    .while:
    cmp eax, ebx
    jnb .endwhile

    add ebx, eax
    shr ebx, 1
    mov eax, edi
    xor edx, edx
    div ebx

    jmp .while

    .endwhile:
    mov eax, ebx
    ret

isqrt_fpu:

    push rdi
    fild qword [rsp]
    fsqrt
    fisttp qword [rsp]
    pop rax
    ret

希望有人能给我一个提示,告诉我如何继续。看起来这个问题以前已经解决了:你有很好的伪代码…进一步分解它,开始编写各个步骤…如果你愿意,从内部开始:x=a+b;x=x/2,y=value/x…转换到寄存器…RAX=(a)+(b)(add),RAX=RAX/2(idiv或div),RBX=RAX,RAX=value/RBX(再次idiv/div)…不要试图简化或改进…先让它工作…大量的寄存器…小步骤,你会明白的。也许可以看看我关于在汇编中乘法的另一篇帖子:@Matthew coudl你告诉我什么是[esp+4]?[esp+4]指内存位置,由寄存器esp(堆栈指针)和4的内容之和寻址