0

I have to do a very simple task in assembly: read input from the user (name) and then output this input.

The way I have to do it - to use function gets(). I know that this function should never be used but teacher specified the task to do it using only gets function.

The problem I face - whenever I call this function and enter my input it gives me Segmentation fault. I make buffer size equal to 24 bytes just for example.

It doesn't matter how much memory I give this function on stack - always the same mistake. One interesting thing: if I leaq -(k*24)(%rsp), %rsp and then mov %rsp, %rdi and then calling gets will allow me to enter as many inputs as I want and never stop. It happens with only number 24 and any k you want.

Why could it happen?

Thank you.

Function 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: Sorry for not mentioning earlier: I have main written in C, it just simply calls the function:

     #include <stdlib.h>
     void name(void);
     void main()
     {
         name();
         return;
     }

UPDATE2: I'm using Linux 64bit and GCC 4.8.4 (quite old, I know)

UPDATE3: Using gcc -o exec main.c name.s to link.

beervoley
  • 11
  • 1
  • 5
  • [why-is-the-gets-function-so-dangerous-that-it-should-not-be-used](http://stackoverflow.com/questions/1694036/why-is-the-gets-function-so-dangerous-that-it-should-not-be-used). **edit**....so, change your teacher/school – LPs Oct 17 '16 at 06:11
  • 1
    @LPs If I had enough money I would do it half a year ago:) – beervoley Oct 17 '16 at 06:15
  • You sure the code crashes during the `gets`? Because it most definitely crashes when you attempt to `ret` to the wrong address (everything you pushed must be popped before you return!). – fuz Oct 17 '16 at 09:26
  • `leaq -24(%rsp),%rsp` is also equivalent to `sub rsp,24`, which I find easier to read (also it sort of hints what to do to restore the `rsp` before `ret`). – Ped7g Oct 17 '16 at 10:29
  • 1
    @LPs at least their using Linux 64bit, which really surprises me. A lot of students at these high priced institutions are being taught assembly using DOS 1.0 – Shift_Left Oct 17 '16 at 11:40
  • What OS and C compiler are you using? Getting the calling convention right here is critical to getting this to work. – doron Oct 17 '16 at 12:12

2 Answers2

0

The changes I've made have already been pointed out to you, but as you've got 90% of it, thought I'd fix it up for you. There probably will be comments about ENTER, but the point is, we're making something work, not worry about optimization.

Your version wouldn't link either, as GCC is going to expect main as the entry point, unless you passed -e name to the linker.

.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
Shift_Left
  • 1,208
  • 8
  • 17
0

Should you not save rsp into rbp before increasing the stack size? Also should you not clean up rsp and rbp before leaving tge function?

doron
  • 27,972
  • 12
  • 65
  • 103