如何在Assembly中测试整数位

时间:2017-04-13 06:49:39

标签: assembly gas

如果给出整数N,如何测试未设置的最低有效位。 我的第一次尝试(气体语法):

#define N      %ecx
#define return %eax

 /* prototype:
  * int leastSigUnsetBit(unsigned int N)
  */

.text
.global leastSigUnsetBit
leastSigUnsetBit:

movl N, 4(%esp)     

movl $-1, return
Loop:
    inc return
    bt return, N
    jc Loop
ret

1 个答案:

答案 0 :(得分:3)

您可以使用bsf(位向前扫描)测试lsb 设置,或者使用tzcnt测试更好 我希望你知道当操作数为零时bsf将返回未定义的数据。 tzcnt修正了这一点 如果要测试未设置的LSB,只需使用not反转输入,然后测试LSB设置。

请注意,tzcnt(几乎)反向兼容并且比bsf更快。旧{c}将tzcnt读取rep bsf reg,reg,但tzcnt会以bsf的方式修改标记:

bsf: ZF=0 -> input was 0.
tzcnt: ZF=0 -> output is 0, CF=0 -> input was zero.

最好的解决方案是使用tzcnt,但请确保您已经测试过cpu支持tzcnt(或者它会执行bsf并且您的代码会给出错误的结果)

;Intel syntax
mov eax,not(-1)
tzcnt edx,eax     ;edx = 32     
mov eax,[random]
not eax           
tzcnt eax,eax

另一种方法是测试操作数是否为零并进行相应调整。 bsf 确实正确更改了标记,您可以使用它来补偿。

来自:http://www.felixcloutier.com/x86/BSF.html

  

BSF   .....   受影响的旗帜

     

如果所有源操作数均为0,则ZF标志设置为1;

not eax
mov edx,32
bsf eax,eax       
cmovz eax,edx         //force result to 32 if zero inputted.

请注意,原则上我不编写AT& T语法,你必须在适用的情况下反转操作数。

tzcnt runs a lot faster than bsf(因为cpu不是它不必做未定义的行为模拟)。