[英]segmentation fault and hang in assembly code
我正在從Fascicle 1重新實現Knuth的程序P:生成前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”處設置斷點來看出。
$ gdb ./a.out
(gdb) b end
Breakpoint 1 at 0x400531
(gdb) run
Starting program: /home/ben/src/hg/asm/knuth/a.out
Breakpoint 1, 0x0000000000400531 in end ()
(gdb) p $rbx
$1 = 3571
一旦我嘗試調用printf,它就會出錯,所以我假設我正在做一些愚蠢的堆棧。
printf
在x86-64中期望%rax
中的值告訴函數浮點參數的數量。 在你的情況下,沒有這樣的論點,所以明確%rax
(清除%eax
也清除%rax
)。 你的程序似乎運行良好的變化:
...
loop:
leaq fmt, %rdi
movzwl x(,j,2), %esi
xor %eax, %eax
call printf
...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.