[fpc-pascal]Default calling convention

Peter Vreman peter at freepascal.org
Fri Jul 2 19:47:51 CEST 2004

> Peter Vreman a écrit :
>> Check what Delphi does for nested procedures. If it is different from
>> FPC
>> then FPC will be adapted.
> Overall, no :-) Delphi (at least the version 5.01) is bugged.
> For instance, with
>   function Add: Longword;
>     var x : Longword;
>     function DoAdd(a: Longword): Longword; register;
>       var y : Longword;
>     asm
>       mov  y, 1
>       add  eax, x
>       add  eax, y

This is unsupported, Accessing variables not in the current stackframe
need additional assembler instructions. That is the reason why FPC gives
an error for this:

p.pp(7,17) Error: You can not reach X from that code

Don't forget that you should be familair with the code generated by the
compiler when programming assembler functions. If you don't know, then
keep away from programming assembler.

>     end;
>   begin
>     x := 7;
>     Result := DoAdd(1);
>   end;
> The result should be 9 (1+7+1) but for Delphi it is only 3.
> "DoAdd" is coded this way
>   mov [ebp-$04], $00000001  // mov y, 1
>   add eax, [ebp-$4]         // add eax, x
>   add eax, [ebp-$4]         // add eax, y
> i.e., for Delphi 5.01, x and y are the same thing!
> I think the best thing that could be done would be to manage so that
> FPC always makes use of [ebp-something] to access a parameter when

This is your opinion for 'best', other ppl like the register calling more.

> the programmer makes use of the parameter name, i,e., with any calling
> convention the instruction "mov eax,param" should never be coded as
> "mov eax,reg" but always as "mov eax,[ebp-something]".

That is already supported:

Solution 1:
add a begin...end around the assembler block. The parameters will then
first be loaded to the local stackframe and the assembler uses [ebp-xx].
IIRC delphi works the same.

Solution 2:
Changing the calling convention from register to stdcall.

More information about the fpc-pascal mailing list