2014-08-29 6 views
0

Я новичок в сборке, и у меня возникла проблема, из-за которой я не знаю, как отлаживать. Я пишу очень простую программу, которая принимает аргумент командной строки, а затем печатает факторы для аргумента. Цель состоит в том, чтобы ознакомиться с решениями и циклами. Мне удалось собрать все это вместе, и он работает для четных чисел, но не будет работать для нечетных чисел. Кроме того, он может давать правильные результаты для четных чисел, но после последней проверки он по-прежнему сталкивается с segfault.Ошибка сегментации при сравнении значения

 section .bss 
     input: resb 100 
     count: resb 100 


     main: 
       mov ecx,[esp+8]    ;point to command line arguement 
       mov eax,[ecx+4]    ;extract second element 


       push dword eax    ;segfaults without dword. 
       call atoi     ;convert the ascii from cmd line into integer. 
       add esp,4 
       mov dword [input],eax  ;copy original 

       xor edx, edx    ;zero out edx to prevent division error. [2] 
       mov ebx,2 
       div ebx      ;divide eax by ebx. quotient stored in eax, remainder stored in edx. 

       mov [count],eax    ;make a copy of the original argument/2, no number larger can be a factor. 

       jmp checkAgain 

     ret 

     ;strFormat db `Count: %d, Quotient: %d, Remainder: %d, Input: %d, EBX: %d\n`,0 

     true: 
       push ebx 
       push dword [input] 
       push edx 
       push eax 
       push dword [count] 

       push strFormat 
       call printf 
       add esp,16 
       cmp dword [count],0 
       jg checkAgain 
     ret 

     checkAgain: 

       xor edx,edx 
       mov eax,[input] 
       mov ebx,[count] 
       div ebx 
       dec dword [count] 
       cmp edx,0 
       je true 
       mov ecx,dword [count]  
       cmp ecx,0    ;this is where I expect the program to end, but it crashes. 
       jg checkAgain 
     ret 

Сборка очень сложна для меня, чтобы обернуть мой разум прямо сейчас; У меня есть чему поучиться, поэтому я ценю отзывы.

+0

Я не могу произвести неправильный результат для нечетных чисел с вашим кодом. Добавьте свой пост с номером, ожидаемым результатом и реальным результатом. – rkhb

+0

Я объяснил это плохо. Он не приводит к неправильным результатам, он исчезает в конце программы. – user2325881

ответ

1

Ошибка сегментации вызвана add esp,16. Вы выталкиваете 6 стеков (= 24 байта) в стек, поэтому вам нужно очистить стек после call printf с помощью add esp,24.

Ваш код не подлежит компиляции. Это один работает для меня:

; Name:  spagfac.asm 
; Assemble: nasm -felf32 spagfac.asm 
; Link:  gcc -m32 -o spagfac spagfac.o 
; Run:  ./spagfac 60 

global main 
extern atoi, printf 

section .bss 
    input: resb 100 
    count: resb 100 

section .data 
    strFormat db `Count: %d, Quotient: %d, Remainder: %d, Input: %d, EBX: %d\n`,0 

section .text 

    main: 
     mov ecx,[esp+8]   ;point to command line arguement 
     mov eax,[ecx+4]   ;extract second element 


     push dword eax   ;segfaults without dword. 
     call atoi    ;convert the ascii from cmd line into integer. 
     add esp,4 
     mov dword [input],eax ;copy original 

     xor edx, edx   ;zero out edx to prevent division error. [2] 
     mov ebx,2 
     div ebx     ;divide eax by ebx. quotient stored in eax, remainder stored in edx. 

     mov [count],eax   ;make a copy of the original argument/2, no number larger can be a factor. 

     jmp checkAgain 

    ret 

    true: 
     push ebx 
     push dword [input] 
     push edx 
     push eax 
     push dword [count] 

     push strFormat 
     call printf 
     add esp,24 
     cmp dword [count],0 
     jg checkAgain 
    ret 

    checkAgain: 

     xor edx,edx 
     mov eax,[input] 
     mov ebx,[count] 
     div ebx 
     dec dword [count] 
     cmp edx,0 
     je true 
     mov ecx,dword [count] 
     cmp ecx,0 
     jg checkAgain 
    ret 

«Выход» с ret работает только с GCC. Если вы используете LD, вам нужно выйти с помощью syscall (int 80h/fn 01h).

+0

Вы определенно правы в этом, у меня было неправильное количество движений в стеке, но даже с этим исправлением segfault все еще происходит. – user2325881

+0

@ user2325881: Я скорректировал ваш код и добавил его в свой пост. Возможно, вы использовали неправильные команды ассемблера/компилятора/компоновщика. – rkhb

Смежные вопросы