assembly - AVR 组件 - 比较后寄存器的旋转问题
问题描述
我正在尝试在汇编中编写一些代码,但无法解决在 cpi、cp 指令之后使用 ror、rol 指令的问题。我被困了一段时间,找不到任何关于它的东西。当我使用 cpi 时,我有一些较旧的代码,然后移动到程序的其他分支,做了一些指令,最后一个是旋转没有问题。如果它改变了某些东西并且它没有帮助,我尝试在旋转之前添加一些指令。我的目标是获得 254,253,251 等 r16 dec 值。只需旋转寄存器的内容。相反,我得到了 254,252,248。如果我不使用 cp 或 cpi,则不会出现问题。我是 asm 编程的新手,如果这是一个非常愚蠢的问题,我很抱歉。
ldi r16,0b11111111
ldi r17,0b00000001
ldi r18,0b00000001
ldi r20,0b00000000
start:
cp r18,r17
breq loop
loop:
inc r20
rol r16
rjmp start
解决方案
您的目标是获得以下值:
255 = 0xFF = 11111111
254 = 0xFE = 11111110
253 = 0xFD = 11111101
251 = 0xFB = 11111011
但是您使用一条rol
指令,将您的寄存器移位 1 并添加进位。进位一直为零,所以你总是加一个零。这会产生以下值:
255 = 0xFF = 11111111
254 = 0xFE = 11111110
252 = 0xFC = 11111100
248 = 0xF8 = 11111000
“问题”是cp
指令也使用进位位,因此它将清除进位位,因为r18
减号操作r17
不会设置进位(您的cp r18, r17
)。您的代码在没有 的情况下也可以工作,cp
因为进位在任何时候都不会被清除。
cpi
一种可能的解决方案是在调用之前使用 a rol
:
cpi r16, 255
rol r16
r16
现在,当 的内容低于时,您的进位将被设置255
,(cpi
执行操作r16
- 255
)。进位将被您使用,rol
并且您得到了正确的结果。一个积极的方面是,该解决方案每个周期只需要一个额外的时钟,因此它比分支指令或其他东西更智能。