编写LC-3汇编代码,计算寄存器R0中“1”位的个数,并将结果放入寄存器R5中。例如,如果 R0 包含“0000 0001 0010 1100”,则结果 4 应存储在 R5 中。 我从各种来源获得了一些信息,但编码不适合正确的程序,而且我对 LC3 的了解不足以适应它。这是我到目前为止所拥有的:
.ORIG x3000
AND R5, R5, #0 ; R5 will act as a mask to
AND R5, R5, #1 ; mask out the uneeded bit
AND R1, R1, #0 ; zero out the result register
AND R2, R2, #0 ; R2 will act as a counter
LD R3, NegSixt ;
MskLoop AND R4, R0, R5 ; Mask off the bit
BRz NotOne ;
NotOne ADD R1, R1, #1 ; if the bit is 0 don't increment
ADD R5, R5, R5 ; shift the mask one bit to the left
ADD R2, R2, #1 ; Increment counter tells where we are
ADD R6, R2, R3 ;
BRn MskLoop ;
ADD R6, R2, R3 ;
BRn MskLoop ; Not done yet go back and
HALT ; check the other bits
NegSixt .FILL 000000100101100 ;
.END
我尝试稍微修改一下,但我确信我只是把它搞砸了......
我建议从第一原则开始工作,而不是仅仅修改整个程序的其他代码。 您很容易陷入不知道发生了什么或为什么发生的地方。
这里的方法是一次一位地查看数字并确定它是零还是非零。 所以,
0110 0110 0110 0110
&0001 &0010 &0100 &1000
===== ===== ===== =====
0000 == 0 0010 != 0 0100 != 0 0000 == 0
您可以看到有两个条目的结果不为 0(因此应该增加我们的计数寄存器)。
为了概括它,我们可以循环
for each digit
if (number & mask != 0)
increment counter
move "1" in mask to the left
这里唯一“棘手”的部分是推进面具。 在许多架构中,您可以使用移位指令,但这在 LC3 中不存在。 然而,向左移动只是乘以二,而乘以二只是向其自身添加一些东西(在您粘贴的代码中看到)。
我对LC3不熟悉。 但要计算设置的位数,请使用右移位寄存器命令将位移至进位标志的效果。
这是您需要的算法:
bitSet counter = 0
loop:
if (register == 0) {
jumpto end
}
right shift register
if carry is set {
increase bitSet counter
}
jumpto loop
end: