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-23 by fireweaver

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]
>>

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.