Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Relation between endianness and stack-growth direction

Is there a relation between endianness of a processor and the direction of stack growth?

For example, x86 architecture is little endian and the stack grows downwards (i.e. it starts at highest address and grows towards lower address with each push operation). Similarly, in SPARC architecture, which is big endian, the stack starts at lowest address and grows upwards towards higher addresses.

This relationship pattern is seen in almost all architectures. I believe there must be a reason for this unsaid convention. Can this be explained from computer architecture or OS point of view? Is this for some optimization in the microcode inside the processor? Does this aid the kernel in some way? Or may be other reason?

Thanks in advance!

like image 364
user31986 Avatar asked Aug 27 '13 15:08

user31986


1 Answers

Stack growth direction is orthogonal to integer endianness.

There is zero connection between the order of bytes within a wider integer (word), and whether a stack push adds or subtracts from the stack pointer. As far as a push is concerned, storing the data is a single operation.

Mapping a register-width integer to bytes in memory uses different hardware from the stack-pointer inc/dec logic; I assume the normal design would be to use the same hardware that non-push/pop stores/loads go through, and just treat the store from a push like any other store of a "word". Not any kind of weird one-byte-at-a-time thing that increments the stack pointer one by one.

This relationship pattern is seen in almost all architectures.

Uhhhh, not really. Many modern RISC ISAs (e.g. MIPS, PowerPC, ARM) have selectable endianness1, and that's not connected to stack-growth direction.

What is the direction of stack growth in most modern systems? shows that on most mainstream systems, the stack growth direction is typically down either by convention or by requirement, including on big-endian systems.

According to the answer on that Q&A, mainstream OSes / ABIs on SPARC choose to grow the stack downward. Upward is an option on SPARC, but the normal choice is downward like other systems.

Can this be explained from computer architecture or OS point of view?

What we can explain is that downward is the de-facto standard. IDK why SPARC bothered to make upward an option. Stack at the top of available memory, with static code/data at fixed addresses at the bottom, is obviously natural without paging / virtual memory. https://softwareengineering.stackexchange.com/questions/137640/why-does-the-stack-grow-downward

So that's how we got here.

On some ISAs, e.g. MIPS, the stack-grown direction is purely determined by software. The hardware doesn't implicitly / asynchronously use the stack, and there aren't push/pop instructions that make it more efficient to go one way or the other.

But the normal choice is still downward.

Other ISAs are like x86 where async interrupts push stuff onto the kernel stack, forcing one direction. Or at least have a bias in one way, by providing efficient push/pop for one direction (like ARM Thumb, and like x86's push/pop). Not to mention x86's call/ret instructions that push/pop a return address instead of just writing a link register.

If there is no choice of direction, the one fixed direction is downward in most ISAs, but @chux comments that PIC24 has upward stack growth.


I'm pretty sure there are big and little-endian examples of all of these, or at least bi-endian systems that can be configured as big or little-endian.


Footnote 1: Some specific ARM or MIPS CPUs have their endianness hard-wired, not runtime selectable, because it's basically a useless feature and waste of silicon for embedded. Not sure about modern POWER hardware; the Godbolt compiler explorer (https://godbolt.org/) has both PowerPC64 and PowerPC64le compilers, but that doesn't tell us whether they're both still relevant.

like image 170
Peter Cordes Avatar answered Oct 19 '22 08:10

Peter Cordes