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?
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
This "booleanizes" a value, producing a 0 or 1 like int ebx = !!ebx
would in C.
Just use xor so you don't have to worry about which CPU recognizes which zeroing idiom. xor (being a recognized zeroing idiom, unlike mov reg, 0 ) has some obvious and some subtle advantages (summary list, then I'll expand on those):
TEST sets the zero flag, ZF , when the result of the AND operation is zero. If two operands are equal, their bitwise AND is zero when both are zero. TEST also sets the sign flag, SF , when the most significant bit is set in the result, and the parity flag, PF , when the number of set bits is even.
The zero flag is a single bit flag that is a central feature on most conventional CPU architectures (including x86, ARM, PDP-11, 68000, 6502, and numerous others). It is often stored in a dedicated register, typically called status register or flag register, along with other flags.
EAX is the register used by IA32 calling conventions to either return an interger value or a memory address to the calling routine. By design, strcpy can return either -1,0 or 1 in EAX with 0 indicating both strings match. TEST EAX,EAX tests whether EAX is zero or not and sets or unsets the ZF bit.
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".
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. :)
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)
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
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
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).
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
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:
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With