Author Topic: syscalls - MacOS  (Read 9010 times)

Offline fredericopissarra

  • Full Member
  • **
  • Posts: 373
  • Country: br
syscalls - MacOS
« on: January 27, 2023, 11:06:16 AM »
Just an info for you all...

MacOS is derived from FreeBSD and its syscalls follows the SysV ABI for i386 with extensions and a minor difference for x86-64: Instead of changing RCX by R10, MacOS uses RCX... and, again, yep... i386 table is used in x86-64 mode, so sys_exit is 1 and sys_write is 4.

I don't have a MacOS machine to test this, by this 'hello.asm' should work on MacOS in x86-64 mode:
Code: [Select]
  bits 64
  default rel   ; program need to be PIE.

  section .rodata

msg:     db `Hello\n`
msg_len  equ $ - msg

  section .text

  global _start

  align 4
_start:
  mov  eax,4      ; sys_write (must be 1 on Linux)
  mov  edi,1      ; stdout
  lea  rsi,[msg]
  mov  edx,msg_len
  syscall

  mov  eax,1      ; sys_exit (must be 60 on Linux)
  xor  edi,edi
  syscall
For i386 mode int 0x80 is used the same way as in Linux...

Reading some material I found that maybe the sections could be renamed to __text and __rodata. But I don't know where to find the official MacOS Reference to confirm.
« Last Edit: January 27, 2023, 11:13:25 AM by fredericopissarra »

Offline tysonprogrammer

  • Jr. Member
  • *
  • Posts: 22
  • Country: us
  • C# application developer attempting assembly.
Re: syscalls - MacOS
« Reply #1 on: April 16, 2023, 07:57:31 PM »
I played around with this and it does work with some modifications. I then compiled it but it seems with MacOS, at least Ventura, using the XCode command line tools is that you have to link against System, which makes the routing executable much larger. I can't say for sure that a more complex program will not have issues. Like with Linux you have to store away EDX, EDI and ESI in main then restore them before returning the the OS when linking to glibc.

Anyway I was nice to finally be able to compile assembly on my Mac.

Code: [Select]
; hello.s - print out hello to the console from x86 assembly on MacOS Ventura
; buid: nasm -f macho64 hello.s
; link: ld -lto_library /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/libLTO.dylib -dynamic -arch x86_64 -platform_version macos 13.0.0 13.3 -syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -o hello -L/usr/local/lib hello.o -lSystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/14.0.0/lib/darwin/libclang_rt.osx.a

bits 64
  default rel   ; program need to be PIE.

  section .rodata

msg:     db "Hello",10
msg_len  equ $-msg

section .text

global _main

align 4
_main:
  mov  eax, 0x02000004      ; sys_write (must be 1 on Linux)
  mov  edi, 1      ; stdout
  lea  rsi, [msg]
  mov  edx, msg_len
  syscall

mov  eax, 0x02000001      ; sys_exit (must be 60 on Linux)
  xor  edi, edi
  syscall

If anyone knows how to do it without linking against System I would like to know how using clang.

Offline fredericopissarra

  • Full Member
  • **
  • Posts: 373
  • Country: br
Re: syscalls - MacOS
« Reply #2 on: April 21, 2023, 10:49:27 PM »
Instead of _main you should use _start, don't you? OR tell the linker _main is the entry point with -e option.