2010-03-10 125 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