この記事にはアセンブリ言語の命令の概要とmov命令の説明が書いてあります。
1.4 アセンブリ言語を少し詳しくみる
前回の続きです。
ここまでで出てきたアセンブリ言語プログラムを少し詳しく見ていきます。
以下のコマンド
ndisasm -b 32 casm-c-sample.bin
で機械語ファイルcasm-c-sample.binを逆アセンブルし、そのアセンブリ言語プログラムを出力すると以下のようになります。
00000000 55 push ebp
00000001 89E5 mov ebp,esp
00000003 83EC10 sub esp,byte +0x10
00000006 C745FC00000000 mov dword [ebp-0x4],0x0
0000000D FF45FC inc dword [ebp-0x4]
00000010 C9 leave
00000011 C3 ret
アセンブリ言語プログラムだけ書き出すと
push ebp
mov ebp,esp
sub esp,byte +0x10
mov dword [ebp-0x4],0x0
inc dword [ebp-0x4]
leave
ret
こうなります。これをリスト1.4とします。
上からの3行
push ebp
mov ebp,esp
sub esp,byte +0x10
は関数入り口での定型的処理命令です。
下からの2行
leave
ret
も関数出口での定型処理命令です。
ここでは4,5行目の
mov dword [ebp-0x4],0x0
inc dword [ebp-0x4]
についてみていきます。
アセンブリ言語命令の概要
ここで、アセンブリ言語のプログラムの概要について見ていきましょう。
アセンブリ言語の命令は1行に1命令です。1命令の文法は以下のようになります。
オペコード オペランド1、オペランド2
リスト1.4の4行目
mov dword [ebp-0x4],0x0
では movがオペコード、dword [ebp-0x4],と0x0の二つがオペランドです。
オペコードとオペランドを組み合わせたものをニーモニックと呼びます。
mov命令
mov命令はデータの移動をします。どこからどこへ移動するかをオペコードで指定します。
以下のような形式です。
mov 移動先、移動元
移動元のデータを移動先へ移動します。ただ、移動といっても移動元のデータはそのままですので、実態はコピーなのですが、movという名前になっています。
mov ebp,esp
リスト1.4の2行目
mov ebp,esp
でもmov命令が使われています。
espにあるデータをebpに移動しているということですね。
ところでオペランドのespとかebpとは何でしょうか?
espとかebpはレジスタと言われる記憶領域です。これらはCPUに内蔵されています。任意の32ビットの値を記憶できます。
espはスタックポインタと呼ばれます。常にスタックの最新の読み書き位置を保持しています。
スタックについては後日改めて解説していきますが、ここではC言語でのローカル変数を置くための記憶領域くらいに認識しておいてください。
スタックは広い記憶領域です。その中の1か所を指すものがスタックポインタです。
mov dword [ebp-0x4],0x0
mov dword [ebp-0x4],0x0
mov ebp,esp と比べると複雑になっていますが、mov命令の基本通りコピー元が0x0でコピー先がdword [ebp-0x4]です。
先ほどはレジスタespにあるデータをレジスタebpに移動したのでした。
今回は0x0にあるデータということでなく、0x0はただの値です。0のことです(16進数の表現になっています)。
値0をdword [ebp-0x4]という場所にコピーしています。
コピー元に普通の数字を書くと、コピー元の場所でなく、ただの数値を表します。この数値は即値とかリテラルといいます。
コピー先のdword [ebp-0x4]という場所は何のことでしょうか?
複雑な形をしているので分解して説明していきます。
・ ebp-0x4: コピー先のメモリ番地(を計算する部分)
・ []: メモリ番地ですよと明示している
・ dword : 領域の大きさを指定する部分
今出てきたメモリ番地について若干の説明です。メモリとはデータを記憶できる大きな領域です。
メモリ番地とはメモリを細かく区切ってそれにつけた連番のことです。
先ほどはesp,ebpなど、レジスタにデータを記憶しましたが、メモリにもデータを書き込んだり、読み込んだりできます。
ではコピー先のdword [ebp-0x4]の話に戻ります。
mov dword [ebp-0x4],0x0
は 即値0x0をメモリ番地[ebp-0x4]にコピーするという話でした。
dwordはそのメモリ番地のサイズを指定しています。dwordを指定するとそのメモリ番地のサイズは32ビットということになります。
そうすると
mov dword [ebp-0x4],0x0
は 「即値0x0をメモリ番地[ebp-0x4]へコピー。そのメモリ番地のサイズは32ビット」
という命令であることがわかりました。
ここまでmov命令の使い方を見てきました。
この記事は以上です。