函数gets()汇编

时间:2016-10-17 06:09:25

标签: assembly x86-64 glibc

我必须在汇编中执行一个非常简单的任务:从用户(名称)读取输入,然后输出此输入。

我必须这样做 - 使用函数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 64bitGCC 4.8.4(相当陈旧,我知道)

更新3:使用gcc -o exec main.c name.s进行链接。

2 个答案:

答案 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吗?