I have looked at similar questions, but cannot seem to find what is wrong with my code.
I am attempting to make the "write" syscall on MacOS to print a string to standard output.
I am able to do it with printf
perfectly, and am familiar with calling other functions in x64 assembly.
This is, however, my first attempt at a syscall
.
I am using GCC's GAS assembler.
This is my code:
.section __TEXT,__text
.globl _main
_main:
pushq %rbp
movq %rsp, %rbp
subq $32, %rsp
movq $0x20000004, %rax
movq $1, %rdi
leaq syscall_str(%rip), %rsi
movq $25, %rdx
syscall
jc error
xorq %rax, %rax
leave
ret
error:
movq $1, %rax
leave
ret
.section __DATA,__data
syscall_str:
.asciz "Printed with a syscall.\n"
There does not seem to be any error; there is simply nothing written to stdout
.
I know that start
is usually used as the starting point for an executable on MacOS, but it does not compile with GCC.
You are using the incorrect SYSCALL number for MacOS. The base for the user system calls is 0x2000000. You are incorrectly using that base. As a result you have encoded the write
SYSCALL as $0x20000004
when it should have been $0x2000004
(one less zero)
As a rule of thumb, make sure you are using the correct value for the SYSCALL number in the %rax
register; ensure you are using the correct arguments for the write
SYSCALL. The write
SYSCALL expects the following arguments:
%rdi
: file descriptor to write to (e.g. 1 for standard output)%rsi
: pointer to the buffer containing the data to be written%rdx
: number of bytes to be writtensyscall
instruction to invoke a system call.