Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the "sub $16, %rsp" instruction being used for?

Let's take the following basic C function and the intentionally unoptimized assembly it produces:

int main() {
    int i = 4;
    return 3;
}

It produces the following (unoptimized) assembly, which all makes sense to me:

main:
        pushq   %rbp
        movq    %rsp, %rbp
        movl    $4, -4(%rbp)
        movl    $3, %eax
        popq    %rbp
        ret

However, as soon as I add in a function call, there are two instructions that I don't quite understand:

void call() {};
int main() {
    int i = 4;
    call();
    return 3;
}
main:
        pushq   %rbp
        movq    %rsp, %rbp
        subq    $16, %rsp     <-- why is it subtracting 16?
        movl    $4, -4(%rbp)
        movl    $0, %eax      <-- why is it first clearing the %eax register?
        call    call
        movl    $3, %eax
        leave
        ret

If the stackframe needs to be 16-byte aligned, how does the subq $16, %rsp help with that? Doesn't the initial pushq %rbp instruction already offset it by 8 and now it's at +24 ? Or what are the points of those two lines in question above?

like image 920
carl.hiass Avatar asked Oct 19 '25 15:10

carl.hiass


1 Answers

The first variant stores the local variable in the red zone, a 128 byte area below the stack pointer that is not changed by signal handlers. The second variant cannot use the red zone because the callq instruction writes to the (original) red zone, clobbering the local variable stored there. (The called function could write to the original red zone as well, of course.)

%eax is set to zero because the function definition declares no prototype, so the compiler has to assume it is a variadic function. The %eax (actually %al) is used to optimize the implementation of variadic functions.

like image 152
Florian Weimer Avatar answered Oct 22 '25 06:10

Florian Weimer



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!