2

I'm currently trying to learn HLA assembler and I'm reading the Art of Assembly book. I'm stuck at the following example:


    type
     recType:
       record
          arrayField: dword[4,5];
              // Other fields
              ..
          endrecord;

    static
    aryOfRecs: recType[3,3];

    // Access aryOfRecs[i,j].arrayField[k,l]:

    intmul( 5, i, ebx ); // Computes index into aryOfRecs
    add( j, ebx ); // as (i*5 +j)*@size( recType ).
    intmul( @size( recType ), ebx );

    intmul( 3, k, eax ); // Computes index into aryOfRecs
    add( l, eax ); // as (k*3 + j) (*4 handled later).

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

So, first of all. recType is a record, having arrayField: dword [4,5] plus - some other, unspecified fields. Then - we've got aryOfRecs which is an array [3,3] of recType declared in a static section. That's ok.

Currently, the code multiplies ebx by @size( recType ) to compute the address of the inner array (arrayField[4,5]), which doesn't make any sense, imho.

So, the whole formula in the book for the address computation works like this:

BASE ADDRESS (aryOfRecs) + (k*3+l)*4 + ((i*5+j)* @size( recType )

I guess it should be:

BASE ADDRESS (aryOfRecs) + (k*3+l)*@size( recType ) + ((i*5+j)*4 instead ?

So, either - Randall Hyde has made a mistake in this example (and yes, I've checked the errata on HLA page. It says nothing about this), or I'm having a brainfart since yesterday ;>

The last line is: mov( aryOfRecs.arrayField[ ebx + eax*4 ], eax );

Basically, it sums up the OFFSET(aryOfRecs) + OFFSET(arrayField) + OFFSET(ebx) + OFFSET(eax*4)

arrayField is the first field in the recType record, so I've assumed that in this particular case - the value of the offset of arrayField (in relation to recType) would be +0. It basically - maps at the beginning of the recType. So I guess it has been included only as a general rule, to cover the cases in which the order of the fields within recType record would've been different (and arrayField wouldn't be the first field in the recType). So - I've skipped the value of OFFSET(arrayField) in the two formulas, above.

And again - OFFSET(eax*4) goes with "outer" array. Multiplying eax by the size of the dword (4) - doesn't make any sense..

So, I'd expect the code to do something like this:


    intmul( 5, i, ebx ); // Computes index into aryOfRecs arrayField
    add( j, ebx ); // as (i*5 +j)*@size( recType ) as (i*5 +j)*4 or (i*5 +j)*@size(dword)
    // *4 is handled later, in the last line with a scaled-index addressing, 
    // to save one (shl ebx by 2 or intmul ebx by 4) instruction
    intmul( @size( recType ), ebx );

    intmul( 3, k, eax ); // Computes index into aryOfRecs
    add( l, eax ); //  as (k*3 + j)(*4 handled later) 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 because @size(dword) = 4
    //addition is commutative

Am I wrong and missing something?

deathnoise
  • 21
  • 1
  • 2

0 Answers0