I'm wondering why I have to use the syscall numbers from /usr/include/asm/unistd_32.h
, not unistd_64.h
, even though I'm using the 64 Bit Registers and assembling and linking with (I think) the appropriate commands:
$ yasm -f elf64 hellow.asm
$ ld -m elf_x86_64 -o hey hellow.o
The file hellow.asm is (I'm aware I'm using the numbers 4 for write and 1 for exit as in the 32.h, because using the ones from 64.h doesn't work. Write is 1 there, and exit 60, and I tried those with no result.)
section .data
msg db "hey you beauty", 0xe
len equ $ - msg ; length of string
section .text
global _start ; for linker
_start: ;linker entry point
mov rdx,len ;message length
mov rcx,msg ;msg to write
mov rbx,1 ;file descriptor (stdout)
mov rax,4 ;system call number (write)
int 0x80 ; call kernel
mov rax,1 ; system call (exit)
int 0x80 ; call kernel
file
on the executable and the object file gives back:
object file: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
executable: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped
My /usr/include/unistd.h
is:
#ifndef _ASM_X86_UNISTD_H
#define _ASM_X86_UNISTD_H
/* x32 syscall flag bit */
#define __X32_SYSCALL_BIT 0x40000000
# ifdef __i386__
# include <asm/unistd_32.h>
# elif defined(__ILP32__)
# include <asm/unistd_x32.h>
# else
# include <asm/unistd_64.h>
# endif
#endif /* _ASM_X86_UNISTD_H */
If you've made it this far through this post, you've earned to know why my "hello world" program says "hey you beauty" instead: I like it when my computer talks to me like a dirty old man in a bar.