确定寄存器的值是否等于零的最简单方法是什么? [英] What's the easiest way to determine if a register's value is equal to zero or not?

查看:259
本文介绍了确定寄存器的值是否等于零的最简单方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆