Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 我的ARM汇编代码在32位寄存器中计算0的数量有什么问题_Assembly_Count_Arm_Counter_Bit - Fatal编程技术网

Assembly 我的ARM汇编代码在32位寄存器中计算0的数量有什么问题

Assembly 我的ARM汇编代码在32位寄存器中计算0的数量有什么问题,assembly,count,arm,counter,bit,Assembly,Count,Arm,Counter,Bit,我已经设置好了,所以只要有一个,它就会递减,但它不太管用,我也不知道为什么你的设计思想有点过于复杂,这让你很难正确使用代码。我不知道你到底为什么认为在无符号右移之后进行x>>1

我已经设置好了,所以只要有一个,它就会递减,但它不太管用,我也不知道为什么你的设计思想有点过于复杂,这让你很难正确使用代码。我不知道你到底为什么认为在无符号右移之后进行x>>1 您可以利用标志来获取关于顶部位的信息,但不需要cmp。使用左移位或添加设置标志的相同,并使用减号条件测试S标志,以找出结果的高位

或者查看C标志以查看位移位,但是在寄存器变为零后的最后一次迭代之后,您需要对C标志执行一些操作。这很好,您可以剥离最后一次迭代

如果使用依赖于符号位的条件,则使用右移时,lsr无法工作

与分支不同,您肯定希望利用ARM对任何指令的谓词执行,但在助记符中附加一个条件。subm是一种sub,如果MI条件为false,则为no op

当然,如果您关心性能,8位查找表可能是实现popcnt的一个好方法,或者有一个bithack公式,ARM可能可以通过其桶形移位器非常有效地实现

顺便说一句,ARM不像其他架构(如x86的popcnt)那样具有硬件位计数指令

在计算机程序中,小数字通常很常见。左移位将需要约30次迭代,才能将设置了任何低位的数字的所有位移出。但是对于像7这样的小数字,右移可以在几次迭代中完成,只有低3位的设置


如果您的输入通常会清除一些连续的高位,那么我为这个答案编写的左移位循环是最糟糕的。

不清楚您的算法是什么。我不知道blt如何帮你检查一点。我建议你简单地做和r3,r0,1;子r1、r1、r3;LSR0,r0,1;b循环。@Jester:blt可以在左移位后检查符号位,如添加r0、r0、r0/cmp/addlt r1、r1、1。或者更好,使用adds/addmi左移并设置标志,以便在设置位时增加计数器。或者我忘记了non-negative的条件名称,它与减号相反,可以与条件add一起使用来计算零。或者,如果你想在移出所有位后停止循环,你确实需要从32中减去。我认为你可以用一种鬼鬼祟祟、高效的方法来计算零:把寄存器移到一个方向或另一个方向都无所谓;如果设置了进位,则递增计数器,然后在寄存器为零时离开循环。这计算1位的数量,当它们全部移出并计数时停止。然后从32中减去1得到你的答案。@DaveM同意这是一个很好的方法,但一点也不认为这是鬼鬼祟祟的。答案很好。需要注意的是,ROR和RRX确实或可能影响进位标志,因此,如果您的条件依赖于进位标志,则使用右移不起作用这一点并不完全正确,尽管无可否认,它们在这种情况下没有多大用处。这就是说,也许一个RRX和其他代码都经过精心设计,这样在进入RRX时,进位标志就可以保证为零,这样就可以使它工作了…@cooperised:是的,轮换很有趣,但是寄存器永远不会变为零。无论如何,请注意,我说过,如果您正在查看符号位/标志,则LSR无法工作。OP在移位后使用cmp,销毁任何C。因此,是的,LSR将低位移位到进位是好的,在循环退出后使用最后的add或sub。与subc r0、r0、1/lsrs r1、r1、1/bne类似,然后是subc r0、r0、1/ret。或者如果设置了C,则条件的正确名称为true。我知道ARM在某些条件名称上与x86不同。同意。如果您确保每次使用前清除进位标志,则使用RRX时寄存器将变为零。也许不是最可读的代码,但却是可行的:-D
test:
       mov r1,#32

loop:
       cmp r0, #0

       beq done
       mov r3, r0 
       lsr r0, r0, #1
       cmp r0, r3
       blt sub
       b done
sub:

      sub r1, r1, #1
      b loop
done:

       mov r0, r1
       mov  pc, lr
test:
       movs  r1, r0            @ copy and set flags
       mov   r0, #32

          @ loop invariants:
          @ r0 = return value
          @ r1 = input
          @ flags set according to the current value of r1
.loop:                         @ do {
      submi r0, r0, #1    @ predicated subtract: if(high_bit_set(r1)) r0--;
      adds  r1, r1        @ left-shift by 1 and set flags
      bne  .loop          @ keep looping until there are no set bits
                               @ }while(r1<<=1);

      mov  pc, lr        @ or bx lr