Indexed Addressing

The following code to demonstrate indexed addressing populates an array. (LEA stands for Load Effective Address where an effective address is an address within a memory segment rather than an absolute address).

program ASM_IndexedDirect;
  {$APPTYPE CONSOLE}
  {$ASMMODE INTEL}//Delete this line in Delphi
uses
  SysUtils;
var
  ByteArray:  array[0..5] of byte;
  Count : integer;
begin
  asm
    MOV DL, 50 //Data to be stored in ByteArray[5];
    MOV ECX, 5 //ECX used as index
    @start:
      MOV [ECX + ByteArray], DL //Contents of DL moves into indexed address
      SUB DL, 10 
    loop @Start //Loop if ECX is not 0
  end;
  for Count := 0 to 5 do
    begin
      writeln('ByteArray[', Count,'] = ', ByteArray[Count]);
    end;
  readln;
end.


program ASM_IndexedDirectA;
  {$mode objfpc}{$H+}
  {$ASMMODE ATT}
uses
  SysUtils;
var
  ByteArray:  array[0..5] of byte;
  Count : integer;
begin
  asm
    MOV $0x32, %DL //Data to be stored in ByteArray[5];
    MOV $0x5, %ECX //ECX used as index
    .LStart:
      MOV %DL, ByteArray(%ECX) //Contents of DL moves into indexed address
      SUB $0xA, %DL
    loop .LStart //Loop if ECX is not 0
  end;
  for Count := 0 to 5 do
    begin
      writeln('ByteArray[', Count,'] = ', ByteArray[Count]);
    end;
  readln;
end.
Arrays of multiple bytes such as arrays of integer are very common. To locate the appropriate address the count needs to be multiplied by the number of bytes per data type. Conveniently, this is allowed within the brackets of the operand. In the next program, the count value is multiplied by the scale factor 4, the number of bytes per integer.
program ASM_ScaledIndex;
  {$APPTYPE CONSOLE}
  {$ASMMODE INTEL}
uses
  SysUtils;
var
  IntArray: array[0..5] of Integer;
  Count : integer;
begin
  asm
    MOV EDX, 50; //Data to go in IntArray[5];
    MOV ECX, 5; //ECX used as index
    @start:
      MOV [ECX * 4 + IntArray], EDX; //Indexed addressing with scaling
      SUB EDX,10;
    loop @Start
  end;
  for Count := 0 to 5 do
    begin
      writeln('IntArray[',Count,'] = ', IntArray[Count]);
    end;
  readln;
end.

program ASM_ScaledIndexedA;
  {$mode objfpc}{$H+}
  {$ASMMODE ATT}
uses
  SysUtils;
var
  IntArray: array[0..5] of Integer;
  Count : integer;
begin
  asm
    MOV $0x32, %EDX //Data to be stored in IntArray[5];
    MOV $0x5, %ECX //ECX used as index
    .LStart:
      MOV %EDX, IntArray (,%ECX,4)  //Indexed addressing with scaling
      SUB $0xA, %EDX
    loop .LStart //Loop if ECX is not 0
  end;
  for Count := 0 to 5 do
    begin
      writeln('IntArray[', Count,'] = ', IntArray[Count]);
    end;
  readln;
end.  
Programming - a skill for life!

Registers, addressing modes and flags