【问题标题】:Why I am getting this error in proteus Invalid opcode 0xFFFF at PC=0x002A为什么我在 PC=0x002A 的 proteus Invalid opcode 0xFFFF 中收到此错误
【发布时间】:2022-11-12 11:14:30
【问题描述】:
我用汇编语言为 avr atmega328P 编写了这段代码,以使用按钮打开和关闭 LED,但在 proteus 中我收到此错误:Invalid opcode 0xFFFF at PC=0x002A
这是我的代码,
.INCLUDE "M328Pdef.inc"
ldi r16,HIGH(RAMEND)
out SPH, R16
ldi r16,LOW(RAMEND)
out SPL, R16
start:
ldi r16,0xFF
out DDRB,r16
ldi r17,0x00
out DDRD,r17
ldi r21,0x00
ldi r23,0x01
Forever:
in r20,PIND
cp r20,r21
BREQ ledon
cp r20,r23
BREQ ledoff
rjmp Forever
ledon:
ldi r22,0x01
out PORTB,r22
ret
ledoff:
ldi r24,0x00
out PORTB,r24
ret
有人有解决方案吗?
【问题讨论】:
标签:
assembly
microcontroller
avr
atmega32
【解决方案1】:
问题在这里:
BREQ ledon ; branch
cp r20,r23
BREQ ledoff ; branch
rjmp Forever
ledon:
ldi r22,0x01
out PORTB,r22
ret ; return from subroutine, but never used [R]CALL.
ledoff:
ldi r24,0x00
out PORTB,r24
ret ; return from subroutine, but never used [R]CALL.
您正在分支到 ledon resp。 ledoff,这只是一个条件跳转。但是在各个块的末尾,您使用的是ret,就好像您通过[r]call 调用了代码一样。
ret 将从堆栈中弹出 2 个字节并将其用作要返回的字地址。代码目标很可能有未初始化的 flach,它包含 0xff,两个 0xff 是 0xffff,它不是合法的 AVR 操作码。
要解决此问题,您可以使用rjmp Forever 而不是ret,但这取决于您想用代码实现什么。