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-tableNewInFireFox
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