I compiled the following c++ code in compiler explorer and the arguments passed to the function was moved to rbp - 4
and sequentially onward if a return statement was included and from rbp - 8
if not. Why does this happen. Is it a type of optimization or is something else occupying the pbp - 4
position ?
int foo(int a, int b, int c)
{
int d = 5;
int e = a + b + c + d;
//return e;
}
results in :
foo(int, int, int): # @foo(int, int, int)
push rbp
mov rbp, rsp
mov dword ptr [rbp - 8], edi
mov dword ptr [rbp - 12], esi
mov dword ptr [rbp - 16], edx
mov dword ptr [rbp - 20], 5
mov edx, dword ptr [rbp - 8]
add edx, dword ptr [rbp - 12]
add edx, dword ptr [rbp - 16]
add edx, dword ptr [rbp - 20]
mov dword ptr [rbp - 24], edx
ud2
and so with the return statement
foo(int, int, int): # @foo(int, int, int)
push rbp
mov rbp, rsp
mov dword ptr [rbp - 4], edi
mov dword ptr [rbp - 8], esi
mov dword ptr [rbp - 12], edx
mov dword ptr [rbp - 16], 5
mov edx, dword ptr [rbp - 4]
add edx, dword ptr [rbp - 8]
add edx, dword ptr [rbp - 12]
add edx, dword ptr [rbp - 16]
mov dword ptr [rbp - 20], edx
mov eax, dword ptr [rbp - 20]
pop rbp
ret
Why is there a change in stack offset ?
The compiler explorer was set to x86-64 clang 6.0.0 and these options (symbols as viewed) : .LX0: , .text , // , \s+ , Intel , Demangle
turned on
EDIT: When I changed the return type of foo
to void
the arguments are moved to rbp - 4
onward sequentially as expected.
foo(int, int, int): # @foo(int, int, int)
push rbp
mov rbp, rsp
mov dword ptr [rbp - 4], edi
mov dword ptr [rbp - 8], esi
mov dword ptr [rbp - 12], edx
mov dword ptr [rbp - 16], 5
mov edx, dword ptr [rbp - 4]
add edx, dword ptr [rbp - 8]
add edx, dword ptr [rbp - 12]
add edx, dword ptr [rbp - 16]
mov dword ptr [rbp - 20], edx
pop rbp
ret
And the function declared as void and with no return statement produces following assembly with x86-64 gcc 7.3. the stack positions are not the same as that of clang and not sequential.
foo(int, int, int):
push rbp
mov rbp, rsp
mov DWORD PTR [rbp-20], edi
mov DWORD PTR [rbp-24], esi
mov DWORD PTR [rbp-28], edx
mov DWORD PTR [rbp-4], 5
mov eax, DWORD PTR [rbp-24]
mov edx, DWORD PTR [rbp-20]
add eax, edx
add eax, DWORD PTR [rbp-28]
add eax, DWORD PTR [rbp-4]
mov DWORD PTR [rbp-8], eax
pop rbp
ret
So what causes this ?