assembly 如何将一个数的位从一个寄存器移到另外八个寄存器

n1bvdmb6  于 2022-11-24  发布在  其他
关注(0)|答案(3)|浏览(210)

我正试着把起始寄存器的位移到八个连续的寄存器中。我刚开始用汇编语言写,所以我真的不知道该怎么做。
我尝试使用rol和lsr指令。但是我的循环只是反转了位。我可以在循环中间将注册表从r18改为r19吗?

.equ sequen = 0x10001011

ldi r17 
ldi r16, 0x8

next: lsr r17
rol r18    

             ;is there a way to move  
            ;to next register, not    
            ; inc its value?
dec r16
brbc 1, next
rjmp pc
t98cgbkg

t98cgbkg1#

就像彼得·科德斯说的,这是可能的。比如说

.equ sequen = 0b1000_1011

        ldi r17, sequen
        ldi r16, 0x8

        ldi zl,18     ;Z (ZH:ZL) is used as indirect address register (pointer in C terminology)
        ldi zh,0      ;this two instruction set Z to 18 - address for first value. See AVR memmory map for details
        clr r0        
next:
        bst r17,0   
        bld r0, 0
        st  z+, r0    ;save result to register and increase address (18, 19, ...|
        lsr r17
        dec r16
        brne next
        rjmp pc
3vpjnl9f

3vpjnl9f2#

我正在尝试将起始寄存器中的位移动到八个连续的寄存器中。
只需展开该循环:

lsr r17 $ clr r18 $ rol r18
lsr r17 $ clr r19 $ rol r19
lsr r17 $ clr r20 $ rol r20
lsr r17 $ clr r21 $ rol r21
lsr r17 $ clr r22 $ rol r22
lsr r17 $ clr r23 $ rol r23
lsr r17 $ clr r24 $ rol r24
lsr r17 $ clr r25 $ rol r25

$是GNU汇编程序支持的行分隔符。
或者,您可以将相应的位存储在T标志中,然后将其加载到目标寄存器。

bst r17,0 $ clr r18 $ bld r18,0
bst r17,1 $ clr r19 $ bld r19,0
bst r17,2 $ clr r20 $ bld r20,0
bst r17,3 $ clr r21 $ bld r21,0
bst r17,4 $ clr r22 $ bld r22,0
bst r17,5 $ clr r23 $ bld r23,0
bst r17,6 $ clr r24 $ bld r24,0
bst r17,7 $ clr r25 $ bld r25,0

还有另一种方式是根据r17的值跳过,这也是每位消耗3条指令:

clr  r18
sbrc r17, 0
inc  r18
clr  r19
sbrc r17, 1
inc  r19
clr  r20
sbrc r17, 2
inc  r20
...

GNU汇编器允许将其编写为扩展到24条指令的重复:

.irp reg, 0, 1, 2, 3, 4, 5, 6, 7
    lsr r17
    clr 18+\reg
    rol 18+\reg
    .endr

因此可能需要检查您的汇编程序是否支持此类快捷方式。
是否可以在循环中将注册表从r18更改为r19?
不。"经典" AVR可以间接寻址通用寄存器,因为它们被Map到内存地址0x0..0x1f,但我强烈反对这样的黑客行为。

kxkpmulp

kxkpmulp3#

我在伪代码中使用的模式如下。
从寄存器V开始,寄存器V保存8位值,例如0xe4 1110 0100
将寄存器B设置为位模式0x01,结果进入R0至R7

((V & (B << 0)) >> 0) & 0x01 goes into R0 (the bottom bit, ie bit 0) 0x00
((V & (B << 1)) >> 1)& 0x01 goes into R1 (the next bit, ie bit 1)   0x00
((V & (B << 2)) >> 2)& 0x01 goes into R2                            0x01
((V & (B << 3)) >> 3)& 0x01 goes into R3                            0x00
((V & (B << 4)) >> 4)& 0x01 goes into R4                            0x00
((V & (B << 5)) >> 5)& 0x01 goes into R5                            0x01
((V & (B << 6)) >> 6)& 0x01 goes into R6                            0x01
((V & (B << 7)) >> 7)& 0x01 goes into R7                            0x01

这可能是一个循环,你左移初始位模式,然后右移结果的位移值,然后你把结果移动到内存位置偏移的位移值。
在循环结束时,incr shiftValue和与结束值的比较(或减去)有条件地跳转到循环开始。

loop:
  ((V & (B << ShiftValue)) >> ShiftValue) goes into Memory+Shiftvalue
  ShiftValue subtract 0x80
  jump when zero loop:

相关问题