3.1 Using assembler in the sources

There are essentially 2 ways to embed assembly code in the pascal source. The first one is the simplest, by using an asm block:

Var  
  I : Integer;  
begin  
  I:=3;  
  asm  
   movl I,%eax  
  end;  
end;

Everything between the asm and end block is inserted as assembler in the generated code. Depending on the assembler reader mode, the compiler performs substitution of certain names with their addresses.

The second way is implementing a complete procedure or function in assembler. This is done by adding a assembler modifier to the function or procedure header:

function geteipasebx : pointer;assembler;  
asm  
  movl (%esp),%ebx  
  ret  
end;

It’s still possible to declare variables in an assembler procedure:

procedure Move(const source;var dest;count:SizeInt);assembler;  
var  
  saveesi,saveedi : longint;  
asm  
  movl %edi,saveedi  
end;

The compiler will reserve space on the stack for these variables, it inserts some commands for this.

Note that the assembler name of an assembler function will still be ’mangled’ by the compiler, i.e. the label for this function will not be the name of the function as declared. To change this, an Alias modifier can be used:

function geteipasebx : pointer;assembler;[alias:'FPC_GETEIPINEBX'];  
asm  
  movl (%esp),%ebx  
  ret  
end;

To make the function available in assembler code outside the current unit, the Public modifier can be added:

function geteipasebx : pointer;assembler;[public,alias:'FPC_GETEIPINEBX'];  
asm  
  movl (%esp),%ebx  
  ret  
end;