macOS Mojave + nasm の Hello world

nasm の Hello world 記事はそこそこあるもののコピペで動かなかったのでメモ。

TL;DR

  • エントリポイントは start ではなくて _main という名前にしておく
  • ld コマンドに -lSystem-macosx_version_min 10.13 を指定しておく

前提

  • macOS Mojave 10.14.1
  • uname -m -> x86_64

書いたやつ

github.com

GLOBAL _main

SECTION .text

_main:
  mov rax, 0x2000004;
  mov rdi, 1;
  mov rsi, hello_world;
  mov rdx, 13;
  syscall;
  mov rax, 0x2000001;
  mov rdi, 0;
  syscall;


SECTION .data;
  hello_world db "Hello World", 0x0a;
hello.out: hello.o
    ld -lSystem -o hello.out -macosx_version_min 10.13 hello.o
hello.o: hello.asm
    nasm -f macho64 -o hello.o hello.asm

インターネット上にいろいろ落ちてるサンプルとの変更点は1つだけ。GLOBAL でアクセス可能にしているシンボル名が start になっているのが多かったのだが、_main にした。 これは ld コマンド実行時にシンボルが見つからないんだが?と怒られたので変更。たぶん macOS 側の仕様が変わった?のかな?

Undefined symbols for architecture x86_64:
  "_main", referenced from:
     implicit entry/start for main executable
ld: symbol(s) not found for inferred architecture x86_64

また make コマンドにも -lSystem-macosx_version_min 10.13 を追加。これもわからなくてググったのだが以下のSOにたどり着いた。そしたらこいっちでも「 start から _main に変えてみたがまだだめなんだが」とのこと。start って名前はどこから来てるんですかねえ。

https://stackoverflow.com/questions/52830484/nasm-cant-link-object-file-with-ld-on-macos-mojave

$ ./hello.out
Hello World