【问题标题】:Segmentation-fault error happening with Assembly code program汇编代码程序发生分段错误错误
【发布时间】:2011-03-19 20:36:57
【问题描述】:

我在运行代码时不断收到分段错误错误。一切都编译得很好,但我似乎无法让它做我想做的事。该程序要求用户输入 3 个整数,然后询问用户他们认为这些数字的平均值是多少,将其考虑在内,然后返回用户是否猜对了

    segment .data
;
; Output strings
;
prompt1          db    "Enter a positive integer: ", 0
prompt2          db    "Enter a second positive integer: ", 0
prompt3          db    "Enter a third positive integer: ", 0
prompt4      db    "Enter a guess of their average: ", 0   
outmsg1          db    "You entered ", 0
outmsg2          db    " and ", 0
outmsg3          db    " and ", 0
outmsg4      db    "You guessed that the average is ", 0
outmsg5      db    "You did you guess correctly? (0 = no, 1 = yes)", 0
avermsg      db    "The average of the numbers is ", 0


segment .bss

input1   resd 1
input2   resd 1
input3   resd 1
input4   resd 1
guess    resd 1

segment .text
        Global  main
main:
        enter   0,0               ; setup routine
        pusha

        mov     eax, prompt1      ; print out prompt1
        call    print_string

        call    read_int          ; read integer    
        mov     [input1], eax     ; store integer into input1


        mov     eax, prompt2      ; print out prompt2
        call    print_string

    call    read_int      ; read integer
    mov [input2], eax     ; store integer into input2

    mov     eax, prompt3      ; print out prompt3
        call    print_string

    call    read_int      ; read integer
    mov     [input3], eax     ; store integer into input3

    mov eax, prompt4      ; print out prompt4
    call    print_string      

    call    read_int      ; read integer
    mov [guess], eax


    mov eax, [input1]     ; eax = dword at input1
    add eax, [input2]     ; eax += dword at input2
    add eax, [input3]     ; eax += dword at input3
    mov ebx, 3          
    div ebx       ; divides the sum by 3
    mov ecx, eax      ; freeing up eax, puts quotient into ecx

    dump_regs 1       ; print out register values

; next print out results    
    mov    eax, outmsg1
    call   print_string   ; print out first message
    mov    eax, [input1]
    call   print_int

    mov    eax, outmsg2   
    call   print_string   ; print out second message
    mov    eax, [input2]
    call   print_int

    mov    eax, outmsg3
    call   print_string       ; print out  thrid message
    mov    eax, [input3]
    call   print_int    

    mov eax, outmsg4
    call    print_string      ; print out fourth message
    mov eax, [input4]
    call    print_int   

    xor    ebx, ebx
    cmp    ecx, [guess]

    sete   bl
    neg    ebx
    mov    edx, ebx
    and    ecx, edx
    not    ebx
    and    ebx, [guess]
    or     edx, ebx

    mov    eax, outmsg5
    call   print_string
    mov    ecx, eax
    call   print_int

    mov    eax, [avermsg]
    call   print_string   ; print out final message
    mov    ecx, edx
    call   print_int      ; print out average of ebx
    call   print_nl       ; print new line

    popa
    mov eax, 0        ; return back to C
    leave
    ret

【问题讨论】:

  • 请格式化代码,使其在此处可读,并查明失败的确切位置。 asm 很难按原样阅读。
  • 感谢digitalRoss,我不确定分段错误发生在哪里,它在运行时发生。
  • 您提供的代码不包括read_intprint_stringprint_intprint_nl 例程,其中任何一个都可能相关。
  • 程序应该做的事情在它死前实际上做了多少(如果有的话)?它打印任何东西吗?接受任何用户输入?即使您不能告诉我们是什么指令触发了段错误,您也应该能够从程序在发生错误之前设法执行多少操作来确定它何时发生。
  • @yes123:为什么不呢?我认为 OP 正在学习底层硬件的实际工作原理,这很棒。

标签: linux assembly segmentation-fault nasm


【解决方案1】:

在不知道你使用的编译器的情况下,很难查明问题。

分段错误发生在保护模式下,当您尝试访问您无权访问的分段时。

您在这里声明了 3 个不同的段。在调用 print_string 之前,您必须确保您的 ds 寄存器已初始化为您的 .data 段。

read_int 之后将数据保存到input1 变量似乎也有问题,该变量似乎与您用于打印消息的段不同,但您没有更改ds

我不熟悉您的编译器如何处理这些段,所以请提供其文档的链接。

【讨论】:

    【解决方案2】:
    div ebx
    

    问题似乎在这里。您必须将 edx 归零,因为 is 是除数的高位字,因此您可能会遇到 除法溢出 异常。
    如果不是这种情况,则问题可能出在您的某些 I/O 例程中

    【讨论】:

    • 我认为不可能。分段错误显然是一个内存处理问题。
    猜你喜欢
    • 2023-03-12
    • 1970-01-01
    • 2012-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多