Proteus运行ATmega328P汇编代码时出现‘Invalid opcode 0xFFFF at PC=0x002A’报错求助
解决AVR汇编代码中"Invalid opcode 0xFFFF at PC=0x002A"错误
错误原因
你遇到的Invalid opcode 0xFFFF错误,本质是程序执行到了无有效机器码的内存区域,问题出在ledon和ledoff段的ret指令上:
BREQ是相对跳转指令,直接跳转到标签位置执行代码,并非通过call指令调用子程序;ret指令的作用是从子程序返回,它会从栈中弹出call指令保存的返回地址。但你的代码里没有用call调用ledon/ledoff,栈中存储的是初始化时的RAMEND值,执行ret后PC会跳转到这个无效地址,触发错误。
修正方案
把ledon和ledoff段的ret替换为rjmp Forever,让执行完LED控制逻辑后直接回到主循环:
.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 rjmp Forever ; 替换原ret指令 ledoff: ldi r24,0x00 out PORTB,r24 rjmp Forever ; 替换原ret指令
额外提示
如果后续需要用子程序调用的方式实现功能,才应该用call+ret的组合,比如把BREQ ledon改成rcall ledon,此时ret就能正确返回跳转前的位置。
内容的提问来源于stack exchange,提问作者Muhammad Umar
相关产品推荐
相关产品推荐

