【发布时间】:2017-02-26 00:45:29
【问题描述】:
我必须在汇编中做一个非常简单的任务:从用户(名称)读取输入,然后输出这个输入。
我必须这样做 - 使用函数gets()。我知道永远不应该使用这个函数,但是老师指定任务只使用gets函数来完成。
我面临的问题 - 每当我调用此函数并输入我的输入时,它都会给我分段错误。例如,我将缓冲区大小设置为 24 字节。
我在堆栈上给这个函数多少内存并不重要——总是同样的错误。一件有趣的事情:如果我leaq -(k*24)(%rsp), %rsp 然后mov %rsp, %rdi 然后调用gets 将允许我输入任意数量的输入并且永不停止。只有数字 24 和您想要的任何 k 才会发生这种情况。
为什么会这样?
谢谢。
函数name
.string1:
.string "Please enter your name: "
.string2:
.string "Hello, %s"
.globl name
name:
push %rbx
push %rbp #calee saved regs
leaq -24(%rsp),%rsp # name_str[24]
mov %rsp, %rbp #save rsp
movq $.string1, %rdi
xorl %eax,%eax
call printf
movq %rsp, %rdi
call gets
movq $.string2, %rdi
mov %rax, %rsi
xorl %eax, %eax
call printf
ret
UPDATE1:抱歉之前没有提到:我在C写了main,它只是简单地调用了函数:
#include <stdlib.h>
void name(void);
void main()
{
name();
return;
}
UPDATE2:我正在使用Linux 64bit 和GCC 4.8.4(我知道很老了)
UPDATE3:使用gcc -o exec main.c name.s 链接。
【问题讨论】:
-
why-is-the-gets-function-so-dangerous-that-it-should-not-be-used。 编辑....所以,改变你的老师/学校
-
@LPs 如果我有足够的钱,我会在半年前这样做:)
-
您确定代码在
gets期间崩溃了吗?因为当您尝试ret到错误的地址时,它肯定会崩溃(您推送的所有内容都必须在返回之前弹出!)。 -
leaq -24(%rsp),%rsp也等同于sub rsp,24,我觉得它更易于阅读(它也暗示了如何在ret之前恢复rsp)。 -
@LPs 至少他们使用 Linux 64 位,这真的让我感到惊讶。这些高价机构的许多学生正在使用 DOS 1.0 学习汇编