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 比较值时出现分段错误_Assembly_X86_Segmentation Fault_Nasm_32 Bit - Fatal编程技术网

Assembly 比较值时出现分段错误

Assembly 比较值时出现分段错误,assembly,x86,segmentation-fault,nasm,32-bit,Assembly,X86,Segmentation Fault,Nasm,32 Bit,我是汇编新手,遇到了一个我不知道如何调试的问题。我正在编写一个非常简单的程序,它接受一个命令行参数,然后打印参数的因子。目的是熟悉决策和循环。到目前为止,我已经成功地将其全部固定在一起,它适用于偶数,但不适用于奇数。此外,它可能会为偶数生成正确的结果,但在最后一次检查后仍会遇到SEGFULT section .bss input: resb 100 count: resb 100 main: mo

我是汇编新手,遇到了一个我不知道如何调试的问题。我正在编写一个非常简单的程序,它接受一个命令行参数,然后打印参数的因子。目的是熟悉决策和循环。到目前为止,我已经成功地将其全部固定在一起,它适用于偶数,但不适用于奇数。此外,它可能会为偶数生成正确的结果,但在最后一次检查后仍会遇到SEGFULT

        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

对我来说,现在很难集中精力进行组装;我有很多东西要学,所以我很感激任何反馈

分段错误是由
添加esp,16
引起的。将6个DWORD(=24字节)推送到堆栈上,因此必须在使用
add esp,24
调用printf后清除堆栈

你的代码不可编译。这个对我很有用:

; 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,则必须使用系统调用(int 80h/fn 01h)退出。

对于代码中的奇数,我不能产生错误的结果。请把你的帖子加上一个数字,一个预期结果和真实结果。我解释得很糟糕。它不会产生不正确的结果,它会在程序结束时出现错误。这一点你肯定是正确的,我确实在堆栈中有错误的移动次数,但即使有了此修复,仍然会出现错误。@user2325881:我更正了你的代码并将其添加到我的帖子中。可能您使用了错误的汇编器/编译器/链接器命令。