From your original question I did not realize gcc limited red-zone use to leaf functions. I don’t think that’s required by the x86_64 ABI, but it is a reasonable simplifying assumption for a compiler. In that case you only need to make the function calling your assembly routine a non-leaf for purposes of compilation:
int global;
was_leaf()
{
if (global) other();
}
GCC can’t tell if global
will be true, so it can’t optimize away the call to other()
so was_leaf()
is not a leaf function anymore. I compiled this (with more code that triggered stack usage) and observed that as a leaf it did not move %rsp
and with the modification shown it did.
I also tried simply allocating more than 128 bytes (just char buf[150]
) in a leaf but I was shocked to see it only did a partial subtraction:
pushq %rbp
movq %rsp, %rbp
subq $40, %rsp
movb $7, -155(%rbp)
If I put the leaf-defeating code back in that becomes subq $160, %rsp