Intel Syntax(NASM) ことはじめ
NASM
NASM(Netwide Assembler)は、x86-64アーキテクチャ向けのアセンブラ。
x86-64は、AMD64やIntel 64、x64などと呼ばれることもあります。同一の命令セットにこのように複数の名前がついているのには歴史的背景があります。
https://www.sigbus.info/compilerbook#アセンブラとは
環境
MacOSの場合nasmの動作確認をすることは極めて難しいので、EC2インスタンスにVSCodeの拡張機能でssh接続するのが一番簡単だと思われます。無料枠があるので、ちょっと使う分にはお金はかかりません。
- AWS EC2(Amazon Linux 2)
- VSCode Remote-SSH
必要なパッケージのインストール
yum install git -y
yum install nasm gcc gdb
サンプルコードを動かしてみる
以下は何もせず終了ステータス42で終了するサンプルコードです。
global _start
section .text
_start:
mov rax, 60
mov rdi, 42
syscall
ここで、mov rax, 60は、raxレジスタに60を入れるという意味になります。ここで60という数値はexitのシステムコール番号になります。同様にmov rdi, 42はrdiレジスタに42を入れるという意味です。rdiは主に第一引数の値を格納される場所として使用されます。そしてsyscallで引数に42が渡った状態でexitが実行されます。引数を渡すのではなく、レジスタにおいておくという感じなので慣れるまで頭がこんがります。
このサンプルコードはCコードにするとこうなります。シンプルですね。
int main() {
return 42;
}
実行方法
上のアセンブリコードをexit.sという名前で保存し、ターミナルからC言語と同じようにコンパイル、リンク、実行します。ここでエラーメッセージが出ずに42で終了されていれば大丈夫です!$?は終了ステータスを表します。
$ nasm -f elf64 exit.s -o exit.o
$ ld exit.o -o exit
$ ./exit
$ echo $? // 42
gdbを使ってみる
学習コストが高いので後で紹介するサイトなどでデバッグをするといいかも。
コンパイル時にデバッグオプション-gを追加する必要があります。
$ nasm -f elf64 -g exit.s -o exit.o
$ ld exit.o -o exit
$ gdb --tui ./exit // guiモードで起動
(gdb) break _start
(gdb) run
(gdb) info regisgters
rax 0x0 0
rbx 0x0 0
...
(gdb) quit
終わりに
他にも便利なサイトがあるのでまずはこちらから使用してみると いいかも。便利🍙
opcodeのランキング。movが3割近く占めていたり面白い
Discussion