汇编循环通过寄存器值的每一位

时间:2016-10-03 02:35:07

标签: loops assembly mips

我有一个寄存器$ t0,它存储了一些整数。例如,假设我将整数1100存储到它。该值的二进制表示为0000010001001100.当然,对于32位寄存器,它可以扩展到32位,但这很容易完成。

我试图在程序集中实现一个循环,它遍历寄存器值的每一位并检查它是1还是0.如何做到这一点?

也许我误解了寄存器的性质。据我所知,寄存器存储了32位数,是吗?这是否意味着每个位都存储在特定地址?

我尝试过使用shift作为寄存器并检查位但是失败了。我也查看了lb命令,但这会加载字节,而不是位。那么一个人会做什么?

3 个答案:

答案 0 :(得分:3)

一些基础知识:

大多数(全部?)移位指令将该位移出进位标志

大多数(所有?)CPU都有一个分支命令,跳转到进位标志集

上的位置

结合这个,您可以执行以下操作:

load register1,< the value to be tested >
load register2, 0

Lrepeat:
    compare register1 with 0
    jump if zero Lexit

    shift right register1
    jump no carry Lskip
    increase register2 
Lskip:
    jump Lrepeat

Lexit:                      ; when you end up here, your register2
                            ; holds the count of bit register1 had set

仍然可以进行一些优化:

Lrepeat:
    compare register1 with 0
    jump if zero Lexit
    shift right register1
    jump no carry Lskip       <-- note: here you jump ...
    increase register2 
Lskip:
    jump Lrepeat              <-- ... to jump again!
Lexit:

=====>

Lrepeat:
    compare register1 with 0
    jump if zero Lexit
    shift right register1
    jump no carry Lrepeat     <-- so you can optimize it this way
    increase register2 
Lskip:
    jump Lrepeat             
Lexit:

某些CPU有一个&#34;添加进位&#34; instuction, 例如6502:

ADC register,value      ; register = register + value + Carry flag

这可以用来避免分支(条件跳转),通过向register2每个循环添加0(加上Carry当然)

    shift right register1
    add with carry register2,0   ; may look weird, but this adds a 
                                 ; 1 if the carry is set, which is
                                 ; exactly what we want here
    jump Lrepeat

请注意,您不需要知道寄存器大小!你只需循环直到寄存器为1,这可以节省你很多时间,例如如果您的值类似于0000 0000 0000 0000 0000 0000 0001 1001

答案 1 :(得分:2)

在任何处理器上,设置一个循环来计算寄存器中的位数,在这种情况下为32.每次通过循环时,AND与1相关的寄存器然后将结果添加到累加器,并且最后移动寄存器。这给你设定位数。

精确的指令因处理器而异。要循环,你通常设置一个标签,递减一个计数器,然后执行一个名称如branch_not_equal_to为零的指令(BNZ,BNEQ0之类的东西)。并且将具有AND,ANDI(和立即)之类的名称。 ADD可能是ADD,ADC(带有进位)。这种转变将类似于ASR(算术右移)LSR(逻辑右移),您可能必须将其传递1才能说只移位一个地方。但是所有处理器都允许您以这种方式读出寄存器位。

答案 2 :(得分:0)

将要迭代的寄存器表示为R0。因此,例如,最低有效位为R0= 1011 0101

2)使用第二个清除的寄存器R1=0000 0001

3)AND R1R0然后右移R0(因此下一次迭代会检查R0的下一位)。

4)让R3成为第三个寄存器,递增1 IF AND操作得到1(也就是说,你在R0中遇到1 )。 ELSE,再次循环检查R0中的下一位。

您可以通过使用递减循环计数器来迭代整个32位或您选择的长度。

相关问题