使用 Test Operator MASM 组件计算 1 的数量

问题描述 投票:0回答:2

我有一个 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
assembly masm
2个回答
1
投票

您应该分别处理该值的上半部分和下半部分,因为此任务是位计数,其中您可以单独处理每个位。

此代码显示了一个概念,但我不擅长 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

0
投票

我的问题是,我不确定在使用 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.
最新问题
© www.soinside.com 2019 - 2024. All rights reserved.