首页 > 解决方案 > 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

标签: assemblyavr

解决方案


您的目标是获得以下值:

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并且您得到了正确的结果。一个积极的方面是,该解决方案每个周期只需要一个额外的时钟,因此它比分支指令或其他东西更智能。


推荐阅读