[fpc-devel] Compiling Intel assembly code in 32 and 64 bit.

Ludo Brands ludo.brands at free.fr
Thu Jan 26 16:03:47 CET 2012


> Hello everyone,
> 
> I am trying to compile the following code:
> 
> procedure XORBuff(I1, I2: Pointer; Size: Integer; Dest: 
> Pointer); {$IFDEF FPC}
>   {$ASMMODE INTEL}
> {$ENDIF}
> asm
>        AND   ECX,ECX
>        JZ    @@5
>        PUSH  ESI
>        PUSH  EDI
>        MOV   ESI,EAX
>        MOV   EDI,Dest
> @@1:   TEST  ECX,3
>        JNZ   @@3
> @@2:   SUB   ECX,4
>        JL    @@4
>        MOV   EAX,[ESI + ECX]
>        XOR   EAX,[EDX + ECX]
>        MOV   [EDI + ECX],EAX
>        JMP   @@2
> @@3:   DEC   ECX
>        MOV   AL,[ESI + ECX]
>        XOR   AL,[EDX + ECX]
>        MOV   [EDI + ECX],AL
>        JMP   @@1
> @@4:
>        POP   EDI
>        POP   ESI
> @@5:
> end;
> 
> in FPC for Win64 and I get an error (invalid opcode/operand
> combination) in the lines that PUSH and POP registers. If I 
> replace the 32-bit regs with their 64-bit "R" equivalents 
> (PUSH RSI instead of PUSH ESI) it compiles but I suppose it 
> will not compile for Win32.
> 
> So apart from the apparent solution of {$ifdef cpu64}'ing is 
> there any other way to make this compile for 64bit (and 
> Delphi XE if possible, which is 32bit) without conditional 
> compilation? By searching through the FPC source directory I 
> have noticed that units with Intel assembly code that 
> contains PUSH/POP instructions use the "E" regs without 
> ifdef'ing. How do these compile?
> 

There is more than the PUSH/POP that is different. The complete ABI is
different: parameters are passed in other registers, different stack frames,
etc. Changing RSI into ESI will make the assembler happy but the program
won't work as intended. 
The code you found without ifdef is very probably in the cpu specific
directories.

Ludo





More information about the fpc-devel mailing list