当前位置:  开发笔记 > 编程语言 > 正文

FPC BASM32 MUL bug?

如何解决《FPCBASM32MULbug?》经验,为你挑选了2个好方法。

我在将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.

上面的代码在Delphi XE中编译并按预期工作; FPC在线输出编译时错误MUL EAX,EDX:

错误:Asm:[mul reg32,reg32]操作码和操作数的无效组合

我正在使用Lazarus 1.4.4/FPC2.6.4 for Win32(当前稳定版)

任何解决方法或修复问题?



1> Remy Lebeau..:

FreePascal是正确的.只有3种形式MUL:

MUL r/m8
MUL r/m16
MUL r/m32

执行第一个操作数(目标操作数)和第二个操作数(源操作数)的无符号乘法,并将结果存储在目标操作数中.目标操作数是位于寄存器AL,AX或EAX中的隐含操作数(取决于操作数的大小); 源操作数位于通用寄存器或存储器位置.

换句话说,第一个操作数(用于输入和输出)在AL/ AX/中指定,EAX第二个输入操作数显式指定为通用寄存器或存储器地址.

所以,MUL EAX,EDX确实是一个无效的汇编指令.

如果在Delphi中编译此代码并使用调试器查看生成的程序集,您将看到调用Mul(10,20)生成以下程序集代码:

// Mul(10,20)
mov edx,$00000014
mov eax,$0000000a
call Mul

//MUL    EAX,EDX
mul edx

因此,正如您所看到的,Delphi实际上是解析您的源代码,看到第一个操作数EAX并为您剥离它,从而产生正确的程序集.FreePascal并没有为你做那一步.

解决方法?编写正确的汇编代码.不要依赖编译器为您重新解释代码.

function Mul(A, B: LongWord): LongWord;
asm
         MUL    EDX
end;

或者,您可以直接编写汇编代码,让编译器为您完成工作.它知道如何将两个LongWord值组合在一起:

function Mul(A, B: LongWord): LongWord;
begin
  Result := A * B;
end;

虽然Delphi确实使用IMUL而不是MUL在这种情况下.来自Delphi的文档:

的值x / y是类型的Extended,无论类型中的xy.对于其他算术运算符,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}

产生:

imul edx
ret



2> Sergey Salni..:

MUL总是乘以AL,AX或EAX(更多细节),因此您应该只指定另一个操作数.

推荐阅读
周扒pi
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有