nasm write system call not working for 64 bit version how to resolve?

Issue

I have written simple hello_world program in nasm.

segment .text               ; code section
    global _start           ; must be declared for linker

    _start:                 ; tell linker entry point
        mov edx, len        ; message len (DX is for data register)
        mov ecx, msg        ; message to write (CX is for count register)
        mov ebx, 1          ; (stdout) file descriptor
        mov eax, 1          ; system call number for write system call
        int 0x80            ; call kernel

        mov eax, 1          ; system call number for exit system call
        int 0x80            ; call kernel

section .data
    msg db "Hello, World", 0xa
    len equ $ - msg

so when i am compiling this program with elf64 flag
$nasm -f elf64 hello_world.nasm

and then linking with ld
$ld hello_world.o

finally when i ran a.out it not write anything to stdout.

when i opened file unistd_64.h to show which system call is calling for no 1.

// /usr/include/asm/unistd_64.h

#ifndef _ASM_X86_UNISTD_64_H
#define _ASM_X86_UNISTD_64_H 1

#define __NR_read 0
#define __NR_write 1
#define __NR_open 2
#define __NR_close 3
#define __NR_stat 4

As you can see for write system call number is 1. this program will work if i put 4 instead of 1 but 4 is specified in unistd_32.h and i also compiled with elf64 flag so why it is not working for 64 bit?

for your reference unistd_32.h

#ifndef _ASM_X86_UNISTD_32_H
#define _ASM_X86_UNISTD_32_H 1

#define __NR_restart_syscall 0
#define __NR_exit 1
#define __NR_fork 2
#define __NR_read 3
#define __NR_write 4

Solution

You are making a mistake in which you need to use the sysv-64-abi which states that functions parameters to be passed to rdi, rsi, rdx, rcx. In addition exit syscall number is decimal 60 not 1. also you mistyped section .text. Any you need to use syscall and not old slower int soft interrupt instruction to trap into kernel.

section .text               ; code section
    global _start           ; must be declared for linker

    _start:                 ; tell linker entry point
        mov rdx, len        ; message len (DX is for data register)
        mov rsi, msg        ; message to write (CX is for count register)
        mov rdi, 1          ; (stdout) file descriptor
        mov rax, 1          ; system call number for write system call
        syscall            ; call kernel

        mov rax, 60          ; system call number for exit system call
        syscall            ; call kernel

section .data
    msg db "Hello, World", 0xa
    len equ $ - msg

Answered By – KMG

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published