simple Icall question

Go To Last Post
3 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello:

I am trying to make a jump (to subroutines) using ICALL. I am assuming the corresponding return instruction is simply ret. is this true?
My code seems to lock up--if I kill the Icall all is well!! any thoughts?

ldi ZH, high(actions*2) ;get address of command check string
ldi ZL, low (actions*2)
mov temp, routine_to_do ;specify which subroutine to run
lsl temp ;mult by 2 to for word address
add ZL,temp ;point to table address (base +2*cmdnum)
clr temp
adc ZH,temp ;propogate carry
icall ;execute valid cmd subroutine
more code--seems to never come back here/locks up

routine0: ret ;right now routines do nothing but return
routine1: ret
actions: dw routine0, routine1

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You are right that RET is correct. But I don't think you execute routine0 or routine1 in the first place. First you are loading Z with the start address of the list (actions). Then you offset Z with routine_to_do. So far so good. But then you make the icall, which means the program tries to execute the corresponding address in your list as code.

Before icall, you will need to load Z with the content of the list. Insert this just before your icall (if you are using some sort of mega AVR):

lpm temp, Z+
lpm ZH, Z
mov ZL, temp

And then you can do the icall.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks---this worked purrrfectly---I really appreciate it!

Hoyt

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!