Why is 64 bit nasm insisting on the rsi register ? (why can't I put "hello world" into rcx register?)
I have this x86 assembly code for a "hello world" program.
global _start section .text _start: mov eax, 1 ; system call for write mov ebx, 1 ; file handle 1 is stdout mov ecx, message ; address of string to output mov edx, message_len ; length of the string syscall ; invoke operating system to do the write mov eax, 60 ; system call for exit mov ebx, 0 ; exit code 0 syscall ; invoke operating system to ex section .data message: db "Hello, World!!!!", 10 ; newline at the end message_len equ $-message ; length of the string
This don't compile with nasm -felf64 hello.asm && ld hello.o && ./a.out
on a 64 bit Linux machine.
But if I change the third line:
mov ecx, message
to mov rsi, message
it works!
My question is why is 64-bit nasm insisting on the rsi
register?
Because I have seen people compiling with ecx
on 32-bit Arch Linux.
Solution 1:
x86 does not use the same calling convention as x64. In x86 the first argument is ebx which contains the descriptor, ecx contains the buffer, edx contains the length and eax contains the system call ordinal.
In x64, the first argument is contained in RDI, second in RSI, third in RDX and fourth in RCX while RAX contains the ordinal for the system call.
That's why your call is working on X86 but needs to be adjusted to work on X64 as well.