📝

Intel Syntax(NASM) ことはじめ

に公開

NASM

NASM(Netwide Assembler)は、x86-64アーキテクチャ向けのアセンブラ。
https://azelpg.gitlab.io/azsky2/note/prog/asm64/index.html

x86-64は、AMD64やIntel 64、x64などと呼ばれることもあります。同一の命令セットにこのように複数の名前がついているのには歴史的背景があります。
https://www.sigbus.info/compilerbook#アセンブラとは

環境

MacOSの場合nasmの動作確認をすることは極めて難しいので、EC2インスタンスにVSCodeの拡張機能でssh接続するのが一番簡単だと思われます。無料枠があるので、ちょっと使う分にはお金はかかりません。

必要なパッケージのインストール

yum install git -y
yum install nasm gcc gdb

サンプルコードを動かしてみる

以下は何もせず終了ステータス42で終了するサンプルコードです。

exit.s
global _start
section .text

_start:
    mov rax, 60
    mov rdi, 42
    syscall

ここで、mov rax, 60は、raxレジスタに60を入れるという意味になります。ここで60という数値はexitのシステムコール番号になります。同様にmov rdi, 42rdiレジスタに42を入れるという意味です。rdiは主に第一引数の値を格納される場所として使用されます。そしてsyscallで引数に42が渡った状態でexitが実行されます。引数を渡すのではなく、レジスタにおいておくという感じなので慣れるまで頭がこんがります。

このサンプルコードはCコードにするとこうなります。シンプルですね。

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

終わりに

他にも便利なサイトがあるのでまずはこちらから使用してみると いいかも。便利🍙
https://app.x64.halb.it/
https://onecompiler.com/assembly/3z9qxqj69

opcodeのランキング。movが3割近く占めていたり面白い
https://yaya.lsv.jp/x64_opcode_ranking/

Discussion