アセンブリで Hello World を出力するのにハマりまくって大変でした・・。
プログラムはこんな感じ。こちらの記事で紹介されていたコードをコピペさせていただきました🙇
section .data
msg db 'Hello, world!', 0x0a
len equ $ - msg
section .text
global _main ; '_main'を外部参照可能に
_main:
; SYSCALL: write(1, msg, len);
mov rax, 0x2000004 ; MacOSにおけるwrite関数の番号
mov rdi, 1 ; write()の第1引数。標準出力へ
mov rsi, msg ; write()第2引数
mov rdx, len ; write()第3引数
syscall
; SYSCALL: exit(0)
mov rax, 0x2000001 ; exit関数の番号
mov rdi, 0 ; 正常終了
syscall
次に実行ファイルを生成します。生成にはNASMを使用しました。
brew install nasm
コマンドはこんな感じ
nasm -f macho64 hello.asm
-f
でフォーマットを指定します。64bitのmacOSの場合はmacho64
です。
これでhello.o
が生成されました。
アセンブリではこの実行ファイルをそのまま実行できるわけではなく、リンクという手順を挟む必要があります。リンクにはld
コマンドを使用します。(デフォルトで入っているはず)
ld hello.o -o hello -lSystem -L/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib
ここが最大のハマりポイントでした。大抵の記事では
ld hello.o -o hello -lSystem
と記載されているのですが、それだとライブラリが見つからないと怒られます。
ld: library not found for -lSystem
というのも、上記コマンドだと/usr/lib/libSystem.dylib
を使用してリンクを行うようなのですが、macOSBig Sur
以降ではそのファイルがなくなるらしいのです。その場合は使用するライブラリを-L/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib
で指定する必要があります。
これでhello
が生成されたはずです。あとは実行して、Hello world!
が出力されればOKです。
./hello
Hello, world!
libSystem.dylib
を復活させるためにOSの再インストールまでするなど、かなり遠回りしてしまいました。やっとアセンブリのコード内部の学習に入れます。
環境
Mac book Air
1.2 GHz Quad-Core Intel Core i7
参考URL
assemblyでHelloWorld! (Mac)
Missing librairies in /usr/lib on Big Sur?
nasmの公式ドキュメント
nasm - Can't link object file with ld on macOS Mojave