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
syscallinstruction to invoke a system call.
