大概是「最簡單」,或者簡單地說,「不關心細節有關」回答如何確定是:
; here ebx is some value, flags are set to anything
test ebx,ebx ; CF=0, ZF=0/1 according to ebx
jz whereToJumpWhenZero
; "non-zero ebx" will go here
; Or you can use the inverted "jnz" jump to take
; a branch when value was not zero instead of "jz".
有一個詳細的answer from Peter Cordes to "testl
eax against eax?" question關於設置標誌的推理等。還有一個鏈接到另一個類似的答案,但推斷爲什麼它是從性能角度來看最好的方式。 :)
如何設置一些其他的寄存器(我會選擇eax
)到1時ebx
是零,而設置爲0時ebx
非零(非破壞性的方式爲ebx
本身):
xor eax,eax ; eax = 0 (upper 24 bits needed to complete "al" later)
test ebx,ebx ; test ebx, if it is zero (ZF=0/1)
setz al ; al = 1/0 when ZF=1/0 (eax = 1/0 too)
或如何ebx
轉換成自己當1/0爲ebx
零/非零:
neg ebx ; ZF=1/0 for zero/non-zero, CF=not(ZF)
sbb ebx,ebx ; ebx = 0/-1 for CF=0/1
inc ebx ; 1 when ebx was 0 at start, 0 otherwise
或如何ebx
本身轉化爲1/0時,ebx
是零/非零的,其他的變種(快上「P6」爲「Haswell的」芯):
test ebx,ebx ; ZF=1/0 for zero/non-zero ebx
setz bl ; bl = 1/0 by ZF (SETcc can target only 8b r/m)
movzx ebx,bl ; ebx = bl extended to 32 bits by zeroes
等等,等等...這取決於你在測試之前發生了什麼,還你真正想要的作爲測試的輸出,存在多種可能的方式(對於不同的情況是最佳的,對於不同的目標CPU是最佳的)。
我會加幾個非常常見的情況......一個反向環向下計數從N到零,循環N次:
mov ebx,5 ; loop 5 times
exampleLoop:
; ... doing something, preserving ebx
dec ebx
jnz exampleLoop ; loop 5 times till ebx is zero
如何處理的word
5個元素( 16b)數組(在數組[0],數組[1]中訪問它們,...順序):
mov ebx,-5
lea esi,[array+5*2]
exampleLoop:
mov ax,[esi+ebx*2] ; load value from array[i]
; process it ... and preserve esi and ebx
inc ebx
jnz exampleLoop ; loop 5 times till ebx is zero
再舉一個例子,我不知何故像這樣的很多:
如何設置目標寄存器(eax
例子中)到〜0(-1)/ 0時ebx
是零/非零並且已經有值1
在某些寄存器(例如在ecx
):
; ecx = 1, ebx = some value
cmp ebx,ecx ; cmp ebx,1 => CF=1/0 for ebx zero/non-zero
sbb eax,eax ; eax = -1 (~0)/0 for CF=1/0 ; ebx/ecx intact
-1可能看起來儘可能的1(用於索引目的至少),但-1還可以作爲完整位掩碼用於進一步的操作,所以有時它更方便。
您至少使用80386條指令(在8086上不存在'ebx')。此外,答案取決於此代碼前面的指令,零值的存在可能會按照前面的指令進行「泄漏」,從而爲您節省更多的測試時間,否則常用的習慣用法是'test ebx,ebx'來設置ZF。然後把ZF變成0/1的值是ebx的另一個故事,那裏的'測試'可能再次不是最佳解決方案的一部分。下定決心,無論你想確定寄存器是否爲零,或者你想根據它設置一些寄存器爲0/1。 #'mov ebx,0' ='xor ebx,ebx'當你可以摧毀旗幟時。 – Ped7g
爲了說明我的觀點(細節的重要性),讓我們假設在這之前的最後一個(標誌和ebx)修改指令是'neg ebx'。然後'sbb ebx,ebx'會在'ebx'等於零時將'ebx'設置爲-1,對於非零值則設爲0(進一步'neg ebx'會將其轉換爲原來的0/1工作方式)。 – Ped7g
沒有與我一起工作。 –