在DEC PDP-8小型機的每個程序開始時我發出的第一條指令是CLA CLL
,用於清除累加器和鏈接(溢出)位。清零8086上的EAX寄存器%
這個簡單的指令似乎並不存在於8086處理器範圍內,我已經在各種技術網站上看到了很多討論它的最快方法,就像XORing它自己一樣。
這是否已通過處理器邏輯處理某處? 因此它在程序啓動前保證爲0?
在DEC PDP-8小型機的每個程序開始時我發出的第一條指令是CLA CLL
,用於清除累加器和鏈接(溢出)位。清零8086上的EAX寄存器%
這個簡單的指令似乎並不存在於8086處理器範圍內,我已經在各種技術網站上看到了很多討論它的最快方法,就像XORing它自己一樣。
這是否已通過處理器邏輯處理某處? 因此它在程序啓動前保證爲0?
對於8086,清除AX寄存器(不是EAX)的最快和最短的方法是發出一些執行操作的ALU指令。那就是:
xor ax,ax ; opcode: 29 C0
或者
sub ax,ax ; opcode: 31 C0
最短因爲正規mov ax,0
需要3個字節:B8 00 00
,一個字節以上。 最快的因爲xor
和sub
使用3個時鐘週期。 mov
使用4個週期。
另一方面,xor
和sub
將改變標誌,而mov不會。有時,當需要清除寄存器時,您不會介意更改標誌,有時您不想更改標誌。關於代碼清晰度,xor/sub「技巧」是衆所周知的,編譯器會使用它來快速註冊清零,因此任何彙編程序員都會意識到您想要執行的操作。
xor
和mov
做不同的事情。 xor
將設置條件位並且mov
不會。 如果您的目標是將寄存器設置爲特定值,則mov
將明確告知軟件的讀者。
優化彙編程序有時可以安全地將mov reg, 0
轉換爲xor reg, reg
或sub reg, reg
。
sub reg, reg
和xor reg, reg
並不一定會在所有的時間執行同樣的速度。減法需要攜帶和排除或不排除。攜帶通常以非常有效的方式實施,所花費的時間很難測量,因此實際上人們傾向於認爲它們具有同樣快的執行速度。
感謝Michael J. grey,doyanx和Hans Passant給予的回覆。當我發現表明我的問題已被回答時,我會使用它。再次大聲嚷嚷,'有一次,我會回來的'。 Andy – Android
事實上,xor會被CPU識別並專門處理,因此不會有任何錯誤依賴。我不知道sub是否也有相同的處理 –
當程序啓動時(x86堆棧指針除外),處理器寄存器中的內容是無關緊要的。如果您不喜歡寄存器中的垃圾,只需將它們設置爲您喜歡的值即可。
這可能會在代碼開始時花費你所有10條指令。在實踐中,你不需要初始化你沒有立即使用的寄存器,所以它只有1或2條指令。更重要的是,大多數裝配程序比這個大得多,所以沒有人關心。
如果您堅持,您可以通過將寄存器調零(xor reg,reg/sub reg,reg/mov reg,0)來初始化您的寄存器。
值得一提的是,處理器可以利用某些指令。在現代英特爾芯片(不一定是x86)上,「xor reg,reg」打破了「reg」的管道依賴性,實現了更快的代碼,所以你應該堅持使用這些指令。
此外,還建議使用「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會執行速度較慢。
德克
沒有'eax'或'%在8086'eax'和其他32位寄存器eax'在386新近出現的,而不是之前。無論如何,與自己註冊一個寄存器並不會使其歸零。異或與它自己的寄存器做它。 'xor'是最常見的方式,例如。 'xor ax,ax',但在所有Intel處理器'xor'和'sub'中的AFAIK同樣快,所以'sub ax,ax'與'xor ax,ax'一樣快。 – nrz
對不起,我沒有看到你已經打印所有我的答案:)刪除我的答案 – Igor
無論你需要在啓動時將EAX(或任何其他寄存器)清零?必要時將其歸零,例如當從函數返回0時,或者調用需要它歸零的東西時。清除寄存器「以防萬一」僅浪費處理器週期和代碼空間。無論如何,很有可能其他的東西很快就會被覆蓋。 –