2

編集:これはAT&T構文を使用しています

私はGASアセンブラを使用してアセンブリを学習しており、配列内のint値を比較し、その比較に基づいて値を変更するプログラムを作成する必要があります。私はCでインラインアセンブリを使用してそれを書いています。基本変数、たとえばint iの場合、次の行でレジスタeaxに値を格納することを知っています。

movl i, %eax

しかし、変数a [2] [2]があり、a [1] [1]を%eaxに移動したいとします。明らかに間違った答えは次のとおりです。

movl a[1][1], %eax

式の後にエラージャンク'[1][1]'が表示されます。2次元配列の値をレジスタに移動するにはどうすればよいですか?ありがとう!

4

2 に答える 2

3

a[1][1]を線形アドレスに変換するのはあなた次第です。つまり、a[1][1]の先頭からどれだけ離れているかを把握する必要がありaます。まず、行のサイズ(この場合は2 int)を計算します。したがって、(今のところintで作業している)行0の先頭はaからのオフセット0にあり、行1はオフセット2にあり、(さらに行があった場合)というように続きます。次に、その行内のオフセットを追加します。最後に、1つのアイテムのサイズでスケーリングします。

そこから、いくつかの可能性があります。1つは、固定位置が必要なことですa[1][1]。何があっても、取得します。もう1つは、私たちが実際に調べていることです。現時点a[i][j]ではijたまたま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

i2番目のケースでは、inesijinがあると仮定し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でスケーリングします。

于 2012-04-12T04:48:53.337 に答える
2

AT&Tの構文について100%確信が持てないので、混乱した場合に備えて、Intelソリューションと変換したAT&Tを投稿します。

基本的に、配列の値を最初に検索してから、場合によってはスワップする必要があります。

Intel構文

mov ecx, a  ;move the pointer to the 2D array into a register first
mov ecx, [ecx + 04h] ;walk to the a[1] dimension (4h happens to be the size of a pointer on my system)
mov eax, [ecx + 04h] ;eax now holds the value of a[1][1] and ecx still holds the memory location of a[1]
;do stuff with the eax register
mov DWORD PTR SS: [ecx + 4h], 1h ;change the value of a[1][1]

AT&T構文

   movl a, %ecx
   movl 4%(ecx),%ecx
   movl 4%(ecx),%eax
   ; do stuff with eax
   movl $1,4%(ecx)

編集:線形アドレスを計算できるように固定サイズの配列がある場合は、Jerryのソリューションの方がおそらく優れていますが、これは動的に割り当てられた2D配列でも機能します。

于 2012-04-12T04:55:38.907 に答える