1

In trying to learn more about how C generates assembly code, I was exploring the outputs of various snippets of C code using godbolt.

One peculiar thing I came across was encountered with this piece of code:

#include <stdio.h>

int main() 
{
    puts("Hello, world!\n");
    
    return 0;
}

int x()
{
    return 0;
}

Compiling with -O3 yielded the following assembly:

.LC0:
        .string "Hello, world!\n"
main:
        subq    $8, %rsp
        movl    $.LC0, %edi
        call    puts
        xorl    %eax, %eax
        addq    $8, %rsp
        ret
x:
        xorl    %eax, %eax
        ret

My question is this:

Why does C allocate 8 bytes (subq $8, %rsp) on the stack before calling puts, which it doesn't end up using. Is this required to call puts? Or is it for moving the const into memory (which I don't think is right, as the constant is already defined, and the register is already axiomatically allocated).

So, what is the purpose of the subq $8, %rsp line here?

I included the int x function as well, to show that it does not allocate this when not calling puts?

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
Basil
  • 488
  • 1
  • 15
  • 2
    That's 8 bytes not one. It is for stack alignment as required by the calling convention. – Jester Jan 24 '23 at 15:32
  • 1
    How does allocating 8 bytes align the stack? If it's misaligned by, say, 3 bytes, surely adding 8 bytes would keep it misaligned? (3 % 8 = 3, (3 + 8) % 8 = 3) - unless I am misunderstanding stack alignment – Basil Jan 24 '23 at 15:33
  • I am not sure, but in MIPS ASM you must always allocate in stack the necessary memory for the arguments you will pass to any function call, in case it needs to store them somewhere. Maybe that's the reason – Biskweet Jan 24 '23 at 15:40
  • I'm far from an expert but maybe [red zone](https://en.wikipedia.org/wiki/Red_zone_(computing))? – Lundin Jan 24 '23 at 15:42
  • The `call` will place the other 8 bytes in the form of the return address on the stack, bringing the total to 16. – Jester Jan 24 '23 at 15:44
  • 1
    The linked question is not exactly a duplicate, but the accepted answer equally applies here. – Eugene Sh. Jan 24 '23 at 15:44
  • 4
    @EugeneSh.: Indeed, the usual canonical duplicate for these is [Why does the x86-64 / AMD64 System V ABI mandate a 16 byte stack alignment?](https://stackoverflow.com/q/49391001) . I edited the duplicate list to add it, especially since GCC's code-gen used `sub` not `push`. – Peter Cordes Jan 24 '23 at 16:01
  • 1
    @Lundin: Maybe you're mixing up the red zone with Windows x64's 32byte "shadow space"? Shadow space is allocated by the caller, for the callee to use. The red zone is *below* the current RSP, and doesn't need any extra instructions to allocate; that's the whole point. It's safe against *async* clobbering via signal handlers, debuggers, and stuff like that, which means those things have to respect it, but code in the caller doesn't have to do anything. (Again, that's why it's a pure win for efficiency; at worst you just don't end up using it, e.g. in compiler code-gen for non-leaf functions.) – Peter Cordes Jan 24 '23 at 16:05
  • @PeterCordes So below RSP _after_ done stacking as per calling convention? – Lundin Jan 25 '23 at 06:43
  • 1
    @Lundin: 128 bytes below the current RSP at any given moment is safe from asynchronous clobbers. So yes, after you're done pushing stuff and adjusting RSP in the prologue, the red zone where you might keep local vars is the space reachable with `disp8(%rsp)` for negative `disp8` (signed 8-bit; that's why 128 bytes was chosen as the red-zone size.) – Peter Cordes Jan 25 '23 at 06:50
  • @Basil The situation you described (the stack being misaligned by 3) isn't supposed to happen in the first place. A properly working C compiler won't write code that misaligns the stack. – puppydrum64 Jan 26 '23 at 14:33
  • @puppydrum64 Ah fair enough - I'm examining the code for writing my own compiler so it is feasable that the stack could be misaligned by some dodgy asm, but I guess that wouldn't be the fault of this stack alignment ^^ – Basil Jan 26 '23 at 14:37

0 Answers0