「test eax,eax」比「cmp eax,0」更有效嗎?在「cmp eax,0」不符合要求的情況下,是否有必要使用「test eax,eax」?Linux程序集:「test eax,eax」和「cmp eax,0」有什麼區別
謝謝!
「test eax,eax」比「cmp eax,0」更有效嗎?在「cmp eax,0」不符合要求的情況下,是否有必要使用「test eax,eax」?Linux程序集:「test eax,eax」和「cmp eax,0」有什麼區別
謝謝!
由於臧明傑已經在評論已經說了,test eax,eax
幾乎是相同的cmp eax,0
,但它短於cmp
,因爲cmp
你必須提供0
作爲參數。請注意,節省不是很大,因爲第二個操作數得到符號擴展以匹配第一個操作數的大小,所以它不一定需要整個4個字節來表示該零。
現在,你問的是是否有任何其他差異。這是一個合理的問題,因爲cmp
是算術運算(它執行減法並丟棄結果),而test
是邏輯運算(它執行按位AND並放棄結果),因此可以合理懷疑他們可能會不同地修改Flags
寄存器。
事實證明,這兩個指令修改Flags
寄存器在幾乎相同的方式。兩條指令都修改標誌寄存器的OF SF ZF AF PF和CF位。 test
指令總是清除OF和CF,但這也是cmp
對零的做法。唯一的區別是cmp
指令將正確設置the obscure AF
flag,而test
指令將使該標誌的內容不確定。但在cmp eax,0
的情況下,無論eax
的值如何,AF將始終被清除,因此您從test eax,eax
中不能從cmp eax,0
中學到任何東西。
因此,我會得出結論,test eax,eax
會給你cmp eax,0
不會的東西,反之亦然。除了保存一個或兩個指令代碼之外,這兩條指令似乎對於任何實際的或甚至不太實際的目的都是完全可以互換的。
使用test eax,eax
而不是cmp eax,0
表明您知道您的裝配。它還表明,你更喜歡稍微隱蔽的,稍微好一點的表現指令,而不是簡單易懂的指令。這是一種傾向於從其他極客獲得獎勵積分的東西,但在過去的幾十年中,它在現實世界中沒有任何實際用處。
英特爾Core2或Nehalem可能會有性能差異,其中TEST可以與CMP的更多JCC類型進行宏觀融合。例如Core2和Nehalem可以將'test eax,eax/js'宏觀融合,但不能'cmp eax,0/js'。不過,Nehalem可以將'cmp eax,0/jl'宏觀融合。 (Core2不能,但是Core2只能在32位模式下完全熔合)。 [見Agner Fog's microarch pdf](http://agner.org/optimize/) –
'test'比'cmp'短,因爲它不包含immediate。 –
在您提供的示例中,與OpCode計數觀點沒有什麼不同。你只是問「EAX是否爲零?」所以它可能只是整個代碼中的一致性問題。參考英特爾體系結構和說明http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html –
Peter Cordes在這裏有一個很好的答案:http:// stackoverflow。 com/a/33724806/3857942,它涉及'cmp'和'test'之間的區別。這個問題本身並不重複,因爲問題是關於使用'或'進行測試的問題,但答案肯定與這個問題有關。 –