2013-05-01 80 views
1
section .data 
    bufChar: equ 0 

section .bss 
bufNum:  resb 1 
bufMult: resb 1 

。 。 。Segfault访问BSS存储器

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读取一个数字。

我在标记为注释的行处有一个神秘的段错误,我无法看到我是如何尝试访问未对齐的内存......关于如何失败的任何想法?

+0

使用'objdump -d obj.o'来验证'mov ecx,bufChar'确实加载了地址(而不仅仅是偏移量或变量的内容。) – 2013-05-01 18:31:08

+0

mov ecx,bufChar正在转换为mov $ 0x0,%ecx ....是否真的试图进入0x00000000? – Machinarius 2013-05-01 19:44:49

+0

我不得不怀疑......它实际上是否打破了mov,或者是EIP目前指向的指令(这似乎牵涉到系统调用之前)? – cHao 2013-05-01 19:53:52

回答

0

任何机会int 80h正在改变ecxedx对你造成错误的指针读取?如果您可以在该指令前后在调试器中读取寄存器,则可以确认。

+0

int 80h'“不应该”修改任何寄存器,而是修改'eax'(结果或错误)。 'bufChar'没有显示,所以我们不知道它是什么。 'bufNum'和'bufMult'各自保留一个字节,并且将'eax'(4个字节)移入它们中。这个“可能”不会segfault,但它是错误的!告诉我们'bufChar'。 – 2013-05-01 19:24:01

+0

有系统调用可能会更改更多的寄存器,但eax,例如:waitpid - 等待进程终止。返回值为:eax \t完成进程的pid | ECHILD | EINVAL | ERESTART,ecx \t完成过程的退出状态,如果在ecx中输入了非零值。 – Farseer 2013-05-12 13:47:35

0

我已经声明bufChar为.data,显然mov'变成一个常量会segfault的东西。可悲的是,我浪费了一周的时间,只是意识到这一点。