0

today i started to learn x86_64 Assembly with NASM on linux. I successful code a hello world program. Now i want to code another simple program. The program should ask the user for his name and then print "hi [name]". My problem is that the program doesn't ask for a name. If i start the program it doesn't print anything and stops without an error. Here is my Code:

section .data
    msg1 db "Type in ur Name? ", 10
    len1 equ $ - msg1       ; Get the Size of msg1

    msg2 db "Hi, "
    len2 equ $ - msg2       ;Get the Size of msg2

section .bss
    name resb 16            ;16 Bytes for name

section .text
    global _start

_start:

    ;Call Functions
    call _printMsg1
    call _getName
    call _printMsg2
    call _printName

    mov eax, 60
    mov ebx, 0
    int 0x80


_printMsg1:
    mov eax, 1
    mov ebx, 1
    mov ecx, msg1
    mov edx, len1
    int 0x80
    ret


_printMsg2:
    mov eax, 1
    mov ebx, 1
    mov ecx, msg2
    mov edx, len2
    int 0x80
    ret


_printName:
    mov eax, 1
    mov ebx, 1
    mov ecx, name
    mov edx, 16     ; reserve 16 Bytes for the name
    int 0x80
    ret


_getName:
    mov eax, 0      ;Syscall 0 = User Input
    mov ebx, 0
    mov ecx, name
    mov edx, 16     ;16 Bytes for the name
    int 0x80
    ret

Thanks for your help!

EDIT: I found the problem. The program works if i replace the following registers with: eax to rax ebx to rdi ecx to rsi edx to rdx

Seems like i use the false registers.

NewInFireFox
  • 37
  • 1
  • 3
  • According to http://asm.sourceforge.net/intro/hello.html it should be `mov eax, 4` to call the `write` system call. – Barmar May 31 '18 at 18:48
  • Hi and thanks for your answer! i added my solution. i just change the registers. i use the syscall table from here : https://filippo.io/linux-syscall-table/ – NewInFireFox May 31 '18 at 18:59
  • 1
    Are you sure you are programming in 64 bit mode? You might run into [this problem](https://stackoverflow.com/q/46087730/417501). – fuz May 31 '18 at 19:50
  • Using RDI, RSI, and RDX will completely not work if you're still [invoking the 32-bit `int 0x80` ABI](https://stackoverflow.com/questions/46087730/what-happens-if-you-use-the-32-bit-int-0x80-linux-abi-in-64-bit-code) instead of `syscall`. You're using 64-bit call numbers but absolutely everything else is 32-bit. – Peter Cordes Jan 25 '21 at 06:00

2 Answers2

2

x86-32 and x86-64 system calls are very different in numbers, registers and syscall instruction.

A x86-32 system call uses int 80h and this numbers and registers: http://www.lxhp.in-berlin.de/lhpsysc0.html

A x86-64 system call uses syscall and this numbers and registers: http://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/

You're using x86-32 system calls, so change the numbers in EAX accordingly.

rkhb
  • 14,159
  • 7
  • 32
  • 60
1

QUICK FIX
You were confused about the 32 bits and 64 bits registers and the syscalls numbers
I just changed the wrong registers values for the 32 bits architecture

section .data
    msg1 db "Type in ur Name? ", 10
    len1 equ $ - msg1       ; Get the Size of msg1

    msg2 db "Hi, "
    len2 equ $ - msg2       ;Get the Size of msg2

section .bss
    name resb 16            ;16 Bytes for name

section .text
    global _start

_start:

    ;Call Functions
    call _printMsg1
    call _getName
    call _printMsg2
    call _printName

    mov eax, 1
    mov ebx, 0
    int 0x80


_printMsg1:
    mov eax, 4
    mov ebx, 1
    mov ecx, msg1
    mov edx, len1
    int 0x80
    ret


_printMsg2:
    mov eax, 4
    mov ebx, 1
    mov ecx, msg2
    mov edx, len2
    int 0x80
    ret


_printName:
    mov eax, 4
    mov ebx, 1
    mov ecx, name
    mov edx, 16     ; reserve 16 Bytes for the name
    int 0x80
    ret


_getName:
    mov eax, 3      ;Syscall 3 = Read from stdin
    mov ebx, 0  
    mov ecx, name
    mov edx, 16     ;16 Bytes for the name
    int 0x80
    ret

Compiled with nasm and ld for 32 bits

nasm -f elf32 test.asm -o test.o
ld -m elf_i386 test.o -o test
  • 1
    Your `_getName` is buggy. It reads from stderr (fd = ebx=2). That usually happens to work because normally fds 0, 1 and 2 all refer to the same read-write open file description for the terminal, but it would break if the user redirected or closed stderr but not stdin. – Peter Cordes Jan 25 '21 at 06:03
  • Common Pete be pitty isn't my function! What should be the correct value of ebx in _getName function? – another character escaped Jan 25 '21 at 06:13
  • 1
    What are you complaining at me for? You were the one that broke that part of the OP's code which correctly used STDIN_FD (`0`) for the first arg to the read system call. Did you not know that you should be reading input from stdin, or not know the file-descriptor number for stdin? I assume you knew that EBX was the fd arg for `read(int fd, void *buf, size_t len)`. And BTW, if you're going to post answers like this, it would be useful to add some value to the code by commenting it with comments like `; read(0, name, 16)`. – Peter Cordes Jan 25 '21 at 06:21
  • 1
    You still haven't actually edited your answer to fix that. But I wanted to make another point: leaving problems un-corrected in code from the question is a Bad Thing. Code in questions should be assumed to be broken by future readers of Stack Overflow. But code in answers is supposed to work. By copying code into your answer, you're endorsing it as a good example worth following. That's why my answers to "code doesn't work" questions usually fix unrelated problems and even improve thing to do something a better way. (Like using RIP-relative addressing, or putting constants in .rodata) – Peter Cordes Jan 25 '21 at 07:16
  • 1
    TL:DR: bugs in the question are not valid justification for bugs in an answer. That defeats the purpose of what Stack Overflow is about: high quality answers. Read from stderr is not always 100% wrong so it doesn't as clearly fall in this category. e.g. I think I've seen some real-world programs like maybe `less` do that as an alternative to opening `/dev/tty` if their stdin isn't connected to a terminal. (Like `foo | less`). But if you're not doing terminal-specific stuff, it's still not good to be reading from an FD other than stdin. But it's not something to do without a big comment. – Peter Cordes Jan 25 '21 at 07:20
  • Everything you told me is revised, tested and edited now. Sorry, I tried to fix it as fast as I could. I had no slept since years. Thank you again, I made a mistake about the file-descriptor value. I'll be sure of check what I'm going to post the next time if I'm gonna be away for a time. I learned a lot in this site before I login. I want to return the favor but...I can't stop learning :) – another character escaped Jan 26 '21 at 05:55