assembly 按位操作改变位的顺序

l3zydbqr  于 5个月前  发布在  其他
关注(0)|答案(5)|浏览(54)

所以我的练习是改变位的顺序,所以:

7 6 5 4 3 2 1 0

字符串

3 2 7 6 1 0 5 4


我正在努力弄清楚这一点。我试图使用rol方法来旋转它们,这样我就可以得到3 2 1 0 7 6 5 4,这至少会更接近一点。但是超出范围的第一位不会通过第二位进行,我使用的示例是0000 1111
代码:

ldi  r16,$0F   - 0000 1111
       rol  r16  - 0001 1110
       rol  r16  - 0011 1100
       rol  r16  - 0111 1000
       rol  r16  - 1111 0000
       rol  r16  - 1110 000(0 - should be 1) - C was 0, now 1
       rol  r16  - 1100 0001


AVR的rol通过进位旋转;它是adc r16,r16的别名。(Online manual,或PDF)
更新我在练习中读到,我们应该翻转位5,4,3,2,然后使用移位和旋转来获得该顺序,因此这是我的代码

ldi  r16,$0F
       ldi  r17,$3C
       eor  r16,r17
       lsl  r16
       lsl  r16


所以r16是0000 1111 r17是0011 1100然后我用异或门得到r16 0011 0011,然后我想用lsl向左移位两次,所以我得到0110 0110,但是在我做第二次移位后,我得到:0011 0001而不是1100 1100,我不知道为什么会发生这种情况。
更新2前面的代码不工作,因为程序不知道在执行最后一个函数后该做什么,所以它回到了开始,给了我糟糕的结果,解决方案是end: rjmp end,它迫使程序一遍又一遍地无限跳转到这一行

ldi  r16,$0F
       ldi  r17,$3C
       eor  r16,r17
       lsl  r16
       lsl  r16
       end:  rjmp  end

kmb7vmvb

kmb7vmvb1#

使用T标志的较短版本可以是:

;Input: r16
;Output: r16

ror r16        ;r16 = 0 7 6 5   4 3 2 1
ror r16        ;r16 = 1 0 7 6   5 4 3 2
mov r17, r16   ;r17 = 1 0 7 6   5 4 3 2

ror r16        ;r16 = 2 1 0 7   6 5 4 3
ror r16        ;r16 = 3 2 1 0   7 6 5 4

bst r17, 7     ;T = 1
bld r17, 3     ;r17 = 1 0 7 6   1 4 3 2
bst r17, 6     ;T = 0
bld r17, 2     ;r17 = 1 0 7 6   1 0 3 2

andi r17, $3c  ;r17 = - - 7 6   1 0 - -
andi r16, $c3  ;r16 = 3 2 - -   - - 5 4

or r16, r17    ;r16 = 3 2 7 6   1 0 5 4

字符串
诺塔贝内酒店
你试图解决这个问题表明你还没有真正理解(低级)编程。
我建议你花一些时间来内化你正在学习的概念。

huwehgph

huwehgph2#

这个问题很老了,但我会做以下事情(在R16中输入和返回):

MOV R17, R16
SWAP R16
ANDI R16, 0b11000011              
                    
LSR R17
ROR R18                                  
LSR R17
ROR R18

ANDI R17, 0b00110000
SWAP R18

OR R16, R17
OR R16, R18

字符串

kh212irz

kh212irz3#

我们可以作弊看看avr-gcc会产生什么

uint8_t mix (uint8_t bits)
{
  return __builtin_avr_insert_bits (0x32761054, bits, 0);
}

字符串
生成的程序集为:

mix:
    swap r24
    mov r0,r24
    bst r0,2
    bld r24,4
    bst r0,3
    bld r24,5
    bst r0,4
    bld r24,2
    bst r0,5
    bld r24,3
    ret


所以编译器在10条指令中完成它,而不需要上层寄存器。它需要一个临时寄存器R 0。当输入与输出不重叠时,不需要临时寄存器,但它仍然需要10条指令。
有关文档,请参阅__bultin_avr_insert_bitsthe GCC documentation

mqkwyuun

mqkwyuun4#

伪程序集(字节存储在r1中):

mov r2, r1
mov r3, r2
mov r4, r3

shr r1, 4
shl r2, 2
shr r3, 2
shl r4, 4

and r1, 0x03
and r2, 0x0C
and r3, 0x30
and r4, 0xC0

xor r4, r3
xor r3, r2
xor r2, r1

字符串

u1ehiz5o

u1ehiz5o5#

我会用蛮力

ldi   r16, $0F (or any number, your input)
eor   r18, r18
mov   r17, r16
andi  r17, $C0
lsr   r17
lsr   r17
or    r18, r17
mov   r17, r16
andi  r17, $30
lsr   r17
lsr   r17
lsr   r17
lsr   r17
or    r18, r17
mov   r17, r16
andi  r17, $0C
lsl   r17
lsl   r17
lsl   r17
lsl   r17
or    r18, r17
mov   r17, r16
andi  r17, $03
lsl   r17
lsl   r17
or    r18, r17 (the output is `r18`)

字符串

相关问题