【问题标题】:Segfault accessing BSS memory访问 BSS 内存的段错误
【发布时间】:2013-05-01 17:52:25
【问题描述】:
section .data
    bufChar:    equ 0

section .bss
bufNum:     resb    1
bufMult:    resb    1

。 . .

leerNumero:
    xor eax,eax
    mov [bufNum],eax
    add eax,1
    mov [bufMult],eax
inicioLeerNumero:
    mov edx,1
    mov ecx,bufChar
    mov ebx,0
    mov eax,3
    int 80h
    cmp byte [ecx + edx - 1],10 ; Segfaults here.
    je  rLeerNumero
    cmp byte [ecx + edx - 1],48
    jl  noNumero
    cmp byte [ecx + edx - 1],57
    jg  noNumero
    sub eax,48
    mul word [bufMult]
    jo  overflow
    add [bufNum],eax
    jo  overflow
    mov eax,10
    mul word [bufMult]
    jo  overflow
    mov [bufMult],eax
    jmp inicioLeerNumero
rLeerNumero:
    mov eax,bufNum
    ret
noNumero:
    mov eax,errorNumero
    mov ebx,lErrorNumero
    call    imprimir
    jmp salir
overflow:
    mov eax,errorOverflow
    mov ebx,lErrorOverflow
    call    imprimir
    jmp salir

这段代码应该可以工作,至少在纸面上是可以的。我需要在不链接 C 库的情况下完全在汇编中完成一些作业,因此我为什么要重新发明轮子并制作一种方法来将控制台中的数字读入 EAX。

我在标有注释的行中有一个神秘的段错误,我看不到我是如何尝试访问未对齐的内存的……关于这怎么可能失败的任何想法?

【问题讨论】:

  • 使用objdump -d obj.o 验证mov ecx, bufChar 确实加载了地址(而不仅仅是偏移量,或变量的内容。)
  • mov ecx,bufChar 正在转换为 mov $0x0,%ecx.... 是否真的试图移动到 0x00000000?
  • 我想知道...它是否真的打破了 on mov,或者是指令 EIP 当前指向(这似乎暗示系统调用正确之前)?
  • @Machinarius:这是 GAS/AT&T 语法;源操作数和目标操作数与大多数 x86 汇编器显示它们的方式相反。 mov $0x0, %ecx 等价于 mov ecx, 0

标签: linux assembly nasm


【解决方案1】:

int 80h 改变 ecxedx 是否有可能导致错误的指针读取?如果您可以在该指令之前和之后读取调试器中的寄存器,则可以确认。

【讨论】:

  • int 80h“不应该”修改除eax以外的任何寄存器(结果或错误)。 bufChar 没有显示,所以我们不知道它是什么。 bufNumbufMult 各自保留一个字节,而您将 eax(4 个字节)移动到它们中。这个“可能”不会出现段错误,但它是错误的!告诉我们bufChar
  • 有些系统调用可能会更改更多的寄存器但 eax,例如:waitpid - 等待进程终止。返回值为:已完成进程的 eax pid |孩子 | EINVAL | ERESTART,完成进程的 ecx 退出状态,如果在 ecx 中输入了非零值。
【解决方案2】:

我已将 bufChar 声明为 .data,显然将 mov'ing 转换为常量会造成段错误。可悲的是,我浪费了一周的时间来解决这个问题,才意识到这一点。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-27
    • 2011-12-07
    • 2017-08-28
    • 1970-01-01
    相关资源
    最近更新 更多