【问题标题】:Segmentation fault using fgets in assembly在汇编中使用 fgets 的分段错误
【发布时间】:2016-04-23 23:32:34
【问题描述】:

我尝试使用 fgets 将输入读入缓冲区。我推送了 3 个参数,但出现了分段错误。我试图查看 GDB 的问题,但我不明白我收到的消息。
这是代码:

section .rodata
    buffer: db 10
section .text
    align 16 
    global main 
    extern fgets 
    extern stdin  
main: 
    push    ebp
    mov ebp, esp    
    pushad              
    push dword[stdin] 
    push 10;
    push buffer;
    call fgets;
    add esp, 12
    popad           
    mov esp, ebp    
    pop ebp
    ret

这是我收到的信息:

       Program received signal SIGSEGV, Segmentation fault.
       __GI__IO_getline_info (fp=fp@entry=0xf7fb1c20 <_IO_2_1_stdin_>,
       buf=buf@entry=0x80484f0 "\n", n=8, n@entry=9, delim=delim@entry=10,
       extract_delim=extract_delim@entry=1, eof=eof@entry=0x0) at            iogetline.c:86
       86      iogetline.c: No such file or directory.

我的代码有什么问题?

【问题讨论】:

  • 您的 buffer 位于只读数据部分 .rodata 中。将其放在.data 中。尝试写入内存的只读区域时发生段错误。
  • 另外db 10 将分配一个值为10 的字节,而不是您可能想要的10 个字节。
  • 其实放在.bss部分,用resb 10预留10个字节。您当前的版本是一个字节,初始化为{ 10 }。您不想无缘无故地在可执行文件中存储一堆零;这就是 bss 的用途。
  • Peter 是对的,你可以把它放在.bss 并使用resb 10。如果你确实想把它放在.data 中,你可以用像buffer: times 10 db 0 这样的零来分配它。或者,您可以通过为其保留内存来将缓冲区放在堆栈上。

标签: c assembly x86 nasm


【解决方案1】:

因为您要求fgets 写入.rodata 部分中的地址,所以您出现了段错误。它当然是只读的。

将缓冲区放在.bss 部分,并使用resb 10 保留10 个字节。您当前的版本是一个字节,初始化为{ 10 }。您不想无缘无故地在可执行文件中存储一堆零;这就是 bss 的用途。

section .bss
    buffer: resb 10
    buffer_length equ $ - buffer
section .text
    align 16 
    global main 
    extern fgets 
    extern stdin  
main: 
    push dword [stdin]
    push buffer_length
    push buffer           ; 3 pushes gets the stack back to 16B-alignment
    call fgets
    add esp, 12
    ret

在这个函数中你不需要pusha 或堆栈帧(带有ebp 的东西)。通常您只保存/恢复您想使用的调用保留寄存器,而不是每次都保存/恢复所有寄存器。

正如 Michael Petch 指出的那样,最好在堆栈上为缓冲区保留空间,而不是使用静态存储。查看使用本地数组的等效 C 函数的编译器输出。 (例如http://gcc.godbolt.org/)。

【讨论】:

    猜你喜欢
    • 2020-03-10
    • 1970-01-01
    • 1970-01-01
    • 2013-01-19
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    • 2016-01-15
    • 2018-02-07
    相关资源
    最近更新 更多