2

What exactly does "reserve" mean in this context and how does decrementing the stack pointer reserve space on the stack? Does adjusting the stack pointer register have some side effect?

"Reserving space" sounds like memory allocation but memory for the stack is typically fixed and allocated up front so I don't think that's what it means.

I think it just means that we're telling someone else not to use our stack space and that someone else simply reads the stack pointer register and by convention knows that it shouldn't clobber anything above that. If that's right then who is that someone else? Subsequent function calls? The OS?

Praxeolitic
  • 22,455
  • 16
  • 75
  • 126
  • 1
    Your third paragraph is right. Anything below stack pointer (assuming it grows down) is fair game as a matter of convention. – Seva Alekseyev Nov 10 '15 at 16:58
  • @SevaAlekseyev Fair game for who to use? Functions? OS? Anyone else? Go ahead and post an answer if you feel like fleshing out your answer-comment. ;) – Praxeolitic Nov 10 '15 at 17:00
  • 1
    Functions that your function is calling. Note how your function is not supposed to clobber anything below the stack pointer the way it was on entry. The functions your function will call will follow the same convention. Also, interrupt handlers. – Seva Alekseyev Nov 10 '15 at 17:41
  • Learn what push and pop do exactly http://stackoverflow.com/a/33583134/895245 and what C functions compiles to. Then it will be clear. – Ciro Santilli OurBigBook.com Nov 10 '15 at 18:26
  • @SevaAlekseyev: In modern OSes, IRQ handlers use separate kernel stacks (for security reasons: another thread of the user process could modify the stack memory being used by a kernel function!!). However *signal* handlers can asynchronously use space below the stack pointer at any time. (In the Linux/Mac (SysV) 64bit ABI, there's a "red zone" of 128B below `rsp` that's safe from asynchronous clobbering by signal handlers or whatever, so leaf functions that don't need more than that can avoid having to adjust the stack pointer, saving a couple instructions.) – Peter Cordes Nov 10 '15 at 20:27

1 Answers1

3

Just the fact that the stack pointer is now a bit lower has reserved the space. Functions called recursively and so on will (hopefully) respect the reservation by not writing to the memory reserved that way (there is nothing really stopping them, but if they do it then they're broken).

Stack space not allocated in that way can in principle be written to, but since it's a free-for-all that's usually not done (in particular it may not, and probably won't, survive a function call, which could easily allocate it and write all over it, and signal handlers use this space if it's not part of the red zone), the big exception is the Red Zone on x64 (not on Windows) in leaf functions.

It is a type of allocation, it's allocation within a fixed size buffer, but then so is everything, ultimately you can only allocate so much memory no matter what. It's just more limited.

harold
  • 61,398
  • 6
  • 86
  • 164
  • Good point. I should have specified *dynamic* memory allocation. – Praxeolitic Nov 10 '15 at 17:10
  • @Praxeolitic well it's also dynamic, it's done at runtime when functions are called, not fixed at compile time – harold Nov 10 '15 at 17:16
  • 2
    Also the stack size might not be fixed up front, the OS might grow it on demand as needed. – Jester Nov 10 '15 at 17:16
  • 1
    It's not function calls that are the problem. It's asynchronous clobbering by signal handlers that makes space below the stack pointer (or below the red zone) unsafe to use for anything. Even leaf functions need to reserve any space they use. (The red zone counts as already-reserved.) Also note that only the SysV ABI has a red zone. The 64bit Windows ABI doesn't. – Peter Cordes Nov 10 '15 at 20:33
  • @PeterCordes yes, signal handlers too, I thought that was too far for OP who is clearly a beginner. I disagree that function call are not a problem though, even the call itself will mess stuff up, there's no way to avoid that (the rest of the function might cooperate I suppose), and calling the red zone reserved is just playing with semantics – harold Nov 10 '15 at 20:51
  • 2
    @harold: right, what I said in my comment didn't really reflect what I was thinking. I think the fact that a signal handler can come along and modify memory below `rsp` at *any* time, asynchronously, is an important point, though. Otherwise leaf functions wouldn't have to reserve memory. The OP's last paragraph is asking about what things can come along and use memory below the stack pointer, so yes, the answer is further function calls and "the OS" (in the form of signal handlers). – Peter Cordes Nov 10 '15 at 20:55
  • It might be worthwhile to explain that traditional stack allocation is a type of bump pointer allocation (which can also be used, e.g., for the nursery for generational garbage collection). –  Nov 11 '15 at 03:46