0
votes

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.

2
According to asm.sourceforge.net/intro/hello.html it should be mov eax, 4 to call the write system call. - Barmar
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 - NewInFireFox
Are you sure you are programming in 64 bit mode? You might run into this problem. - fuz
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. - Peter Cordes

2 Answers

2
votes

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.

1
votes

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