アセンブリ言語関連の内容を扱います。
NASM アセンブラ、つまり x86 CPU のプログラムです。

まずは覚えよう

アセンブリ言語で書かれたソースをアセンブルしたい:

  nasm -f bin source.asm -o program.bin

source.asm というソースをアセンブルし、
program.bin というファイル名で機械語のコードを出力します。

このとき得られるコードは 16 ビット用のコードで、
機械語だけを単純に出力しているプレーンなバイナリファイルです。

こうして出来上がったバイナリファイルを調べれば、
機械語のコードが読める、というわけです。
しかし、ディスアセンブラ (ndisasm) を使えば、
バイナリファイルの機械語とアセンブラコードの対応付けも
行ってくれます。

機械語のディスアセンブル:

  ndisasm program.bin

命令語を解析する

簡単な命令1つだけの解析。

アセンブルソース:

	mov ax, 0x1122

ディスアセンブル結果:

00000000  B82211            mov ax,0x1122

この B8, 22, 11 (それぞれ16進数)という3バイトのデータが
mov ax, 0x1122 という命令に対応していると考えられます。
こんな感じでアセンブリ言語の命令の機械語を調べることが可能です。

nop命令

nop命令とは、何もしない命令です。

ソース:

	nop

ディスアセンブル:

00000000  90                nop

これによると、nop命令は1バイト、0x90というコードだと推測。

ジャンプ命令の解析

jmp命令とは、命令の実行位置を指定の場所までジャンプする命令です。

ソース:

hang:
	jmp hang

hang: というのはラベルです。
これによりラベルの位置までジャンプします。
この場合だと、同じところを永遠にループします。

ディスアセンブル:

00000000  EBFE              jmp short 0x0

ジャンプ先を様々に変えてみよう:

	jmp label
	nop
	nop
	nop
	nop
label:

ディスアセンブル:

00000000  EB04              jmp short 0x6
00000002  90                nop
00000003  90                nop
00000004  90                nop
00000005  90                nop

バイトデータを直接書く

db, dw, dd などの疑似命令を使えば、
直接バイトデータを書くことが可能です。

例:

	db 0x11, 0x22
	dw 0x3344
	dd 0xaabbccdd

db は1バイト、dw は2バイト、dd は4バイトのデータです。

ラベル

ラベルはメモリの番地を参照するのに使用する名前と考えられます。
このラベルをソース中に使うこともできます:

	mov ax, label
	jmp label
label:
	nop
	nop
	nop
	nop

ディスアセンブル:

00000000  B80500            mov ax,0x5
00000003  EB00              jmp short 0x5
00000005  90                nop
00000006  90                nop
00000007  90                nop
00000008  90                nop

このようにラベルの値を使うことも可能です。

orgディレクティブ

org ディレクティブとは、ロードされるメモリの番地を指示する
指示子(ディレクティブ)です。
これを指定するとメモリ番地が変わる? のかどうか調べます。

ソースは先ほどのものと同様です:

	org 0x100

	mov ax, label
	jmp label
label:
	nop
	nop
	nop
	nop

先頭に org 0x100 が付いていること以外、
以前のものと同様です。
これをディスアセンブルしてみます:

00000000  B80501            mov ax,0x105
00000003  EB00              jmp short 0x5
00000005  90                nop
00000006  90                nop
00000007  90                nop
00000008  90                nop

"mov ax, label" の部分のラベル番地が変化しているようですが、
"jmp label" の方は変化していませんね。

プログラムを実行するには?

こちらを見たほうがいいかもしれません。