2012-11-11 22 views
5

私はx86/x64 CPU命令用のコンパイラを作成しています。私は人々が 'ディスプレースメント'アドレスの意味を理解できないようです。たとえば、Add命令の詳細は次のとおりです。 http://www.c-jump.com/CIS77/CPU/x86/X77_0150_encoding_add_edx_displacement.htmx86/x64ディスプレースメントアドレッシングを追加

通常のメモリアドレスにレジスタが追加された場合にadd命令を実装しようとしています。問題は、アドレスが「変位アドレス」であることです。これは、アドレスが命令位置からのオフセットである符号付きの値であることを意味しますか?

+3

アセンブリコードを生成していますか? Cコードを生成できないのですか、またはLLVMを使用できませんか?または、マシンコードをhttp://code.google.com/p/asmjit/または他のライブラリで公開しますか?あなたはx86/64命令セットをよく理解していますか?あなたはhttp://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html –

答えて

9

間接的なオペランドのいくつかの異なる形式は、x86にあります

  1. [REG]
  2. [REG +変位]
  3. [変位]
  4. [REG *定数+のREG ]
  5. [reg *定数+ reg +変位]

"ディスプレースメント"は残りのアドレスに追加される単なる定数です。アドレス以外に定数以外の成分がない場合、それは依然として「変位」と呼ばれます。これは、主に他のアドレッシングフォームとの整合性のためです。

それを見て別の方法は、すべてのアドレスの形式であることである

[REG *定数+のREG +変位] 0

の値を可能にするコンポーネントのそれぞれに

[ディスプレースメント]フォームは、ディスプレースメント以外のすべてのコンポーネントがゼロであるエンコーディングにすぎません。

コンパイラライターとして、最後の2つの形式は特に興味深いものです。彼らはpArray[index]->field + 1のようなものを1つの命令でエンコードすることを容易にします。

+0

[reg * constant + reg + displacement]はどのようにマシン命令にエンコードされますか?メモリ位置0x00000001に配列があり、そのインデックスにALにアクセスしたいとします。移動命令を使用してMOV AH 0x00000001 [AL]を実行したいと思います。私はそれがちょうど[reg +変位]だと思う。このページのセクション6は、R/Mバイトのエンコードを示していますが、実際には混乱しています。http://www.c-jump.com/CIS77/CPU/x86/lecture.html –

+0

インテルマニュアルの第2巻をご覧ください。各命令はその符号化形式を指定する。 r/mオペランドをリストする符号化形式は、mod/rmバイトのレジスタオペランドまたはメモリオペランドを受け入れます。 –

+0

インテルマニュアルのボリューム2を見てください。各命令はその符号化形式を指定する。 r/mオペランドをリストする符号化形式は、mod/rmバイトのレジスタオペランドまたはメモリオペランドを受け入れます。第2巻、第2.1章の第2章には、mod r/mバイトの意味を示す表があります。 [ - ] [ - ]が記載されているフォームは、SIBバイトを使用するエンコーディングを示します。 SIBアドレッシングはreg * constant + regの形式です。 mod/rmバイトのいくつかの形式は、SIBバイトの後にディスプレースメントが続くことを示します。それらはreg *定数+ reg +定数形式を与える。 SIBについても説明する表があります。 –

3

「置換を行う特別な追加」はありません。そのページは不必要に混乱しています。これは、通常のメモリオペランドエンコーディングの一部です。

addは、すべてのALU-OPSであると同様に符号化されるかなり標準命令である:先としてax/eax/raxを使用して、ソース(04 ib)として先としてalを使用して、即時のための特別な場合があるのと(+ 05 imm)、add r/m, immの3つのバージョン(8ビット宛先の1つ、より広い宛先と8ビットソースの拡張、1つはより広い宛先、広いソース用)、そしてもちろんadd r, r/madd r/m, rの3つのバージョンがあります。

これはちょうどadd r, r/mの特殊なケースです。r/mは、ディスプレースメントの形式を取っています。ModRM encodingの注#1を参照してください。

したがって、それらは単にadd edx, [sdword]を意味します。 (ただし、regフィールドを正しくエンコードしていないと、edx010ではなく011ではありません)

+0

を学習しました。つまり、AL(8ビットレジスタ0)をメモリ位置0x00000000に追加するには、 CPUは(00)00 00000000を(16進で)受け入れますか? –

+0

@RyanBrownはい、それは役に立ちます – harold

4

このページは正確ではありません。あなたが逆アセンブラの出力でそれを見るかもしれないので、それが話す "変位を加える"は、add r[16|32], r/m[16|32]またはadd edx, [0xdisp]という形式を指しています。仮定すると、それは

  • edxレジスタ宛先を符号化及びそれに0x15の値を与えるにModR/Mバイトの実効アドレスと32ビットのディスプレースメントを指定し、オペコード0x03とADD命令について話(インテルを参照®64およびIA-32アーキテクチャーソフトウェア開発者マニュアル第2巻、41ページ、表2-2)。
  • この命令の効果は、メモリアドレスdispのdwordをedxの内容に追加することです。
  • 命令の実際のエンコーディングは、1バイトのディスプレースメントのために\x03\x15\x00\x00\x00\x01です。
関連する問題