4 ms·
Stack allocation of return addresses is embedded in most ISAs- but stack allocation of local variables isn't (because that's not A Thing at the ISA level). Con
by XMPPwocky 8y ago
Stack allocation of return addresses is embedded in most ISAs- but stack allocation of local variables isn't (because that's not A Thing at the ISA level).
Consider, say, shadow stacks- local variables might end up living on a totally separate "stack" from the one "call" pushes onto and "ret" pops from, and one which the ISA has no idea about.
- tptacek 8y agoIn what sense is stack-relative addressing, PUSH, POP, and addition/subtraction on the stack pointer not ISA-level support for stack allocation of local variables?
- XMPPwocky 8y agoAddition, subtraction, and stack-relative addressing are, in most architectures I'm familiar with, generic- stack-relative addressing ends up just being a special case of register-relative addressing, and addition and subtraction are rather important instructions in their own right. PUSH/POP are more obviously "hey store your locals on the stack, kids", but on, say, x64, how often do you actually see a push instead of bp/sp-relative addressing? Most compilers seem to be much happier representing each stack frame as "a bunch of slots, some for things where the address is taken so it needs to be in memory, and others where I spill things into as needed". On ARMv7 (i don't know enough about v8 / AARCH64), "push"/"pop" are just stores/loads with postdecrement / postincrement. Is this lawyer-y? Sure. But I think it's still correct, and this being HN...
- pm215 8y agoThere's a reason 32-bit ARM has 'move base register down and then do some stores' and 'do loads and then move base register up' (stmdb and ldmia) rather than just plain old ldm and stm, and I'm pretty sure it's because it makes the entry and exit sequences for function calls with a stack shorter. (The ARM ISA doesn't privilege a downward growing stack, so you can use stmib and ldmda if you want your stack to grow upward; the Thumb ISA, however, does want a downward stack for push and pop.)
- XMPPwocky 8y agoThat's definitely a large part of it, but it also makes small memcpys nicer (load sizeof(foo)/4 registers from sourceptr with post increment, store them to destptr with post increment)
- physguy1123 8y agoOn x86, push/pop have dedicated hardware optimizations known as the stack engine which perform most of the rsp increments/decrements and passes those offsets into the decoder, instead of using executions slots on them. push/pop are also much smaller than the corresponding mov/add instructions. It's much more optimal to use a series of push/pops for smaller operations like saving registers before a call than to manually adjust and store onto the stack. While technically this is still incrementing/decrementing a register and storing, the amount of isa/hardware support for such things clearly demonstrates that the x86 isa and modern x86 hardware gives special treatment to the stack.