0
int A[R][S][T];

int A[R][S][T];
int store_ele(int i, int j, int k, int *dest) {
    *dest = A[i][j][k];
    return sizeof(A);
}

Gcc は次のアセンブリ コードを生成します。

1.  movl 8(%ebp), %ecx
2.  movl 12(%ebp), %eax
3.  leal (%eax, %eax, 8), %eax
4.  movl %ecx, %edx
5.  sall $6, %edx
6.  sub1 %ecx, %edx
7.  addl %edx, %eax
8.  addl 16(%ebp), %eax
9.  movl A(,%eax,4), %edx
10. movl 20(%ebp), %eax
11. movl %edx, (%eax)
12. movl $2772, %eax

質問 : http://i.imgur.com/szB1XnE.jpg

上記のアセンブリ コードの 9 行目とこれらの質問がわかりません。

4

1 に答える 1

1

何が起こっているのかを説明するには、コードを 1 行ずつ見ていくのが最も簡単です。

1.  movl 8(%ebp), %ecx

これにより、ebp+8 のパラメータで ecx がロードされますi

2.  movl 12(%ebp), %eax

これは eax に ebp+12 のパラメータをロードしますj

3.  leal (%eax, %eax, 8), %eax

これは eax を eax+eax*8 に設定し、基本的にそれ自体を 9 倍しますj*9

4.  movl %ecx, %edx

これにより、edx が ecx に設定されますi

5.  sall $6, %edx

そして、これは左に 6 ビットシフトし、64 を掛けるので、edx はi*64.

6.  sub1 %ecx, %edx

しかし今i、その値から ecx (つまり ) を引くと、edx は になりi*63ます。

7.  addl %edx, %eax

これにより、edx( i*63) が eax() に追加さj*9れるため、eax は になりi*63 + j*9ました。

8.  addl 16(%ebp), %eax

そして、これは ebp+16 にパラメータを追加するkので、eax は になりi*63 + j*9 + kました。

9.  movl A(,%eax,4), %edx

Aこれは、オフセット eax*4 で配列にアクセスし、edx に格納しています。

eax はi*63 + j*9 + kであるため、これは、オフセットで単一の次元の int 配列にアクセスするものと考えることができますi*63 + j*9 + k。int のサイズなので、4 を掛けます。

そのインデックス式を のように書き換えることができることに注意してくださいi*7*9 + j*9 + k。このことから、配列のさまざまな次元がどのようにアクセスされているかがわかると思います。

10. movl 20(%ebp), %eax

これは、ebp+20 のパラメータで eax をロードしますdest

11. movl %edx, (%eax)

これにより、配列から取得したばかりの edx が eax ( dest) のアドレスに格納されます。単一次元の int 配列の*dest = A[i*7*9 + j*9 + k]場合は効果的です。A

12. movl $2772, %eax

これは、 のサイズである値 2772 を返しているだけですA

のサイズがわかったので、配列を逆参照するときにをどのように乗算したAかを振り返ってみると、との値が簡単にわかると思います。ijkRST

更新: 寸法の計算

配列の次元がRSおよびの場合、 、、Tの要素にアクセスするには、どの式を使用しますか?ijk

配列を次元を持つ大きな 3 次元ブロックと考えてくださいR x S x T。インデックスはi、次元を持つブロックから 2 次元のスライスを選択しますS x Tjインデックスは長さのスライスから行を選択しますT。そして、kインデックスはkその行の th 項目です。

したがって、1 次元アドレスは次のように表すことができますi*S*T + j*T + k。上記の逆アセンブルでの配列計算を振り返ってみると、同じパターンに気付きませんか? S逆アセンブリでどの値がおよびにマップされているかがわかりますTか?

検索に関してRは、配列内の項目の数が 693 (2772 バイトのサイズを int サイズの 4 で割った値) であることがわかっています。また、アイテムの数を で計算できることも知っていますR*S*T(3 次元ブロックをもう一度考えてみてください)。したがってR*S*T = 693、 そして と を知っているSのでT、見つけることRは単なる除算の問題です。

于 2013-05-12T17:41:18.463 に答える