Iteration

Whereas in Pascal goto statements are strongly discouraged because they lead to code that is difficult to maintain, in assembler you often construct your own loops and need to write code to jump to labels.

Programs ASMLoop1 and ASMLoop1A are the equivalent of the following Pascal code:

Total: = 0;
Count := 10;
repeat
  Total := Total + Count;
  Count := Count - 1;
until Count = 0; 

program ASMLoop1;
  {$APPTYPE CONSOLE}
  {$ASMMODE INTEL}  //Delete this line in Delphi
uses
  SysUtils;
var
  Total : integer;
begin
  asm
    MOV ECX, 10 // Sets Count to 10.
    MOV EAX, 0  // Initialises accumulator to 0.
    @Start:
      ADD EAX, ECX // Adds Count to accumulator
     // Decrement ECX and go back to @Start if ECX <> 0.
     Loop @Start
     //  Variable Total takes its final value from the accumulator.
     MOV Total, EAX 
  end;
  writeln('Total: ', Total);
  readln;
end.

program ASMLoop1A;
  {$mode objfpc}{$H+}
  {$ASMMODE ATT}  
uses
  SysUtils;
var
  Total : integer;
begin
  asm
    MOV $0xA, %ECX  // Sets Count to 10.
    MOV $0x0, %EAX  // Initialises accumulator to 0.
    .LStart:
      ADD %ECX, %EAX  // Adds Count to accumulator
      //Decrement ECX and go back to .LStart if ECX <> 0.
    Loop .Lstart
    //Variable Total takes its final value from the accumulator.
    MOV %EAX, Total  
  end;
  writeln('Total: ', Total);
  readln;
end.

There is no need to use a loop instruction. The following program replaces the Loop @Start instruction with three instructions:

DEC ECX
CMP ECX, 0  //Compare the contents of ECX with 0
JNZ @Start  //Jump if Not Zero (if ECX <> 0)  

(The compare instruction is actually a subtraction which results in 0 if the operands are equal).

program ASMLoop2;
  {$APPTYPE CONSOLE}
  {$ASMMODE INTEL}  //Delete this line in Delphi
uses
  SysUtils;
var
  Total : integer;
begin
  asm
    MOV ECX, 10 //Set Count to 10.
    MOV EAX, 0 //Initialise accumulator to 0.
    @Start:
      ADD EAX, ECX // Add Count to accumulator
      DEC ECX // Decrement ECX
      CMP ECX, 0 //Compare contents of ECX with 0
    JNZ @Start //Go back to @Start label if ECX <> 0.
    MOV Total, EAX //Variable Total takes its final value from EAX
  end;
  writeln('Total: ', Total);
  readln;
end.

program ASMLoop2A;
  {$mode objfpc}{$H+}
  {$ASMMODE ATT}  
uses
  SysUtils;
var
  Total : integer;
begin
  asm
    MOV $0, %ECX  //Set Count to 10.
    MOV $0, %EAX //Initialise accumulator to 0.
    .LStart:
       ADD %ECX, %EAX  // Add Count to accumulator
       DEC %ECX
       CMP $0, %ECX
       //Go back to @Start if ECX <> 0.
    JNZ .Lstart
    //Variable Total takes its final value from the accumulator.
    MOV %EAX, Total  
  end;
  writeln('Total: ', Total);
  readln;
end.  

If you do not use a loop you are free to use an incrementing (instead of decrementing) counter if you prefer.

Programming - a skill for life!

Getting started with in-line assembler