所以我的练习是改变位的顺序:
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)
rol r16 - 1100 0001
更新 我在练习中读到,我们应该翻转位 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
使用
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
诺塔贝尼
您尝试解决此练习表明您尚未真正理解(低级)编程。
我建议您花一些时间来内化您正在学习的概念。
我会用暴力来做到这一点:
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`)
伪汇编(字节存储在
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
这个问题很旧,但我会做以下事情:
//Assuming R16 contains the data bits
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
//R16 contains the result