This is a basic C code for a basic function call:
int multiply(int num, int k) {
return num * k;
}
int main(int argc, char** argv) {
int k = multiply(5,2);
}
When I tried diassembling this code using the tool available at godbolt.org and picking the option for x86-64 clang 10.0.1, I got the following assembly instructions:
multiply: # @multiply
push rbp
mov rbp, rsp
mov dword ptr [rbp - 4], edi
mov dword ptr [rbp - 8], esi
mov eax, dword ptr [rbp - 4]
imul eax, dword ptr [rbp - 8]
pop rbp
ret
main: # @main
push rbp
mov rbp, rsp
sub rsp, 32
mov dword ptr [rbp - 4], edi
mov qword ptr [rbp - 16], rsi
mov edi, 5
mov esi, 2
call multiply
xor ecx, ecx
mov dword ptr [rbp - 20], eax
mov eax, ecx
add rsp, 32
pop rbp
ret
However, the stack pointer doesn't seem to change with each (or even after) parameters are added to the stack from the registers edi
and esi
by the callee, and remains pointing to the location containing the old value of the base pointer register. Why does that happen?
The compiler plans all space needed for the function and adjusts the stack pointer once at the start of the function and once at the end instead of each time something is needed on the stack inside the function.