我有一个 64 位变量,想要计算其二进制表示形式中 1 和 0 的数量。我不想更改变量中的值,因此我想使用 Test 运算符来计算变量中 1 的数量。我的问题是,我不确定在使用 32 位寄存器时如何处理 64 位变量。
.data
aBigVar QWORD ?
.code
mov ecx, 63 ; use as loop counter
mov eax, 0b
Begin:
add eax, 01b;
test aBigVar, eax ; error: instruction operands must be same size
jz LoopToStart
inc dl
loop Start
LoopToStart:
loop Start
您应该分别处理该值的上半部分和下半部分,因为此任务是位计数,其中您可以单独处理每个位。
此代码显示了一个概念,但我不擅长 MASM,并且此代码出现链接错误。
.486
.model flat,stdcall
.data
aBigVar QWORD ?
.code
mov ecx, 32 ; use as loop counter
mov eax, 1b
xor dl, dl ; dl = 0
Begin:
test DWORD PTR aBigVar, eax
jz NoInc1
inc dl
NoInc1:
test DWORD PTR (aBigVar + 4), eax
jz NoInc2
inc dl
NoInc2:
shl eax, 01b;
loop Start
Start:
END
我的问题是,我不确定在使用 32 位寄存器时如何处理 64 位变量。
test
指令您必须分别处理 qword 变量的两个 32 位部分:
xor eax, eax ; Result
xor ebx, ebx ; (*)
mov ecx, 1 ; Test mask {1,2,4,8,...}
mov edx, aBigVar
mov esi, aBigVar + 4
More:
test edx, ecx ; EDX has low dword
setnz bl ; (*) -> EBX=[0,1]
add eax, ebx
test esi, ecx ; ESI has high dword
setnz bl ; (*) -> EBX=[0,1]
add eax, ebx
shl ecx, 1
jnz More
shr
(或 shl
)指令您必须再次分别处理 qword 变量的两个 32 位部分。您不断推出位,直到寄存器不再有设置位:
xor eax, eax ; Result
mov edx, aBigVar
Lo32:
shr edx, 1
adc eax, 0
test edx, edx
jnz Lo32
mov edx, aBigVar + 4
Hi32:
shr edx, 1
adc eax, 0
test edx, edx
jnz Hi32
bt
指令该指令可以对内存中的位串进行操作。你的aBigVar就是这样一个64位的位串。
xor eax, eax ; Result
mov ebx, offset aBigVar
mov ecx, 63 ; Bit index
Begin:
bt [ebx], ecx
adc eax, 0
dec ecx
jns Begin
-----
For all these codes, the number of 1-bits is in EAX.