klu*_*udg 2 delphi freepascal lazarus fpc basm
我在将Delphi BASM32代码移植到FPC时遇到了一个问题:
program MulTest;
{$IFDEF FPC}
{$mode delphi}
{$asmmode intel}
{$ELSE}
{$APPTYPE CONSOLE}
{$ENDIF}
function Mul(A, B: LongWord): LongWord;
asm
MUL EAX,EDX
end;
begin
Writeln(Mul(10,20));
Readln;
end.
Run Code Online (Sandbox Code Playgroud)
上面的代码在Delphi XE中编译并按预期工作; FPC在线输出编译时错误MUL EAX,EDX:
错误:Asm:[mul reg32,reg32]操作码和操作数的无效组合
我正在使用Lazarus 1.4.4/FPC2.6.4 for Win32(当前稳定版)
任何解决方法或修复问题?
Rem*_*eau 10
FreePascal是正确的.只有3种形式MUL:
MUL r/m8
MUL r/m16
MUL r/m32
Run Code Online (Sandbox Code Playgroud)
执行第一个操作数(目标操作数)和第二个操作数(源操作数)的无符号乘法,并将结果存储在目标操作数中.目标操作数是位于寄存器AL,AX或EAX中的隐含操作数(取决于操作数的大小); 源操作数位于通用寄存器或存储器位置.
换句话说,第一个操作数(用于输入和输出)在AL/ AX/中指定,EAX第二个输入操作数显式指定为通用寄存器或存储器地址.
所以,MUL EAX,EDX确实是一个无效的汇编指令.
如果在Delphi中编译此代码并使用调试器查看生成的程序集,您将看到调用Mul(10,20)生成以下程序集代码:
// Mul(10,20)
mov edx,$00000014
mov eax,$0000000a
call Mul
Run Code Online (Sandbox Code Playgroud)
//MUL EAX,EDX
mul edx
Run Code Online (Sandbox Code Playgroud)
因此,正如您所看到的,Delphi实际上是解析您的源代码,看到第一个操作数EAX并为您剥离它,从而产生正确的程序集.FreePascal并没有为你做那一步.
解决方法?编写正确的汇编代码.不要依赖编译器为您重新解释代码.
function Mul(A, B: LongWord): LongWord;
asm
MUL EDX
end;
Run Code Online (Sandbox Code Playgroud)
或者,您可以直接编写汇编代码,让编译器为您完成工作.它知道如何将两个LongWord值组合在一起:
function Mul(A, B: LongWord): LongWord;
begin
Result := A * B;
end;
Run Code Online (Sandbox Code Playgroud)
虽然Delphi确实使用IMUL而不是MUL在这种情况下.来自Delphi的文档:
的值
x / y是类型的Extended,无论类型中的x和y.对于其他算术运算符,Extended只要至少有一个操作数是实数,结果就是类型; 否则,Int64当至少一个操作数是类型时,结果是类型Int64; 否则,结果是类型Integer.如果操作数的类型是整数类型的子范围,则将其视为整数类型.
除非禁用堆栈帧并启用优化,否则它还会使用一些难看的膨胀组件.通过配置这两个选项,可以Mul()生成单个IMUL EDX指令(RET当然还有指令).如果您不想在项目范围内更改选项,则可以Mul()使用{$STACKFRAMES OFF}/ {$W-}和{$OPTIMIZATION ON}/ {$O+}编译器指令将它们隔离.
{$IFOPT W+}{$W-}{$DEFINE SF_Was_On}{$ENDIF}
{$IFOPT O-}{$O+}{$DEFINE O_Was_Off}{$ENDIF}
function Mul(A, B: LongWord): LongWord;
begin
Result := A * B;
end;
{$IFDEF SF_Was_On}{W+}{$UNDEF SF_Was_On}{$ENDIF}
{$IFDEF O_Was_Off}{O-}{$UNDEF O_Was_Off}{$ENDIF}
Run Code Online (Sandbox Code Playgroud)
产生:
imul edx
ret
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
138 次 |
| 最近记录: |