Issue
So I've got this example C program.
int worship(long john)
{
return 0 * john;
}
int main()
{
return worship(666);
}
The assembly looks (essentially) like this:
worship(long):
pushq %rbp
movq %rsp, %rbp
movq %rdi, -8(%rbp)
movl $0, %eax
popq %rbp
ret
main:
pushq %rbp
movq %rsp, %rbp
movl $666, %edi
call worship(long)
popq %rbp
ret
I ran into this while reading about stack smashing. In the assembly worship(long):
section where it says movq %rdi, -8(%rbp)
I would expect it to be using pushq
based on everything I've read so far. Is this the new way that GCC is pushing arguments onto the stack and if so is there a compiler flag I could be using to toggle this?
Solution
GCC manual says,
-mpush-args
Push instructions will be used to pass outgoing arguments when functions are called. Enabled by default.
-mno-push-args
Use PUSH operations to store outgoing parameters. This method is shorter and usually equally fast as method using SUB/MOV operations and is enabled by default. In some cases disabling it may improve performance because of improved scheduling and reduced dependencies.
-maccumulate-outgoing-args
If enabled, the maximum amount of space required for outgoing arguments will be computed in the function prologue. This is faster on most modern CPUs because of reduced dependencies, improved scheduling and reduced stack usage when preferred stack boundary is not equal to 2. The drawback is a notable increase in code size. This switch implies -mno-push-args.
Even -mpush-args
enabled by default it is override by -maccumulate-outgoing-args
which is enabled by default. Compiling passing option -mno-accumulate-outgoing-args
explicitly could change the instructions to push
.
Answered By - Sunil Bojanapally Answer Checked By - Mildred Charles (WPSolving Admin)