34

From Wikipedia:

In computing, a red zone is a fixed-size area in a function's stack frame beyond the return address which is not preserved by that function. The callee function may use the red zone for storing local variables without the extra overhead of modifying the stack pointer. This region of memory is not to be modified by interrupt/exception/signal handlers. The x86-64 ABI used by System V mandates a 128-byte red zone, which begins directly after the return address and includes the function's arguments. The OpenRISC toolchain assumes a 128-byte red zone.

From the System V x86-64 ABI:

The 128-byte area beyond the location pointed to by %rsp is considered to be reserved and shall not be modified by signal or interrupt handlers. Therefore, functions may use this area for temporary data that is not needed across function calls. In particular, leaf functions may use this area for their entire stack frame, rather than adjusting the stack pointer in the prologue and epilogue. This area is known as the red zone.

  • Given these two quotes, is the red zone above the stacked return address or below the stacked return address?

  • Since this red zone is relative to RSP, does it move downward with each push and does it move upward with each pop?

Michael Petch
  • 46,082
  • 8
  • 107
  • 198
Sep Roland
  • 33,889
  • 7
  • 43
  • 76
  • 9
    maybe interesting? http://eli.thegreenplace.net/2011/09/06/stack-frame-layout-on-x86-64/. It seems to clarify the issue? The stack grows 'downwards' (lower address) in memory. The 'red zone' is the area 'down' (lower memory address) from the current 'stack pointer'. – Ryan Vincent Jun 26 '16 at 19:15
  • 2
    Interesting indeed. As always: a picture is worth a thousand words! – Sep Roland Jun 26 '16 at 19:32
  • @FUZxxl I see you removed the *C++* tag. I only added it because SO had suggested me to do so. – Sep Roland Jun 26 '16 at 19:36
  • @SepRoland The suggestions are not always correct. Only add tags that describe what your question is about. If it's not about C++, then the suggestion is wrong. – fuz Jun 26 '16 at 19:38
  • Note that, because of the red zone and other things, pushes and pops aren't usually emitted. – Jonathon Reinhart Jun 26 '16 at 19:41
  • 9
    The description on Wikipedia sounds totally wrong. *begins directly after the return address and includes the function's arguments* is total nonsense. On function entry, `%rsp` points at the return address, so yes the red-zone begins below there until the function modifies `%rsp`. Args are above the return address. They're safe from async modification for the normal reason (being above %rsp), not because of the red zone. That part of the Wiki article is flat out wrong, and I don't see any valid interpretation. – Peter Cordes Jun 26 '16 at 22:04
  • related recent question: http://stackoverflow.com/questions/37941779/why-do-we-need-stack-allocation-when-we-have-a-red-zone. Is that a duplicate? The answer there answers this question, right? – Peter Cordes Jun 26 '16 at 22:22
  • 1
    @PeterCordes It's precisely that answer by Cody Gray that made me doubt because of the discrepancy between the negative offset (-8) to RSP and the comment for the 32-byte scratch area. I see you've bugfixed it. It makes sense now. – Sep Roland Jun 27 '16 at 13:03
  • 1
    @SepRoland: ouch. Documentation bugs can be really confusing. I'm kind of a fanatic about making sure answers don't include any wrong info, even if their answer to the main question is ok. (e.g. [this inline asm that had unsafe constraints, where the only way to get my point through the OP's thick head was to write a whole answer](http://stackoverflow.com/a/38040651/224132).) Anyway, glad to hear that my attention to detail is justified. Too bad I didn't notice that earlier, since I'd already upvoted it soon after Cody posted it :) – Peter Cordes Jun 27 '16 at 13:11

2 Answers2

27

Given these two quotes, is the red zone above the stacked return address or below the stacked return address?

The red zone is the 128 bytes just below rsp, i.e. rsp - 128 to rsp - 1.

Since this red zone is relative to RSP, does it move downward with each push and does it move upward with each pop?

Yes.

fuz
  • 88,405
  • 25
  • 200
  • 352
  • If a function used its *red zone* and then wanted to call another function would it still have to use `sub rsp,128` before doing the `call` ? Or does the hardware place this new return address below the current *red zone*? – Sep Roland Jun 26 '16 at 19:49
  • 7
    @SepRoland The hardware doesn't know about the red zone. The red zone is a convention for software and it's use is limited by what the hardware can do. The red zone is not preserved during function calls so either you need to store data that must live through function calls inside your stack frame or (temporarily) lower the stack pointer. The whole purpose of the red zone is to avoid moving the stack pointer though, so this is not something a compiler would do. – fuz Jun 26 '16 at 20:34
  • 1
    *"The hardware doesn't know about the red zone."* This puzzles me. How then does the hardware know to not use the 128 bytes below `RSP` when an interrupt/exception/signal fires? – Sep Roland Jun 26 '16 at 21:33
  • 2
    @SepRoland It doesn't, cf. [this answer](http://stackoverflow.com/questions/25787408/amd64-abi-128-byte-red-zone). – fuz Jun 26 '16 at 21:56
  • 11
    @SepRoland: user-space stacks are never used for interrupts anyway. The kernel can't trust them. [kernel code has to be compiled with `-mno-red-zone` for exactly the reasons you mention](http://stackoverflow.com/questions/25787408/amd64-abi-128-byte-red-zone), because interrupts push RIP and RFLAGS onto the kernel stack. BTW, I just answered that question right *before* seeing this :P – Peter Cordes Jun 26 '16 at 21:57
11

The Wikipedia article about the Red Zone was wrong, thus creating the ambiguity.

I had modified the article in April 2017 to fix the issue. As of that update the Wikipedia article reads:

In computing, a red zone is a fixed-size area in a function's stack frame beyond the current stack pointer which is not preserved by that function. The callee function may use the red zone for storing local variables without the extra overhead of modifying the stack pointer. This region of memory is not to be modified by interrupt/exception/signal handlers. The x86-64 ABI used by System V mandates a 128-byte red zone, which begins directly under the current value of the stack pointer. The OpenRISC toolchain assumes a 128-byte red zone

This brings the Wikipedia article more in line with the 64-bit System V ABI definition. With the ambiguity above resolved, regarding the question:

Since this red zone is relative to RSP, does it move downward with each push and does it move upward with each pop?

The Red Zone is always the 128 bytes just below RSP. As RSP changes (by PUSH/POP/MOV etc) so too does the location of the Red Zone.

Michael Petch
  • 46,082
  • 8
  • 107
  • 198