2015-02-01 2 views
1

Я повторно реализую программу Кнута P из Fascicle 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 ./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, это недостатки, поэтому я предполагаю, что я делаю что-то глупо со стеком.

ответ

2

printf ожидает в x86-64 значение в %rax, которое сообщает функции количество аргументов с плавающей запятой. В вашем случае таких аргументов нет, поэтому ясно %rax (очистка %eax также очищает %rax). Ваша программа, похоже, работает нормально с изменением:

+0

Огромное вам спасибо, это исправляет его, и программа работает без проблем. Вы чемпион! – spew