Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2012-01

Compiling Intel assembly code in 32 and 64 bit.

2 messages · 2 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

kyan

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?

Thank you in advance and bare with me, I am by no means an assembly expert.

Reply by email

Ludo Brands
to kyan
Show quoted text 48 lines
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

Reply by email