a[1][1]を線形アドレスに変換するのはあなた次第です。つまり、a[1][1]
の先頭からどれだけ離れているかを把握する必要がありa
ます。まず、行のサイズ(この場合は2 int)を計算します。したがって、(今のところintで作業している)行0の先頭はaからのオフセット0にあり、行1はオフセット2にあり、(さらに行があった場合)というように続きます。次に、その行内のオフセットを追加します。最後に、1つのアイテムのサイズでスケーリングします。
そこから、いくつかの可能性があります。1つは、固定位置が必要なことですa[1][1]
。何があっても、取得します。もう1つは、私たちが実際に調べていることです。現時点a[i][j]
ではi
、j
たまたま1ですが、他のサイズである可能性もあります。
最初に、アセンブラがアドレスを計算するためにいくつかの計算を実行できるという事実を使用できます。
// one row down times 2 ints per row + offset of 1 into last row, all times size of int
movl a + (1 * 2 + 1)*4, eax
i
2番目のケースでは、inesi
とj
inがあると仮定しebx
ます。この場合、私たちは自分で計算を行う必要があります(申し訳ありませんが、今のところIntel構文を使用します-私はそれに慣れています):
shl esi, 1 ; i * 2
add esi, ebx ; i * 2 + j
shl esi, 2 ;(i * 2 + j) * 4
mov eax, a[esi]
x86は、アドレス指定に一般的なこのようないくつかの操作を実際に組み合わせることができるため、上記のように個別の命令として実行する必要がないため、次のように簡単に減らすことができます。
shl esi, 1
mov eax, a[esi][ebx]
最後に少し説明が必要かもしれません-少なくともMASM(そしておそらくガスでは)では、アセンブラは、値をロードしているeax
ので、4バイトの量で作業していることを知っています。オフセットを自動的に4でスケーリングします。