确定寄存器的值是否等于零的最简单方法是什么? [英] What's the easiest way to determine if a register's value is equal to zero or not?
问题描述
我正在使用Irvine库中的x86程序集.
I'm using x86 assembly with the Irvine library.
检查寄存器值是否等于零的最简单方法是什么?
What's the easiest way to check if a register value is equal to zero or not?
我使用了cmp指令,但是我正在寻找其他方法. 这是我使用cmp指令的代码,寄存器是ebx
I used cmp instruction but i'm searching for alternative way. This is my code using cmp instruction and the register is ebx
cmp ebx,0
je equ1
mov ebx,0
jmp cont
equ1:
mov ebx,1
jmp cont
cont:
exit
这会布尔化"一个值,在C中会像int ebx = !!ebx
那样产生0或1.
This "booleanizes" a value, producing a 0 or 1 like int ebx = !!ebx
would in C.
推荐答案
可能最简单"或最简单的不关心细节"回答了确定的方法是:
Probably the "easiest", or simplest, "not-caring about details" answer how to determine is:
; 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".
彼得·科德斯(Peter Cordes)提供了详细的答案,以"testl
反对eax? 有关设置标志的问题等.也有一个指向类似答案的链接,但是从性能的角度考虑为什么这是最好的方法. :)
There's a detailed answer from Peter Cordes to "testl
eax against eax?" question reasoning about flags being set, etc. Also has a link to yet another similar answer, but reasoning about why it is best way from performance point of view. :)
当ebx
为零时如何设置其他寄存器(我将选择eax
)为1,而当ebx
为非零(ebx
本身的非破坏性方式)时如何设置为0:>
How to set some other register (I will pick eax
) to 1 when ebx
is zero, and to 0 when ebx
is non-zero (non destructive way for ebx
itself):
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
为零/非零时如何将ebx
自身转换为1/0:
Or how to convert ebx
itself into 1/0 when ebx
is zero/non-zero:
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
为零/非零时如何将ebx
自身转换为1/0,其他变体(在"P6"和"Haswell"内核上更快):
Or how to convert ebx
itself into 1/0 when ebx
is zero/non-zero, other variant (faster on "P6" to "Haswell" cores):
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).
etc, etc... It depends what happens before your testing, and also what you really want as output of test, there're many possible ways (optimal for different situations, and optimal for different target CPU).
我将添加一些更常见的情况...从N到0的反循环递减计数,以循环N次:
I will add few more extremely common situations... A counter-loop down-counting from N to zero, to loop N times:
mov ebx,5 ; loop 5 times
exampleLoop:
; ... doing something, preserving ebx
dec ebx
jnz exampleLoop ; loop 5 times till ebx is zero
如何处理word
(16b)数组的5个元素(以array [0],array [1],...顺序访问它们):
How to process 5 elements of word
(16b) array (accessing them in array[0], array[1], ... order):
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
再举一个例子,我很喜欢这个例子:
One more example, I somehow like this one a lot:
当ebx
为零/非零并且您已经在某个寄存器中具有值1
时,如何将目标寄存器(例如eax
)设置为〜0(-1)/0示例):
How to set target register (eax
in example) to ~0 (-1)/0 when ebx
is zero/non-zero and you already have value 1
in some register (ecx
in example):
; 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也可以用作完整的位掩码,用于进一步的and/xor/or
操作,因此有时更方便.
The -1 may look as practical as 1 (for indexing purposes at least), but -1 works also as full bitmask for further and/xor/or
operations, so sometimes it is more handy.
这篇关于确定寄存器的值是否等于零的最简单方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!