为什么GCC使用Mov而不是推入函数调用?

Mil*_*les 6 c assembly stack gcc compilation

所以我有这个C程序示例.

int worship(long john)
{
    return 0 * john;
}

int main()
{
    return worship(666);
}
Run Code Online (Sandbox Code Playgroud)

该程序集(基本上)看起来像这样:

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
Run Code Online (Sandbox Code Playgroud)

我在阅读堆栈粉碎时遇到了这个问题.在汇编worship(long):部分,它表示movq %rdi, -8(%rbp)我希望它pushq基于我到目前为止阅读的所有内容.这是GCC将参数推送到堆栈的新方法吗?如果有的话,我可以使用编译器标志来切换它吗?

Sun*_*lly 7

GCC手册说,

-mpush-args
Run Code Online (Sandbox Code Playgroud)

在调用函数时,推送指令将用于传递传出参数.默认情况下启用.

-mno-push-args   
Run Code Online (Sandbox Code Playgroud)

使用PUSH操作存储传出参数.此方法较短,通常与使用SUB/MOV操作的方法一样快,默认情况下启用.在某些情况下,由于改进了调度并减少了依赖性,因此禁用它可能会提高性能.

-maccumulate-outgoing-args
Run Code Online (Sandbox Code Playgroud)

如果启用,则将在函数序言中计算传出参数所需的最大空间量.这在大多数现代CPU上更快,因为当优选的堆栈边界不等于2时,依赖性降低,调度改进并且堆栈使用减少.缺点是代码大小显着增加.这个开关意味着-mno-push-args.

即使-mpush-args默认情况下启用,也会默认启用覆盖-maccumulate-outgoing-args.-mno-accumulate-outgoing-args显式编译传递选项可以将指令更改为push.


归档时间:

查看次数:

1143 次

最近记录:

11 年,9 月 前