下面的代码是我不久前为 Linux 编写的 - 它找到了最高设置位,我认为这就是您所要求的。它不符合您的确切规格,但应该很容易适应。
进一步说明:
- 返回 0 表示设置了第 0 位;如果没有找到位,则返回 64。
- 该汇编程序是为 Linux 下 GCC 使用的调用约定编写的。我不知道这在 Mac OS X 下有何不同 - 你需要检查一下。
- 输入是一个 64 位无符号整数。
- 每个 CPU 架构都被写入一个单独的 .S 源文件,并根据正在构建的目标使用“gcc”选择性地编译。我不使用内联汇编程序。
x86:
/*
* Find the highest set bit in a bitboard.
*
* %eax: &bb
*/
.globl x86_msb;
.type x86_msb,@function;
x86_msb:
mov 4(%eax), %edx
bsr %edx, %eax
jz msb_z1
add $32, %eax
ret
msb_z1:
mov (%eax), %edx
bsr %edx, %eax
jz msb_z2
ret
msb_z2:
mov $64, %eax
ret
x86_64:
/*
* Return the offset of the highest set bit in the bitmask
*
* %rdi: &bb
*/
.globl x64_msb;
.type x64_msb,@function;
x64_msb:
movq (%rdi), %rdi
bsrq %rdi, %rax
jz msb_empty
ret
msb_empty:
mov $64, %eax
ret
以下是 Windows 实现(.asm 文件):
x86:
;;
;; Return the offset of the highest set bit in the bitmask
;;
;; ECX: &bb
;;
public @x86_msb@4
@x86_msb@4:
mov edx, dword ptr [ecx + 4] ; bb (high)
bsr eax, edx
jz msb_z1
add eax, 32
ret
msb_z1:
mov edx, dword ptr [ecx] ; bb (low)
bsr eax, edx
jz msb_z2
ret
msb_z2:
mov eax, 64
ret ; bb is empty
x86_64:
;;
;; Return the offset of the highest set bit in the bitmask
;;
;; RCX: &bb
;;
x64_msb PROC
mov r8, qword ptr [rcx] ; r8 = bb
bsr rax, r8 ; rax = lsb(bb)
jz msb_empty
ret
msb_empty:
mov eax, 64 ; bb was empty
ret
x64_msb ENDP