如果给出整数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
答案 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不是它不必做未定义的行为模拟)。