5 ms·
There is no difference inside the computer between those concepts. For convenience, many architectures have a single assembly instruction for taking one regist
by geofft 8y ago
There is no difference inside the computer between those concepts.
For convenience, many architectures have a single assembly instruction for taking one register (called the "stack pointer"), adjusting it by a word, and moving a register to the address at that word, and a corresponding instruction to move data back to a register and adjust it in the other direction. That's the extent of the abstraction. You can implement it with two instructions instead of one, and then you get as many stack pointers as you want. Zero, if you want.
There is no "heap" on modern OSes. There used to be a thing called the program break, beyond which was the heap. It's almost meaningless now. You ask for an area of virtual memory via mmap or equivalent; it is now one of several heaps you have.
And you can pass around pointers from all your stacks and all your heaps in the same ways, as long as they remain valid.
You need to understand this in order to understand how thread stacks work (you typically allocate them via mmap or from "the heap"); how sigaltstack works and why you need it to catch SIGSEGV from stack oveflows; how segmented stacks (as previously used in Go and Rust) work; how Stackless Python works; how to share data structures between processes; etc.
- jpindar 8y agoFor your definition of 'computer', perhaps. Many microcontrollers have the stack defined by the hardware.
- simonh 8y agoLeaning how microcontrollers work is not the same as 'learning how the computer works' in general, which is the subject at hand.
- geofft 8y agoAnd some, such as RISC-V, have no predefined stack pointer at all. (Push and pop are implemented by doing them manually; call is implemented by the jump instruction optionally taking an argument for a register to use as the stack.) C, at best, teaches you the C abstract machine, which supports both of these concrete implementations equally well.
- tptacek 8y agoI think this is lawyering a bit. There might not be a "heap", per se, but there is stack allocation (which is embedded all the way into the ISA) and "everything else". You can, after all, build a simple "heap" on top of an adequately large static buffer. Since this is a distinction that is very important both for performance in high-level languages and for correctness in C, and one C forces you to think about and makes plain without having to reason through escape analysis and closures, I think the previous comment's point is well taken.
- XMPPwocky 8y agoStack 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...
- drb91 8y agoThey may not be distinguished at the instruction level, but if you’re trying to argue it’s not a useful thing to teach you’ve lost me. Dynamic vs static vs scoped (stack) allocation is incredibly important to reasoning about basic programs.
- Sir_Cmpwn 8y agoLike I established in my opening comment, C tells you how software works, not how hardware works. Regardless, you're still wrong in several ways here. Making it out of several discontinuous regions of memory doesn't make your heap less of a heap. Most architectures also provide instructions for loading data from the stack and optimize for this purpose, using their caches more efficiently and making design decisions which have clearly been influenced by the C (or System V) ABI.