我必须在汇编中执行一个非常简单的任务:从用户(名称)读取输入,然后输出此输入。
我必须这样做 - 使用函数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
写的,它只是简单地调用函数:
#include <stdlib.h>
void name(void);
void main()
{
name();
return;
}
更新2:我使用的是Linux 64bit
和GCC 4.8.4
(相当陈旧,我知道)
更新3:使用gcc -o exec main.c name.s
进行链接。
答案 0 :(得分:0)
我已经向您指出了我所做出的更改,但是当您已经获得了90%的更改时,我认为我已经为您解决了这些问题。可能会有关于ENTER
的评论,但关键是,我们正在制作一些有用的工作,而不用担心优化。
您的版本也不会链接,因为GCC会期望main
作为入口点,除非您将-e name
传递给链接器。
.string1:
.string "Please enter your name: "
.string2:
.string "Hello, %s\n"
.globl main
main:
enter $80, $0
movl $.string1, %edi
call printf
movq %rsp, %rdi
call gets
movl $.string2, %edi
mov %rax, %rsi
call printf
leave
xorl %eax, %eax
ret
答案 1 :(得分:0)
在增加堆栈大小之前,是否应该将rsp保存到rbp中?你还应该在离开tge函数之前清理rsp和rbp吗?