Resetting the stack pointer

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

Suppose the 'main' part of your program calls a subroutine by using the stack (RCALL and RET).

Then the sub is calling another sub by using RCALL.

Is it then possible to make a RJMP directly from the second sub to the main program by resetting the stack in 'main' ?

My problem is how to reset the stack.

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

What you describe is technically possible but it would be a quite awful way to structure the code. Why on earth would you want to do it?

To set the stack at any time you OUT to SPL and SPH locations.

Cliff

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

The "proper" way to do this is to pop all your return addresses off the Stack from inside your subroutine then RJMP out, back to the Main Program.

However, your idea would also work under certain circumstances. If it's a simple program you could even jump right to start and reinitialize your stack to top-of-memory if you are sure there is nothing else of importance on the Stack.

These techniques are outside "normal" programming practice, so be careful. Make sure you documents what is going on very well if you (or someone else) ever needs to go back and examine it.

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

Thanks for suggestions!

>Why on earth would you want to do it?

The subroutine is a software PWM, and it is calling a process subroutine at precalculated times. The process subroutine run its program and return to PWM by RET-command.

But if there was a stop-command from the user in the process part, the subroutine running PWM might be disturbed during the return, so it would be better returning directly to the main program, resetting the PWM outputs and so on.

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

I've used this approach for handling errors. Go 2 or 3 level deep in calls, and if you have an error, report the error and fallback to the main loop by popping off the stack. The reason for doing this saves having to test for a error condition each time you return from the previous call. Yes you have to be carefull and it won't work in all cases.

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

"pop all your return addresses off the Stack from inside your subroutine then RJMP out"

I believe jumping out and then pop the adresses out in the main might work. This way, main can continue to run (displaying user output and so on).

Resetting the processor is also an option, then it all starts over again :-)

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

Poping the stack works only if you know how many bytes to pop. If the code path is always the same, then there is no problem. But if, say, the routine is called from more than one place, then the number of bytes may vary. One possible solution is to store the value of the stack pointer of the level that you want to return to. Then you could set the stack pointer to that value, and adjust it down so that it points to the return address of the top level call.

Regards,
Steve A.

The Board helps those that help themselves.

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

If you RJMP to the second routine, rather than an RCALL, then when the second routine does a RET, it will return to the main program right after the RCALL to the first routine, with no need to adjust the stack..

Be sure to clearly document this in your code.

Laurence Boyd II

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

>If you RJMP to the second routine, rather than an RCALL

Good idea. But the sub must return to the other sub as usual most of the time except when the stop-command occur. I did some testing just initiating the stack pointer adress after return, and it seems to work.

The program is just stright forward: Main, sub1,sub2,sub1,sub2 and so on.

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

If you know what is on the stack above the address for sub1 to return to main is only the address for sub2 to return to sub1, you could pop this last address from the stack before doing the RET. This address is 2 bytes for up to 128K bytes of program memory, 3 bytes for larger.

Laurence Boyd II