【发布时间】: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这样的零来分配它。或者,您可以通过为其保留内存来将缓冲区放在堆栈上。