2010-03-10 122 views
7

有时我写的很短的装配功能,如为什么Delphi编译器不内联汇编函数?

function SeniorBit(Value: LongWord): Integer; 
asm 
     OR EAX,EAX 
     JZ @@Done 
     BSR EAX,EAX 
     INC EAX 
@@Done: 
end; 

,这似乎是内联的最佳人选:

function SeniorBit(Value: LongWord): Integer; inline; 

但是Delphi编译器不允许它。为什么?


更新时间:

感谢ldsandon,存在5.5岁开report on QC。该报告包含一些提议(如扩展asm指令)以简化编译器的asm内联。我宁愿在程序/功能级别上引入“裸体”指令,它告诉编译器它不必为程序创建栈帧,并且可以选择保留哪些寄存器(在eax,edx和ecx之间)。

如果使用BASM代码进行高效内联过程的一般任务很困难(也可能没有必要),一个好主意是为最重要的情况启用内联(如裸函数与明确声明的寄存器使用)。

+0

在编译时使用不同的调用约定时,应该在结果之后添加寄存器调用约定(例如...:Integer; register;)以确保该函数也可以工作。 – 2010-03-10 07:30:01

+2

如果您想讨论编译器支持内联汇编函数的未来可能性,那么QC或消息板可能是最好的选择。我试图回答,目前确实不可能用asm块嵌入函数,因为它是实现的。你可能认为这是一个好主意(嘿,我喜欢大会,并认为它会很好)。但是SO是讨论编译器功能请求的地方吗?我想你想得到关于你手边的问题的答案:为什么我不能把这个内联。 – 2010-03-10 10:19:34

+0

@Ritsaert Hornstra:您为什么认为SO不是讨论编译器功能请求的地方?这显然是编程问题,必须在哪里解答如何以最好的方式实现这个东西,以及[可能的修辞问题]为什么这个东西还没有实现。 – kludg 2010-03-10 10:39:05

回答

10

查看Quality Central报告#9283(并为此投票)。基本上问题是编译器应该能够理解在内联代码之前要保留哪些寄存器以及之后要恢复的内容。只要编译器处理寄存器,它很容易,如果没有使用控制,则不是。 你的例子非常简单,但编译器必须能够处理更复杂的情况。该报告处于开放状态,希望新的编译器也能够内联BASM代码。

5

您不能内联手工制作汇编代码。

这将很难让这些汇编程序内联;正常内联各种对寄存器使用的影响,局部变量等是编译器无法使用内联汇编的地方。

+0

我无法看到内联上述汇编函数的任何问题。实际上它比纯粹的pascal功能更简单。 – kludg 2010-03-10 07:40:45

+4

如果你认为它很简单,EMbarcadero应该聘请你为他们的新编译器大师:-)。不是在开玩笑:这很难。一个编译器执行不同的阶段(不知道从里面的Delphi编译器)文本(lexing)令牌(解析)语法树(优化)语法树 - > ... - >(codegen)机器码。现在,在使用某种抽象语法树的优化阶段,嵌入式assemently很难分析。 – 2010-03-10 08:05:27

+0

我不明白为什么?这是一个从前到后的简单线性扫描,以查找分配/修改的寄存器。一些启发式(如使用BP设置堆栈框)。请注意,如果检测到奇怪的构造(如adressing%esp),则可以禁用内联。有基础的工作已经很棒了。 – 2010-03-10 23:13:11