FPC BASM32 POP bug?
Asked Answered
T

0

6

Another discrepancy between Delphi and FPC BASM:

program PopTest;

{$IFDEF FPC}
  {$mode delphi}
  {$asmmode intel}
{$ELSE}
  {$APPTYPE CONSOLE}
{$ENDIF}

var
  B: LongWord;

procedure Pop(A: LongWord; var B: LongWord);
asm
         PUSH   EAX
         POP    [EDX]
end;

begin
  Pop(5, B);
  Writeln(B);
  Readln;
end.

This 32-bit code works as expected in Delphi XE and produces access violation in FPC (2.6.4)

Debugging reveals that POP instruction (in FPC compiler) pops a word instead of expected double word, thus destroying the stack and the procedure's return address. The solution is

procedure Pop(A: LongWord; var B: LongWord);
asm
         PUSH   EAX
         POP    DWORD [EDX]
end;

which is actually better code since it removes the parameter size ambiguity.

Bug or not?

Transmigrant answered 30/12, 2015 at 9:24 Comment(8)
I don't understand how popping a Word into a DWord can lead to an AV? Is it not the other way around?Philbert
Why would you expect DWORD? Surely you need to specify what the pointer points to. Is there any documentation anywhere? Or do we have to reverse all of this?!!Erosion
@Lieven 4 bytes pushed, but only 2 bytes popped, stack destroyedErosion
tx David. It didn't dawn on me that push/pop operations can have different sizes. Stupid but there you have it ;)Philbert
@DavidHeffernan If DWORD specifier is required here the compiler should generate compile-time error.Transmigrant
@serg I agree ......Erosion
It's probably not a bug - it's poorly documented, but FPC uses, afaik, GNU for ASM and there are rather significant differences between how Delphi and FPC work with inline assembly. I wouldn't be surprised if you are required to be explicit about memory sizes with FPC. There are other rather serious differences between FPC and Delphi as regards inline assembly. With optimizations on, eg:, you cannot treat registers other than EDX as volatile. Parameters are passed RTL instead of LTR... lots of very serious inconsistencies. There should be no expectation that ASM should translate directly.Oakes
On x86(_64) targets FPC mostly uses an internal assembler. So there are actually two assemblers involved, a reader (syntax to asmlist) and assembler (asmlist to .o(bj)) But yes, it has leaned towards ATT syntax for a long time, meaning that intel syntax assember only started to get attention after say 2007. Anyway, I can remember this is an known issue in 2.6.4, first logical thing would be to test with 3.0.0 (last release) and trunk. The older 2.6.x branch is abandonned for over an year.Bartell

© 2022 - 2024 — McMap. All rights reserved.