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;