Yahoo Groups archive

AVR-Chat

Index last updated: 2026-04-28 22:41 UTC

Message

Re: [AVR-Chat] Some questions about the stack in an AVR ATmega168A

2011-11-24 by Jim Wagner

I don't know that it does, but its a core operational detail that I would expect some care to have been applied.

Jim Wagner

On Nov 23, 2011, at 1:33 PM, fireweaver wrote:

> 
> Does the AVR studio simulator truly mimic the AVR hardware exactly as 
> far as push and pop order?
> If it does, I suppose I could try that instead and do the final smoke 
> test when I get my hardware.
> 
> On 11/23/2011 3:16 PM, wagnerj@proaxis.com wrote:
> > The Instruction Set document tells you a little more, but not everything.
> > PUSH and POP are single byte operations, so the order is defined by your
> > code. Note that, for large flash memory AVRs, the return addresses will be
> > 3 bytes, not 2!
> >
> > I would simply make a very small test example, assemble it, and run it in
> > the software emulator-debugger. You can see for yourself exactly what is
> > happening with the stack. No great mysteries.
> >
> > Jim Wagner
> > Oregon Research Electronics
> >
> >> [1]
> >> While perusing the ATmega168A documentation, I discovered that NOWHERE
> >> is it mentioned
> >> concerning the byte order when a push or pop, call or return instruction
> >> is issued.
> >>
> >> So the first question is simple: When I call a subroutine, which byte
> >> of the programme
> >> counter is pushed first: The high byte or the low byte? The important
> >> reason is below.
> >>
> >>
> >> [2]
> >> The following question is a little more complex:
> >>
> >> I sometimes write subroutines (on other CPUs) that take either constant
> >> arguments
> >> or pointers to variables coded inline with the subroutine call.
> >>
> >> An example of such a call is shown below:
> >>
> >> CALL some_procedure
> >> .dw argument_1 ; constant or pointer argument
> >> .db "some_text",0 ; constant text argument
> >> ....
> >> return_point:
> >>
> >> What happens is this:
> >>
> >> The saved programme counter is popped into an index register. Bytes or
> >> words are
> >> read using the index and the index is incremented accordingly.
> >> When the procedure is finished, the index is already pointing to the
> >> correct return
> >> point, so doing an indirect jump to the contents of the index register
> >> returns you
> >> to the caller. Alternatively, I can push the index back onto the stack
> >> and do a
> >> normal return instruction.
> >>
> >> I'm thinking that such code would look like this:
> >>
> >> rcall some_procedure
> >> .dw argument_1
> >> .dw argument_2
> >> ...
> >> ...
> >>
> >> some_procedure:
> >> pop ZL ; I'm not sure if this is the right order.
> >> pop ZH ; when the stack is popped, it is back to the
> >> state it
> >> ; ; was in before the call.
> >> lsl ZL ; times two because LPM only extracts bytes.
> >> rol ZH ; we lose the high bit so only the lower 32K
> >> ; can be addressed
> >> ...
> >> procedure code goes here, using LPM reg,Z+ to load the registers
> >> ...
> >> adiw Z,1 ; bump return address past last byte of
> >> parameters
> >> lsr ZH
> >> ror ZL ; adjust back to word format
> >> ijmp ; return to caller
> >>
> >> The question is this: Is this code correct?
> >>
> >> Mostly, I use this with output routines that are called on to display
> >> large amounts
> >> of fixed text, such as instructions or help screens.
> >>
> >> [3]
> >> I have one final question that has nothing to do with stacks: When
> >> using AVRstudio,
> >> what is the correct programming protocol for use with an Arduino Mega
> >> 2560 board?
> >>
> >> fireweaver
> >>
> >>
> >>
> >>
> >> [Non-text portions of this message have been removed]
> >>
> 
> 



[Non-text portions of this message have been removed]

Attachments

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.