Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Original Arm had an ISA which didn't mandate a stack direction -- the stack pointer register (r13) was not special and it was only the calling convention that decreed that it was the stack pointer. The instruction set's LDM/STM (load/store multiple) insns supported both decrementing and incrementing the base register either before or after the accesses, which meant you could use them to implement an ascending stack if you wanted. However in practice the usual calling convention was "r13 is the stack pointer, and the stack descends". When the Thumb instruction set was added, this convention was baked into some instructions because the 16-bit opcode size didn't allow spending bits on the fully flexible "any base register, any direction, any way" operations the 32-bit Arm encoding used. In the M-profile variant of the architecture, the calling convention is heavily baked into the exception handling model (taking an exception/interrupt pushes a stack frame onto the stack) so the stack must be r13 and grow downwards. In the 64-bit Arm architecture, SP is no longer a general purpose register; I think in theory you could implement an ascending stack, but since the [reg+offset] addressing mode that allows the largest offset value takes an unsigned offset, accessing stack slots via [sp+N] is more natural than the [sp-N] an ascending stack would prefer.

Summary: original Arm gave the software the flexibility to implement an ascending stack, but in practice the stack was always descending, and more recent architecture changes assume this to a greater or lesser extent.



Thank you, I learned something new today!


It's not just the direction of the stack: in theory, there are two possible kinds of downwards-growing stacks, a 'full' SP points to the last used entry, whereas an 'empty' SP points to the next free entry. It all depends upon how you 'push' something on to the stack: do you decrease the SP before or after writing the data?

ARM let you choose either approach (making four different stack configurations in total!) - this flexibility is because ARM didn't have any specialised 'push' or 'pop' operations, you read/write to the stack using the normal load/store ops, which have a variety of addressing modes.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: