next up previous contents
Next: Telling the compiler what Up: Using assembly language Previous: AT&T Syntax

Calling mechanism

  Procedures and Functions are called with their parameters on the stack. Contrary to Turbo Pascal, all parameters are pushed on the stack, and they are pushed right to left, instead of left to right for Turbo Pascal. This is especially important if you have some assembly subroutines in Turbo Pascal which you would like to translate to Free Pascal.

Function results are returned in the first register, if they fit in the register. For more information on this, see section (8.2)

The registers are not saved when calling a function or procedure. If you want to call a procedure or function from assembly language, you must save any registers you wish to preserve.

The first thing a procedure does is saving the base pointer, and setting the base (%ebp) pointer equal to the stack pointer (%esp). References to the pushed parameters and local variables are constructed using the base pointer.

In practice this amounts to the following assembly code as the procedure or function header :

   pushl   %ebp
   movl    %esp,%ebp

When the procedure or function exits, it clears the stack by means of the RET xx call, where xx is the total size of the pushed parameters on the stack. Thus, in case parameters with a total size of xx have been passed to a function, the generated exit sequence looks as follows:

  leave
  ret  $xx

When you want your code to be called by a C library or used in a C program, you will run into trouble because of this calling mechanism. In C, the calling procedure is expected to clear the stack, not the called procedure. To avoid this problem, Free Pascal supports the export modifier. Procedures that are defined using the export modifier, use a C-compatible calling mechanism. This means that they can be called from a C program or library, or that you can use them as a callback function.

This also means that you cannot call this procedure or function from your own program, since your program uses the Pascal calling convention. However, in the exported function, you can of course call other Pascal routines.

Technically, the C calling mechanism is implemented by generating the following exit sequence at the end of your function or procedure:

  leave         {Copies EBP to ESP, pops EBP from the stack.}
  ret
Comparing this exit sequence with the previous one makes it clear why you cannot call this procedure from within Pascal: The arguments still are on the stack when the procedure exits.

As of version 0.9.8, the Free Pascal compiler supports also the cdecl and stdcall modifiers, as found in Delphi. The cdecl modifier does the same as the export modifier, and stdcall does nothing, since Free Pascal pushes the paramaters from right to left by default.

All this is summarized in table (3.1). The first column lists the modifier you specify for a procedure declaration. The second one lists the order the paramaters are pushed on the stack. The third column specifies who is responsible for cleaning the stack: the caller or the called function. Finally, the last column specifies if registers are used to pass parameters to the function.

  

Modifier Pushing order Stack cleaned by Parameters in registers
(none) Right-to-left Function No
cdecl Right-to-left Caller No
export Right-to-left Caller No
stdcall Right-to-left Function No
Table 3.1: Calling mechanisms in Free Pascal

More about this can be found in chapter (4) on linking.


next up previous contents
Next: Telling the compiler what Up: Using assembly language Previous: AT&T Syntax

Michael Van Canneyt
Tue Mar 31 16:50:06 CEST 1998