ModR/M
読み:モード-アーエム
外語:ModR/M

 x86の機械語コード中にあり、二つのソースの種類を表わすために使われるバイト。
目次

概要
 x86では、二つのオペランドがあるレジスターを扱う命令は、このバイトをパラメーターとしてオペコードの直後に置く。
 そして必要なら、更にSIBバイト、変位(オフセット)、即値(イミディエイト)が続く。
 このModR/Mバイトの存在により、「reg, reg」「reg, [reg]」「reg, [reg + disp]」など複雑なx86のオペランドを柔軟に指定することを可能としている。

特徴

構造
 片方はレジスターに固定、もう片方はレジスターまたはメモリーが選択可能で、またレジスターを使う場合はオフセットを追加することができる。
76543210
modregr/m
 modは、次のようにr/mの用途を切り替える。
 mod=11のみ実効アドレスではなくレジスターを指定し、それ以外はレジスターとレジスターまたはディスプレースメントにより実効アドレスを指定し、そのアドレスのデータを参照する機能になる。

レジスター
 レジスターは3ビットで表現されるため、都合8本のレジスターが存在することになる。
 レジスター長は、元々の8086では16ビットだったものの、i386以降32ビット化にともない伸びた。但し、ModR/Mの構造変更は現実的に不可能であったため、レジスターの本数は増えなかった。
 レジスター数の拡張が図られたのは64ビットされてからで、REXプリフィックスを用いて不足する1ビットを補い、結果として倍の16本のレジスターを扱えるようになった。

一覧表

変化
 アドレッシングの基本的な設計は、CPUが16ビット、32ビット、64ビットと進化しても、大きくは変わっていない。
 いかにもCISC的な複雑なアドレッシングが特徴であり、高速化の足枷になると思われるが、それでも互換性などの維持が根底にあるためか、機能の削除などは今日まで行なわれていない。
 それどころか、32ビット以降のプロテクトモードでは、16ビット時代では出来なかった殆ど全てのレジスターを使ったレジスター間接のアドレッシングに対応し、またインデックスレジスターの倍率の指定なども可能になるなど、利便性が大幅に向上した。
 結果として、16ビットのリアルモードと、32ビット以降のプロテクトモードでは解釈方法が大きく違っており、また64ビット化した際にもRIP相対アドレッシングなどの追加が行なわれた。

16ビット
 16ビット、つまり元々の設計では、次のようなアドレッシングになる。
 mod
r/m00011011
000[BX + SI][BX + SI + disp8][BX + SI + disp16]AL/AX
001[BX + DI][BX + DI + disp8][BX + DI + disp16]CL/CX
010[BP + SI][BP + SI + disp8][BP + SI + disp16]DL/DX
011[BP + DI][BP + DI + disp8][BP + DI + disp16]BL/BX
100[SI][SI + disp8][SI + disp16]AH/SP
101[DI][DI + disp8][DI + disp16]CH/BP
110[disp16][BP + disp8][BP + disp16]DH/SI
111[BX][BX + disp8][BX + disp16]BH/DI

32ビット
 i386のプロテクトモードでは、次のようなアドレッシングになる。
 ほぼ全てのレジスターを使ったレジスター間接アドレッシングに対応するため、16ビットにあったようなアドレッシングについてはSIBバイトを使って表現するようになった。
 レジスター単独の場合、汎用レジスターの他に、MMXレジスター、XMMレジスターが指定できるが、ここでは略している。
 mod
r/m00011011
000[EAX][EAX + disp8][EAX + disp32]AL/AX/EAX
001[ECX][ECX + disp8][ECX + disp32]CL/CX/ECX
010[EDX][EDX + disp8][EDX + disp32]DL/DX/EDX
011[EBX][EBX + disp8][EBX + disp32]BL/BX/EBX
100[<SIB>][<SIB> + disp8][<SIB> + disp32]AH/SP/ESP
101[disp32][EBP + disp8][EBP + disp32]CH/BP/EBP
110[ESI][ESI + disp8][ESI + disp32]DH/SI/ESI
111[EDI][EDI + disp8][EDI + disp32]BH/DI/EDI

64ビット
 ロングモード(64ビット)は32ビットとほぼ同様だが、RIP相対アドレッシングが追加されている。
 64ビットでは、レジスター数が倍となり表現に4ビットを要するため、regフィールドおよびr/mフィールドの各4ビット目はREXプリフィックスのREX.r、REX.bで表現する。
 レジスター単独の場合、汎用レジスターの他に、MMXレジスター、XMMレジスターが指定できるが、ここでは略している。
 単なる[disp32]は出来なくなった。[disp]からレジスターへのロードはオペコードA1、その逆はA3にあるため、実用上の問題はない。
 mod
rex.br/m00011011
0000[RAX][RAX + disp8][RAX + disp32]AL/RAX
001[RCX][RCX + disp8][RCX + disp32]CL/RCX
010[RDX][RDX + disp8][RDX + disp32]DL/RDX
011[RBX][RBX + disp8][RBX + disp32]BL/RBX
100[<SIB>][<SIB> + disp8][<SIB> + disp32]AH/RSP
101[RIP + disp32][RBP + disp8][RBP+ disp32]CH/RBP
110[RSI][RSI + disp8][RSI + disp32]DH/RSI
111[RDI][RDI + disp8][RDI + disp32]BH/RDI
1000[R8][R8 + disp8][R8 + disp32]R8
001[R9][R9 + disp8][R9+ disp32]R9
010[R10][R10 + disp8][R10 + disp32]R10
011[R11][R11 + disp8][R11 + disp32]R11
100[<SIB>][<SIB> + disp8][<SIB> + disp32]R12
101[RIP + disp32][R13 + disp8][R13+ disp32]R13
110[R14][R14 + disp8][R14 + disp32]R14
111[R15][R15 + disp8][R15 + disp32]R15

再検索