未だに意味不明なアドレッシングモード

x86のアドレッシングモードは、なかなかに豊富なわけだが、
これが、初心者にとっては、なかなかに難解なわけである。
例えば、

MOV     AX, [EBX+ECX]

は、OKだけど、

MOV     AX, [BX+CX]

は、NGとかね。
でも、

MOV     AX, [BX+SI]

は、OKだったり...


これをきちんと理解するのは、なかなかに、大変な事だと思う。
でも、諦めちゃうと、いつまで経っても分からないままなので、
少し、自分なりに、努力してみましょうと。


で、まず、

MOV     AL, [BX]

アセンブル結果を眺めてみる。

8A 07

8Aをインテルのオペコードマップで調べると、MOV Gb,Eb となる。
Gb,Ebは、後続のModR/Mを、reg(バイト),R/M(バイト)と解釈すると。
07が、そのModR/Mで、二進数に変換すると、00000111となるので、
mod=00, reg=000 -> AL, R/M=111 -> [BX] となる。
ふむふむ。


次に、

MOV     AL, [BX+SI]

アセンブル結果は、

8A 00

ほとんど、さっきと同じだけど、ModR/Mの内容が変わっている。
mod=00, reg=000 -> AL, R/M=000 -> [BX+SI] となる。
ふ〜む。


なんか、ちょっとだけ、見えてきたよ。
昔ながらの16ビットアドレス指定形式では、
[AX]だとか[CX]だとかは使えないのね。
はい、使えるのは、以下のパターンね。
[BX+SI],[BX+DI],[BP+SI],[BP+DI],[SI],[DI],[BP],[BX]
そうそう、昔は、レジスタそれぞれに役割があったっけ!!
ベース系のレジスタとインデックス系のレジスタしか使えないと。


なるほどなるほど。
変にインテルの資料を斜め読みとかして、
SIBバイトの存在を中途半端に知ってしまった故に混乱したわけだ。
SIBバイトは、x86が32bit化された際に追加された要素なんで、
基本、32bit形式でしか利用出来ないわけですね!!
よって、[EAX+ECX*4+0x1234]なんて出来ても、[AX+CX*4+0x1234]は出来ないと。


落ち着いて、整理して考えれば、少しずつでも理解が進むというわけですね。
それにしても... x86って、無茶苦茶だねぇ〜。(^^;