• AVR Freaks

Helpful ReplyHot!How is the value of _stack calculated

Author
toms
Senior Member
  • Total Posts : 131
  • Reward points : 0
  • Joined: 2006/03/07 18:06:24
  • Location: London, UK
  • Status: offline
2021/01/16 13:02:26 (permalink)
0

How is the value of _stack calculated

Hi all,
 
Sorry if this is a repeat post, the forum search is seemingly broken and wont find anything related to "stack" or "_stack".
 
Im wondering how the value of _stack is determined, or perhaps where it is determined. So far everything I can find seems to suggest it originates somewhere around the linking stage, either from the linker script, or perhaps internally within the linker itself?
 
But, I dont see anything in my linker script defining _stack directly, so perhaps it is formed internally somehow?
 
Basically I would like to try and find out why sp is initialised to a value of 0xa000fff8 by crt0 on my PIC (PIC32MX450F256). Ive seen some suggestions that the stack should be aligned to 8 bytes, so that somewhat explains the f8 bit.
 
But has something already been stored on the stack already between f8-ff, suggesting pre-decrement? Or can I consider that the f8 address is the first place I can push something onto the stack, which would mean post-decrement right? Ordinarily I would expect to see the stack pointer initialised to the very end of RAM, or 0xa0010000 on my PIC which has 64K of RAM, and use pre-decrement for push and post-increment for pop. So this has me confused a little.

Any insight appreciated.
 
Thanks!
post edited by toms - 2021/01/16 13:04:28
#1
moser
Super Member
  • Total Posts : 616
  • Reward points : 0
  • Joined: 2015/06/16 02:53:47
  • Location: Germany
  • Status: offline
Re: How is the value of _stack calculated 2021/01/18 02:57:02 (permalink) ☄ Helpfulby Jim Nickerson 2021/01/18 07:25:24
+3 (3)
You should be able to find that information in the Compiler User Guide and Linker User Guide, of your compiler version, which you forgot to tell us. Check the "docs" sub-directory, which is located next to the "bin" directory, in which you can find the compiler.
 
For xc32 it might probably be in Linker User Guide, section "9.6 Stack Allocation" and section "9.7 Heap Allocation", and Compiler User Guide, section "7.4 Stack" and section "15.3.3 Initialize Stack Pointer and Heap". Check if this helps you.
#2
toms
Senior Member
  • Total Posts : 131
  • Reward points : 0
  • Joined: 2006/03/07 18:06:24
  • Location: London, UK
  • Status: offline
Re: How is the value of _stack calculated 2021/01/20 10:55:06 (permalink)
0
Good point. I completely brain farted a bit and didnt even think to look in the linker manual. pink: pink
 
Ive had a bit of a look, but still dont really see the detail Im looking for in terms of how the initial value for _stack is calculated. But! I do see in the linker map file that this is its initial value, so its not like something has been pushed onto the stack to bring it down to there. So that answers one question and well, might just have to be enough for now, short of looking through the code to find out what its doing.
 
Thanks.
#3
jdeguire
Super Member
  • Total Posts : 622
  • Reward points : 0
  • Joined: 2012/01/13 07:48:44
  • Location: United States
  • Status: offline
Re: How is the value of _stack calculated 2021/01/20 11:35:03 (permalink)
+1 (1)
Normally, it'd be in the linker script, but Microchip modified the GNU linker to add what they call a "best-fit allocator". This tries to put sections that are not mapped specifically in the linker script wherever they'll fit around sections that are mapped. This is why you also won't see .text or .data sections in the linker scripts that come with XC32. I'm not 100% sure, but I would guess that '_stack' is set by this modified linker behind the scenes.
#4
moser
Super Member
  • Total Posts : 616
  • Reward points : 0
  • Joined: 2015/06/16 02:53:47
  • Location: Germany
  • Status: offline
Re: How is the value of _stack calculated 2021/01/21 02:49:10 (permalink)
+2 (2)
As jdeguire said, the linker decides the location:
9.6 Stack Allocation
By default, 32-bit linker dynamically allocates the largest stack possible from unused data memory. Previous releases used output sections specified in the linker script to allocate the stack.
 
The location and size of the stack is reported in the link map output file and the Memory-Usage Report, under the heading Dynamic Memory Usage.

 
For the pre/post-decrement question, I guess some of the assembler experts here will know the answer. I assume (!!!) that sp points to the last occupied location. So you need to decrement first, and then store stuff. That matches to various examples you can find with a search engine of your choice, for example https://stackoverflow.com/questions/15100476/mips-relevant-use-for-a-stack-pointer-sp-and-the-stack .
 
But maybe you can also just create a simple example with two .c files and two functions which call each other, and which have some local (volatile) variables, which are used before and after the call, and therefore need to get placed on the stack. And then just look at the assembly and see what it does with the sp register. Even if you do not really understand assembler, with that two-page "MIPS32 Instruction Set Quick Reference" you should probably be able to get the information you are looking for.
 
And maybe those 8 missing bytes are just because they want to avoid pointing to a memory location, which does not exist. Or there is something which occupies that piece of data memory. But this is just guessing.
#5
toms
Senior Member
  • Total Posts : 131
  • Reward points : 0
  • Joined: 2006/03/07 18:06:24
  • Location: London, UK
  • Status: offline
Re: How is the value of _stack calculated 2021/01/21 06:06:52 (permalink)
+1 (1)
Yep. Fortunately I am fairly familiar with assembly (written my fair share).
 
My tendency is to assume the same as you, as pre-decrement seems to be nearly universal for stacks that grow downwards (based on my experience so far).
 
And I think Im fairly sure that this is the case anyway. One such example I looked at in disassembly of my own code was something along the lines of

subtract from sp
store with positive offset from sp
 
function code
 
load with positive offset from sp
add to sp
return
 
As for the missing 8 bytes, nothing in the linker map file seems to point to a000fff8, so Im wondering if its some kind of alignment issue with another section. It seems the stack is positioned before RAM functions in memory, so I wonder if some empty sections related to that is just consuming a few bytes here and there.
#6
Jump to:
© 2021 APG vNext Commercial Version 4.5