Lazarus

Programming => General => Topic started by: paule32 on April 14, 2025, 05:37:25 pm

Title: FPC 3.2.2 - Assembler call Assembler Routine - with nostackframe - how to ?
Post by: paule32 on April 14, 2025, 05:37:25 pm
The given assembler function:

Code: Pascal  [Select][+][-]
  1. function foo(var s: buf): longint; assembler; nostackframe;
  2. asm
  3.  

how can I call a external "bar" function with the "buf" parameter to a similar:
function, to "not" lose or overwrite the stack ?

Code: Pascal  [Select][+][-]
  1. function bar(var s: buf): longint; assembler; nostackframe;
  2. asm
  3.  
Title: Re: FPC 3.2.2 - Assembler call Assembler Routine - with nostackframe - how to ?
Post by: Thaddy on April 14, 2025, 06:31:31 pm
How would you handle the stack allocation for s then? Manually?
Title: Re: FPC 3.2.2 - Assembler call Assembler Routine - with nostackframe - how to ?
Post by: ALLIGATOR on April 14, 2025, 07:01:57 pm
Unfinished example for Windows x64.
Maybe someone will complete and further develop the example

Code: Pascal  [Select][+][-]
  1. program app;
  2. {$asmmode intel}
  3.  
  4. type
  5.   buf = array [0..9] of dword;
  6.  
  7. function bar(var s: buf): longint; assembler; nostackframe;
  8. asm
  9.   mov dword ptr [rcx], 33
  10. end;
  11.  
  12. function foo(var s: buf): longint; assembler; nostackframe;
  13. asm
  14.   sub rsp, 8
  15.   mov [rsp], rcx
  16.  
  17.   // ...
  18.   mov rcx, [rsp]
  19.   call bar
  20.   // ...
  21.  
  22.   add rsp, 8
  23. end;
  24.  
  25. var
  26.   b: buf;
  27.  
  28. begin
  29.   b[0]:=7;
  30.   WriteLn(b[0]);
  31.   foo(b);
  32.   WriteLn(b[0]);
  33.   ReadLn;
  34. end.
  35.  
Title: Re: FPC 3.2.2 - Assembler call Assembler Routine - with nostackframe - how to ?
Post by: paule32 on April 14, 2025, 07:07:48 pm
I don't realy have much knowledge about Assembly.
I only know x86 Assembly, when I would call a Routine, I have to "puish" the register in Stack-Reverse calling convention (C / C++) to give the Parameters for the calling Routine.

But I don't thinking/know if the Stack is destroyed when I "push ebp  mov ebp, esp"...
This is for x86.
And I working in x64 Windows 11 Mode.
There is a totally new concept of calling Routines, where I not firm in.

And as I saw "nostackframe" I could simply do a "call bar" - but I am not in this knowledge.
Because there is not only a "call bar" - I have to give a Parameter from one source to the next ...

Please sorry for my English - it is bad, I know - but I don't know how to describe my Problem better...
I will do my best to learn and proof it.
Title: Re: FPC 3.2.2 - Assembler call Assembler Routine - with nostackframe - how to ?
Post by: paule32 on April 14, 2025, 09:10:11 pm
can I simply call "call bar" in foo ?
so a call through ... ?
Title: Re: FPC 3.2.2 - Assembler call Assembler Routine - with nostackframe - how to ?
Post by: Khrys on April 15, 2025, 07:00:38 am
nostackframe  simply prevents the compiler from managing local variables for you (including "invisible" temporaries). If you try to declare local variables in a  nostackframe  procedure, you'll get an error.

In older x86 (32-bit) calling conventions, all arguments were pushed onto the stack like you described, but that is no longer the case: all major modern calling conventions (x86-64) pass the first few parameters in registers (Windows uses  rcx, rdx, r8, r9  while Linux uses  rdi, rsi, rdx, rcx, r8, r9). This improves performance, but it also means that parameters must be manually stored somewhere in non-leaf functions (aka functions that call other functions, like your example).

@ALLIGATOR's response is what you need to do - manually allocate & deallocate stack space by moving the stack pointer (if you decide to add more parameters you must pay attention to stack alignment (https://stackoverflow.com/questions/64729055/what-does-aligning-the-stack-mean-in-assembly), though).
Title: Re: FPC 3.2.2 - Assembler call Assembler Routine - with nostackframe - how to ?
Post by: Thaddy on April 15, 2025, 07:45:56 am
Yes that example, while unfinished is good.
You are right about alignment when setting up de stack manually as in the second function.
TinyPortal © 2005-2018