Subroutines and Stacks (Problem with Return address)

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

Hi, i am running this code in order to add the data from the sram addreses 0x060 to 0x063 by using two subroutines (the first one adds the data of sram addresses into R1,R0 and the second performs the sign extension in the register R3). Although, in the second return(RET) from the ADDEXT subroutine the program counter returns to the first line of code instead in the point of where the first subroutine is rcalled.Can anyone help with debugging i think there is a mistake in the return address of the first RET in the subroutine ADDEXT, Thank you in Advance.

 

.include"m32def.inc"

.equ ram=0x060
.equ datalen=4
.def metritis=r16

ldi r19,low(RAMEND)
OUT SPL,R19
ldi r19,high(RAMEND)
OUT SPH,R19
ldi r18,0x0A
ldi metritis,datalen
ldi XL,low(ram)
ldi XH,high(ram)
loop:
    st X+,r18
    INC R18
    dec metritis
    brne loop
ldi XL,low(ram)
ldi XH,high(ram)
LD R22,-X

RCALL ADDEXT
ADDEXT:

    ADIW XH:XL,1
    RCALL SignExt
    ADD R0,R2
    ADC R1,R3
    RET

SignExt://Sign Extension
    ld R2,X
    CLR R3
    TST R2
    BRPL synex
    DEC R3
    synex:
    ret
telos:
    rjmp telos

Last Edited: Tue. Dec 4, 2018 - 09:00 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
 

.include"m32def.inc"

.equ ram=0x060
.equ datalen=4
.def metritis=r16

ldi r19,low(RAMEND)
OUT SPL,R19
ldi r19,high(RAMEND)
OUT SPH,R19
ldi r18,0x0A
ldi metritis,datalen
ldi XL,low(ram)
ldi XH,high(ram)
loop:
    st X+,r18
    INC R18
    dec metritis
    brne loop
ldi XL,low(ram)
ldi XH,high(ram)
LD R22,-X

RCALL ADDEXT     <----- what do you expect will happen upon return from this call???
ADDEXT:

    ADIW XH:XL,1
    RCALL SignExt
    ADD R0,R2
    ADC R1,R3
    RET

SignExt://Sign Extension
    ld R2,X
    CLR R3
    TST R2
    BRPL synex
    DEC R3
    synex:
    ret
telos:
    rjmp telos

 

Click Link: Get Free Stock: Retire early!

share.robinhood.com/jamesc3274

 

 

 

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

In the first RET from the first subroutine the program counter will move to the ADIW XH:XL,1 although in the second RET of the same subroutine the program counter will go at the top of the code as i have already mentioned maybe because at the first return(RET) the program counter had to go to the //RCALL ADDEXT and not //ADIW XH:XL,1.

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

MrSpikeHawk wrote:
although in the second RET of the same subroutine the program counter will go at the top of the code

 

How do you figure it will "return" to the top of code?

 

Only one return address was pushed on the stack by the RCALL,

the second time the RET is hit, there is no valid address on the stack to return too!

 

Try single stepping this in the simulator to see what happens after the second return.

 

Jim

 

Click Link: Get Free Stock: Retire early!

share.robinhood.com/jamesc3274

 

 

 

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

I runned the program with the Step into(F11) in order to see if both RET are working correctly but as i mentioned when the first RET (ADDEXT subroutine) is executed for the second time then the program counter returns in the first line of code instead of where it is called (RCALL (ADDEXT). As you correctly said in the second return of the first subroutine there is no valid address to return to however I can't find any possible solution to that problem.

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

try rjmp telos after the rcall.

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

Why are you heading into addext without using a call?

 

You call it, ok fine.  As soon as it is finished , you walk right back into it.  Put your subs somewhere else, like at the bottom of your code where you won't accidentally enter them.

 

you may like this

http://www.acorn-kernel.net/kernelunleashed/readarticle?ClassKey=ahJzfmFjb3JuLWtlcm5lbC1ocmRyDwsSB0FydGljbGUYybUQDA

 

When in the dark remember-the future looks brighter than ever.

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

I tried it and it doesn't work for some reason in the second return of the first subroutine the stack pointer loses the correct return adrress.

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

I tried it and it doesn't work for some reason in the second return of the first subroutine the stack pointer loses the correct return address.

 

both of your subs are fine in terms of you will call them and they WILL return, no stack problem

 

What command do you want to happen after RCALL ADDEXT ???!?   you will enter the sub without a call!!!!!  Obviously you can't do that.

After the rcall put in whatever commands you want to run thereafter.

 

You must provide an updated listing of all your changes, or it is not possible to diagnose further. 

 

 

 

When in the dark remember-the future looks brighter than ever.

Last Edited: Wed. Dec 5, 2018 - 12:51 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You can observe the operation on the simulator. Note that the stack pointer ‘points’ to the stack which is in ram. The return address is stored on the stack, not the stack pointer.

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

Thanks guys problem fixed the code operates correctly i had to RCALL the ADDEXT subroutine from another routine and as Raving mentioned i should have put commands after the RCALL ADDEXT in order to return at the right spot because previous after the RCALL ADDEXT there where no commands for the program counter to move on so that's why it went at the top of the code.