macosassemblyx86-64system-callsmach

x86_64 assembly exit system call parameter on macOS Mojave?


I have the following file:

; hello.s

.section __TEXT,__text
.globl _main
_main:
    movl $0x2000001, %eax
    movl $42, %ebx
    syscall

I try to run it as follows:

# run.sh

as -mmacosx-version-min=10.9 hello.s -o hello.o
ld -macosx_version_min 10.9 -lSystem hello.o -e _main -o hello
./hello
echo $?

The output is:

$ ./run.sh
1

I expect it to be

$ ./run.sh
42

What's wrong here?

Edit:

Based on the answer from zneak, we need to use the %edi register for syscalls, so the working program is:

; hello.s

.section __TEXT,__text
.globl _main
_main:
    movl $0x2000001, %eax
    movl $42, %edi
    syscall

Solution

  • System calls on 64-bit macOS use the System V ABI, so you need to write your first parameter to %edi instead of %ebx. Just like for normal calls, the argument registers for syscalls are rdi, rsi, rdx, rcx, r8, r9.

    Currently, you get 1 because rdi contains the argc parameter of main, and the shell invokes your program with one argument.