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.
CodePudding user response:
You are using the incorrect SYSCALL number for MacOS. The base for the user system calls is 0x2000000. You are incorrectly using 0x2000000. 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 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 written- On macOS, you need to use the
syscall
instruction to invoke a system call.