Assembly 组件(x86):数量为';01';十六进制数二进制码中的重复
我是汇编新手,我的任务是确定16b十六进制数二进制代码中的01重复次数。例如: 编号AB34为:1010 101100110100 由于01在上面以粗体显示,因此需要对其进行计数并将其存储在下面的代码中。诀窍是只使用逻辑指令,如AND、NOT、OR、XOR、moving(SHL、SHR)、ROR/RCR、ROL/RCL)和逻辑比较 以下是我所拥有的:Assembly 组件(x86):数量为';01';十六进制数二进制码中的重复,assembly,x86,binary,instructions,Assembly,X86,Binary,Instructions,我是汇编新手,我的任务是确定16b十六进制数二进制代码中的01重复次数。例如: 编号AB34为:1010 101100110100 由于01在上面以粗体显示,因此需要对其进行计数并将其存储在下面的代码中。诀窍是只使用逻辑指令,如AND、NOT、OR、XOR、moving(SHL、SHR)、ROR/RCR、ROL/RCL)和逻辑比较 以下是我所拥有的: name program data segment BR dw 0AB34H ; RESULT db 0 data ends
name program
data segment
BR dw 0AB34H ;
RESULT db 0
data ends
code segment
assume CS:code, DS:data
start:
mov ax, data
mov ds, ax
mov ax, BR
mov cx, 16
mov bx, 0
lwhile:
; something with logical instructions
loop lwhile
mov RESULT, bl
mov ah, 4ch
int 21h
code ends
end start
我假设在循环中需要做一些工作,通过一些寄存器(如bx)进行计数,然后移动到结果
我愿意接受任何建议,提前谢谢。您应该充分利用
和、cmp
和shr
说明。查找并尝试它们
总体而言,您的代码的结构如下:
mov ax, bx ; Current shifted value of BR
and ax, 03h ; Mask out (zero) all but the lowest two bits
cmp ax, 1 ; Check if the lower two bits are 01
jne next_bits ; Jump if nonzero (no, they are not 01)
; increment your counter here
next_bits:
...
将BR
值复制到工作寄存器(例如bx
)
检查01的最低两位,如果是,则递增计数器
将工作寄存器向右移位一位
转到2[执行此操作15次,因为BR
中有16位,您正在检查位对]
我给你留下一些细节。步骤2中的部分代码可能如下所示:
mov ax, bx ; Current shifted value of BR
and ax, 03h ; Mask out (zero) all but the lowest two bits
cmp ax, 1 ; Check if the lower two bits are 01
jne next_bits ; Jump if nonzero (no, they are not 01)
; increment your counter here
next_bits:
...
cmp
将检查已下移到低阶两位的当前位对是否为01
。要检查下一对位,请使用shr
指令。循环将继续移位一位,直到耗尽工作寄存器中的所有位。谢谢,我仍在弄清楚xor/和/和/和/不指令以及它们的实际作用。我来试试。@DušanJovanović这些指令就是他们所谓的“按位”指令。它们对相应的位进行操作not
是一元数(有一个操作数)并简单地反转所有位(0变为1,1变为0)和
产生一个结果,其位分别是两个操作数对应位的逻辑“与”(1和1产生1,0,任何值都是0)。等等…我想出来了,非常感谢!mov ax,BR mov cx,15 mov bx,0 while_loop:mov dx,ax和ax,03h xor ax,1 jne next add bx,1 next:mov ax,dx shr ax,1 loop while_loop mov RESULT,bl@DušanJovanović太好了。我很高兴你成功地完成了这项工作。有趣的问题是如何在不受教学选择限制的情况下有效地完成这项工作。例如,可以使用x=(x-1)&x;清除最低设置位代码>(leaax,[si-1]
/和si,ax
)。但是我现在想不出什么特别适合01
。或用于折叠重复运行的1
,以设置popcnt
。可能使用+lzcnt
循环,并检查您清除的位是否在前一位之后?因此,循环每设置一位运行一次,而不是16/32/64次。但不是每01场比赛一次。