機械語の解読

8086の機械語を読んでみます。

私にも、「アセンブリ命令と16進のオペコードは、1対1で対応している。アセンブリコード→機械語の翻訳って、手間だけの問題じゃん!」と思っていた時期がありました。でも、逆アセンブルの結果を見ると、同じmov命令なのに、どうも16進数のコードが異なっている(あるあるネタ)。あ、mov+レジスタの組み合わせで、ユニークにコードが割り当てられているんだ!と一瞬思いましたが、それもまた違うらしい。

で、朝からIntelデベロッパーズマニュアル(pdf)を読み込んでいたのですが…

インテル® 64 および IA-32 アーキテクチャー・ソフトウェア・デベロッパーズ・マニュアル
http://www.intel.co.jp/content/www/jp/ja/processors/architectures-software-developer-manuals.html

じつはオペコードというのは、mov+レジスタバイト単位/ワード単位/ダブルワード単位、レジスタ間転送/メモリ→レジスタ転送/レジスタ→メモリ転送/即値→レジスタ転送/即値→メモリ転送、アドレッシングモード指定…によって、オペコードが変わってくるのですね。そういう条件によってオペコードが変わってくると非常にストレスなので、条件を制限した上で、IA-32機械語フォーマットを解析してみたいと思います。

基本データ型のサイズ

基本データ型 ビットサイズ バイトサイズ
バイト 8ビット 1バイト
ワード 16ビット 2バイト
ダブルワード 32ビット 4バイト
クワッドワード 64ビット 8バイト
ダブル・クワッドワード 128ビット 16バイト

各基本データ型に対するサイズは、CPUのレジスタ長など設計によって決まってくるので、普遍的ではありません。日常生活で目にする単位、例えば1cm=10mmとか、1分=60秒などは普遍的ですが、計算機においては単位が設計依存という話は本当に多いです。

命令リファレンスの表記について

Intelの命令リファレンスを眺めていると、「imm、r/m、rb、rw、rd」という表記を目にします。これは何を意味するかと言うと…

記号 意味
imm 即値
r/m レジスタ or メモリ

それぞれ、データ型によって、末尾にサイズが付与されます。例えば、バイト型の即値は「imm8」、ワード型の即値は「imm16」、ダブルワード型の即値はimm32、となります。r/mについても同様です。

他にもいろいろありますが、今回は、必要最低限のものだけをあげてみました。