Home > front end >  Why am I getting this error in proteus: " Invalid opcode 0xFFFF at PC=0x002A"
Why am I getting this error in proteus: " Invalid opcode 0xFFFF at PC=0x002A"

Time:11-12

I wrote this code for avr atmega328P in assembly language. It turns on and off an LED using a push button, but in proteus I am getting this error:

Invalid opcode 0xFFFF at PC=0x002A

This is my code:

.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

Does anyone have a solution for it?

CodePudding user response:

Problem is here:

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.

You are branching to ledon resp. ledoff, which is just a conditional jump. But at the end of the respective blocks, you are using ret as if you called the code by means of [r]call.

The ret will pop 2 bytes from the stack and use these as a word-address to return to. The code target will very likely have uninitialized flach, which holds 0xff's, and two 0xff's are 0xffff which is not a legal AVR opcode.

To fix, you could rjmp Forever instead of ret, but it depends on what you want to achieve with the code.

  • Related