2012-11-16 69 views
1

我正在將代碼從MASM移植到C內聯彙編程序(x86,Windows,MS VC) 愚蠢不是一個真正的代碼,只是欺騙以提供一個想法。比方說,我將一些數據定義爲靜態數組,甚至是兩個標籤之間的代碼塊,我需要獲取它的大小。Visual-C++內聯彙編程序的兩個偏移量的差異

label1: 
    bla bla bla 
    label2: 
    .... 
    mov eax, (offset label2 - offset label1) 

這樣的代碼在MASM就像一個魅力,但在CI收到以下錯誤消息: 「錯誤C2425:‘ - ’:在‘第二個操作數’非常量表達式」 我可以編譯:我希望編譯器在編譯時評估(偏移label1 - offset label2),但它看起來像我錯了。 當然,我可以得到 mov eax,offset label2 mov edx,offset label1 sub eax,edx 編譯後的,但是這只是用於計算常量的額外代碼。 有人可以解釋我,請問我的代碼有什麼問題?

它可能是由搬遷造成的?如何推動它?

期待一個答案, 謝謝。

+0

你至少可以簡化一下:mov eax,offset label2; sub eax,offset label1; –

回答

0

是的,它可能是由重定位的威脅引起的,但也可能是處理相對跳躍的變長指令的威脅。很可能是因爲一些小小的麻煩,彙編程序編寫人員採取了簡單的方法,並實現了一個1遍或2遍編譯器,以儘快做出最終決定。因此一些便利的表達式不受支持。

正如評論中的建議,彙編程序仍可能支持mov +子組合。

0

真正的彙編程序可能會在代碼已經獲得所有標籤的固定地址之前,先通過幾次代碼運行。例如,根據您想要跳躍的程度,某些跳躍有短而長的形式。如果你在標籤之間有這樣的跳躍,距離取決於跳躍的位置。

C編譯器可能會將部分內容留給鏈接器/加載器,並且在編譯時沒有修復這些值。

你很可能得到ADDRES計算代碼到兩個指令

mov EAX, offset Label2 
sub EAX, offset Label1 

我不認爲這會正是破壞代碼的性能。

+0

那麼......如果它不知道編譯這個__asm塊時,它如何知道label2的偏移呢?似乎是這樣;那麼在編譯時我是否會要求它進行分割,或者使用sub eax,offset label1來做它自己。 –

+0

問題是,在真實代碼中,這樣的計算需要lea eax,[ebx +()],我沒有自由寄存器等等。我想編譯器有一些限制,所以它不能評估這樣的表達式。感謝您的回覆! –

+0

編譯器可能不知道確切的地址,但鏈接器或程序加載器稍後將填入空白。 –