2

私は現在 HLA アセンブラーを学ぼうとしていて、Art of Assembly の本を読んでいます。私は次の例で立ち往生しています:

    タイプ
     録音タイプ:
       記録
          arrayField: dword[4,5];
              // その他のフィールド
              ..
          エンドレコード;

    静的
    aryOfRecs: recType[3,3];

    // aryOfRecs[i,j].arrayField[k,l] にアクセス:

    intmul( 5, i, ebx ); // インデックスを aryOfRecs に計算します
    add(j, ebx); // (i*5 +j)*@size( recType ) として。
    intmul( @size( recType ), ebx );

    intmul( 3, k, eax ); // インデックスを aryOfRecs に計算します
    add( l, eax ); // (k*3 + j) として (*4 は後で処理)。

    mov( aryOfRecs.arrayField[ ebx + eax*4 ], eax );

ということで、まずは。recType はレコードであり、arrayField: dword [4,5] とその他の未指定フィールドがあります。次に、静的セクションで宣言された recType の配列 [3,3] である aryOfRecs を取得します。それで大丈夫です。

現在、コードは ebx を @size( recType ) で乗算して、内部配列 (arrayField[4,5]) のアドレスを計算しますが、これは意味がありません。

したがって、アドレス計算の本にある式全体は次のように機能します。

ベースアドレス (aryOfRecs) + (k*3+l) *4 + ((i*5+j)* @size( recType )

私はそれがすべきだと思います:

BASE ADDRESS (aryOfRecs) + (k*3+l) *@size( recType ) + ((i*5+j) *4代わりに ?

つまり、Randall Hyde がこの例で間違いを犯したか (そうです、HLA ページの正誤表を確認しましたが、これについては何も書かれていません)、昨日から頭がおかしくなっているのです ;>

最後の行は次のとおりです。mov( aryOfRecs.arrayField[ ebx + eax*4 ], eax );

基本的に、OFFSET(aryOfRecs) + OFFSET(arrayField) + OFFSET(ebx) + OFFSET(eax*4) を合計します。

arrayField は recType レコードの最初のフィールドであるため、この特定のケースでは、(recType に対する) arrayField のオフセットの値は +0 になると想定しました。基本的に - recType の先頭にマップします。したがって、recType レコード内のフィールドの順序が異なる場合 (および arrayField が recType の最初のフィールドではない場合) をカバーするために、一般的な規則としてのみ含まれていると思います。そのため、上記の 2 つの数式で OFFSET(arrayField) の値をスキップしました。

繰り返しますが、OFFSET(eax*4) は「外側」の配列になります。eax に dword のサイズを掛けること (4) - 意味がありません..

したがって、コードは次のようになると思います。

    intmul( 5, i, ebx ); // インデックスを計算してaryOfRecs配列フィールド
    add(j, ebx); ///as (i*5 +j)*@size( recType )(i*5 +j)*4 または (i*5 +j)*@size(dword) として
    // *4 は後で処理され、スケーリングされたインデックスのアドレス指定を含む最後の行で、
    // 1 つの (shl ebx by 2 または intmul ebx by 4) 命令を保存する
    intmul( @size( recType ), ebx );

    intmul( 3, k, eax ); // インデックスを aryOfRecs に計算します
    add( l, eax ); ///  as (k*3 + j)(*4は後述)as (k*3 + l)*@size(recType)
    intmul( @size( recType ), eax );

    mov( aryOfRecs.arrayField[ ebx + eax*4 ], eax );
    mov( aryOfRecs.arrayField[ ebx*4 + eax], eax ); //ebx*4 なので @size(dword) = 4
    //加算は交換可能です

私は間違っていて、何かが欠けていますか?

4

0 に答える 0