Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.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 分段错误和挂起汇编代码_Assembly_X86 64_Knuth - Fatal编程技术网

Assembly 分段错误和挂起汇编代码

Assembly 分段错误和挂起汇编代码,assembly,x86-64,knuth,Assembly,X86 64,Knuth,我正在重新实现Knuth的程序p,它来自分册1:生成前500个素数。程序生成前25个素数时没有问题。代码如下: $ cat progp.S /* print the first 500 primes */ #define n %bx #define j %r12 #define k %r13 #define pk %r14d .data fmt: .asciz "%d\n" x: .space 1000

我正在重新实现Knuth的程序p,它来自分册1:生成前500个素数。程序生成前25个素数时没有问题。代码如下:

$ cat progp.S
/* print the first 500 primes */

#define n       %bx
#define j       %r12
#define k       %r13
#define pk      %r14d

        .data
fmt:    .asciz  "%d\n"
x:      .space 1000

        .text
        .globl  main
        .type   main, @function
main:
        pushq   %rbp
        movq    %rsp, %rbp
        xorq    %rbx, %rbx
        movw    $2, x
        movw    $3, n
        movq    $1, j
Mtwo:
        movw    n, x(,j,2)
        incq    j
Mthree:
        cmpq    $500, j
        je      end
Mfour:
        addw    $2, n
Mfive:
        movq    $1, k
Msix:
        movzwl  x(,k,2), pk
        movzwl  n, %eax
        xorq    %rdx, %rdx
        divl    pk
        cmpl    $0, %edx
        je      Mfour
Mseven:
        cmpl    pk, %eax
        jle     Mtwo
Meight:
        incq    k
        jmp     Msix
end:
        xorq    j, j
loop:
        leaq    fmt, %rdi
        movzwl  x(,j,2), %esi
        call    printf
        incq    j
        cmpq    $25, j
        je      bye
        jmp     loop
bye:
        movl    $0, %edi
        callq   exit
        leave
        ret
        .size   main,.-main
        .end
如果将Mthree中的比较值减少到25,则程序正常。任何更高的值都会导致程序出现故障或在printf中挂起

我将其与以下内容组合:

cc -static progp.S
我还可以补充一点,在不调用printf的情况下,它成功地生成了前500个素数,这可以从在gdb中将断点放在“end”处看到


只要我尝试调用printf,它就会出现故障,因此我假设我对堆栈做了一些愚蠢的事情。

printf
在x86-64中需要一个
%rax
中的值,该值告诉函数浮点参数的数量。在您的情况下,没有此类参数,因此清除
%rax
(清除
%eax
也会清除
%rax
)。您的程序似乎在进行更改后运行良好:

...
loop:
        leaq    fmt, %rdi
        movzwl  x(,j,2), %esi
        xor     %eax, %eax
        call    printf
...

非常感谢,这修复了它,程序运行没有任何问题。你是冠军!
...
loop:
        leaq    fmt, %rdi
        movzwl  x(,j,2), %esi
        xor     %eax, %eax
        call    printf
...