2013-11-25 223 views
1

在DEC PDP-8小型機的每個程序開始時我發出的第一條指令是CLA CLL,用於清除累加器和鏈接(溢出)位。清零8086上的EAX寄存器%

這個簡單的指令似乎並不存在於8086處理器範圍內,我已經在各種技術網站上看到了很多討論它的最快方法,就像XORing它自己一樣。

這是否已通過處理器邏輯處理某處? 因此它在程序啓動前保證爲0?

+2

沒有'eax'或'%在8086'eax'和其他32位寄存器eax'在386新近出現的,而不是之前。無論如何,與自己註冊一個寄存器並不會使其歸零。異或與它自己的寄存器做它。 'xor'是最常見的方式,例如。 'xor ax,ax',但在所有Intel處理器'xor'和'sub'中的AFAIK同樣快,所以'sub ax,ax'與'xor ax,ax'一樣快。 – nrz

+0

對不起,我沒有看到你已經打印所有我的答案:)刪除我的答案 – Igor

+1

無論你需要在啓動時將EAX(或任何其他寄存器)清零?必要時將其歸零,例如當從函數返回0時,或者調用需要它歸零的東西時。清除寄存器「以防萬一」僅浪費處理器週期和代碼空間。無論如何,很有可能其他的東西很快就會被覆蓋。 –

回答

1

對於8086,清除AX寄存器(不是EAX)的最快和最短的方法是發出一些執行操作的ALU指令。那就是:

xor ax,ax ; opcode: 29 C0 

或者

sub ax,ax ; opcode: 31 C0 

最短因爲正規mov ax,0需要3個字節:B8 00 00,一個字節以上。 最快的因爲xorsub使用3個時鐘週期。 mov使用4個週期。

另一方面,xorsub將改變標誌,而mov不會。有時,當需要清除寄存器時,您不會介意更改標誌,有時您不想更改標誌。關於代碼清晰度,xor/sub「技巧」是衆所周知的,編譯器會使用它來快速註冊清零,因此任何彙編程序員都會意識到您想要執行的操作。

+0

謝謝,這是我正在尋找的答案,技術上完整並且明確解釋 – Android

+0

是不是相反? xor = 0x31和sub = 0x29? – tigrou

0

xormov做不同的事情。 xor將設置條件位並且mov不會。 如果您的目標是將寄存器設置爲特定值,則mov將明確告知軟件的讀者。

優化彙編程序有時可以安全地將mov reg, 0轉換爲xor reg, regsub reg, reg

sub reg, regxor reg, reg並不一定會在所有的時間執行同樣的速度。減法需要攜帶和排除或不排除。攜帶通常以非常有效的方式實施,所花費的時間很難測量,因此實際上人們傾向於認爲它們具有同樣快的執行速度。

+0

感謝Michael J. grey,doyanx和Hans Passant給予的回覆。當我發現表明我的問題已被回答時,我會使用它。再次大聲嚷嚷,'有一次,我會回來的'。 Andy – Android

+1

事實上,xor會被CPU識別並專門處理,因此不會有任何錯誤依賴。我不知道sub是否也有相同的處理 –

0

當程序啓動時(x86堆棧指針除外),處理器寄存器中的內容是無關緊要的。如果您不喜歡寄存器中的垃圾,只需將它們設置爲您喜歡的值即可。

這可能會在代碼開始時花費你所有10條指令。在實踐中,你不需要初始化你沒有立即使用的寄存器,所以它只有1或2條指令。更重要的是,大多數裝配程序比這個大得多,所以沒有人關心。

如果您堅持,您可以通過將寄存器調零(xor reg,reg/sub reg,reg/mov reg,0)來初始化您的寄存器。

值得一提的是,處理器可以利用某些指令。在現代英特爾芯片(不一定是x86)上,「xor reg,reg」打破了「reg」的管道依賴性,實現了更快的代碼,所以你應該堅持使用這些指令。

0

此外,還建議使用「XOR REG,REG」的32位寄存器,如果我們使用第一個同一個寄存器的16位部分,如果想改變我們的下述指令訪問32位。
實施例:

LOCATION DW 3 

xor eax, eax 
mov ax, [LOCATION] ; first a 16 bit access to the lower part of EAX 
shl eax, 2   ; following by a 32 bit access 

異或指令使我們的代碼更快的執行。我認爲movzx-instruction會執行速度較慢。

德克