【问题标题】:Segmentation Fault When Comparing a Value比较值时出现分段错误
【发布时间】:2014-10-23 02:59:54
【问题描述】:

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

        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

现在组装对我来说非常困难;我有很多东西要学,所以我很感激任何反馈。

【问题讨论】:

  • 我不能用你的代码为奇数产生错误的结果。请在帖子中添加数字、预期结果和实际结果。
  • 我解释得很糟糕。它不会产生错误的结果,它会在程序结束时出现段错误。

标签: assembly x86 segmentation-fault nasm 32-bit


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

【讨论】:

  • 你说得很对,我确实在堆栈中移动了错误的数量,但是,即使有了这个修复,段错误仍然会发生。
  • @user2325881:我更正了您的代码并将其添加到我的帖子中。也许你使用了错误的汇编器/编译器/链接器命令。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-21
  • 1970-01-01
  • 2022-11-18
  • 1970-01-01
  • 2018-01-07
  • 1970-01-01
相关资源
最近更新 更多