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.

4
  • According to asm.sourceforge.net/intro/hello.html it should be mov eax, 4 to call the write system call. Commented May 31, 2018 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 : filippo.io/linux-syscall-table Commented May 31, 2018 at 18:59
  • 1
    Are you sure you are programming in 64 bit mode? You might run into this problem. Commented May 31, 2018 at 19:50
  • Using RDI, RSI, and RDX will completely not work if you're still invoking the 32-bit int 0x80 ABI instead of syscall. You're using 64-bit call numbers but absolutely everything else is 32-bit. Commented Jan 25, 2021 at 6:00

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

Comments

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 

6 Comments

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.
Common Pete be pitty isn't my function! What should be the correct value of ebx in _getName function?
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).
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)
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.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.