Well, you've seen the formulas for computing the address of a multidimensional array element. Now it's time to see how to access elements of those arrays using assembly language.
The mov
, shl
, and intmul
instructions make short work of the various equations that compute offsets into multidimensional arrays. Let's consider a two-dimensional array first.
static i: int32; j: int32; TwoD: int32[ 4, 8 ]; . . . // To perform the operation TwoD[i,j] := 5; you'd use code like the following. // Note that the array index computation is (i*8 + j)*4. mov( i, ebx ); shl( 3, ebx ); // Multiply by 8 (shl by 3 is a multiply by 8). add( j, ebx ); mov( 5, TwoD[ ebx*4 ] );
Note that this code does not require the use of a two-register addressing mode on the 80x86. Although an addressing mode like TwoD[ebx][esi]
looks like it should be a natural for accessing two-dimensional arrays, that isn't the purpose of this addressing mode.
Now consider a second example that uses a three-dimensional array:
static i: int32; j: int32; k: int32; ThreeD: int32[ 3, 4, 5 ]; . . . // To perform the operation ThreeD[i,j,k] := esi; you'd use the following code // that computes ((i*4 + j)*5 + k )*4 as the address of ThreeD[i,j,k]. mov( i, ebx ); shl( 2, ebx ); // Four elements per column. add( j, ebx ); intmul( 5, ebx ); // Five elements per row. add( k, ebx ); mov( esi, ThreeD[ ebx*4 ] );
Note that this code uses the intmul
instruction to multiply the value in EBX by 5. Remember, the shl
instruction can only multiply a register by a power of 2. While there are ways to multiply the value in a register by a constant other than a power of 2, the intmul
instruction is more convenient.[64]