gpt4 book ai didi

编译器优化 call-ret vs jmp

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:52:52 28 4
gpt4 key购买 nike

我正在构建其中一个项目,我正在查看生成的列表文件。(目标:x86-64)我的代码如下所示:

int func_1(var1,var2){
asm_inline_(
)
func_2(var1,var2);
return_1;
}
void func_2(var_1,var_2){
asm __inline__(
)
func_3();
}
/**** Jump to kernel ---> System call stub in assembly. This func in .S file***/
void func_3(){
}

当我看到汇编代码时,我发现在调用 func_2 和 func_3 时使用了“jmp”指令而不是“call-return”对。我确信这是编译器优化之一,我还没有探索如何禁用它。 (海湾合作委员会) 当我向 func_2 和 func_3 添加一些可变变量并递增它们时,“jmp”被“call-ret”对替换。 我很困惑地看到这种行为,因为这些变量是无用的,它们没有任何作用。 有人可以解释这种行为吗?

谢谢

最佳答案

如果代码跳转到另一个函数的开始而不是调用它,当跳转到的函数返回时,它将返回到调用外部函数的地方,忽略任何更多该点之后的第一个函数。假设行为是正确的(无论如何,第一个函数在那之后对执行没有任何贡献),这是一种优化,因为它减少了一个级别的指令和堆栈操作的数量。

在给定的示例中,行为正确的;没有要弹出的本地堆栈,也没有要返回的值,因此调用后不需要运行代码。 (return_1,假设它不是某个东西的宏,是一个纯表达式,因此无论它的值如何,它什么都不做。)所以当它没有更多的东西时,没有理由为将来保留堆栈框架为事件做贡献。

如果您将 volatile 变量添加到函数体中,您不仅仅是在添加编译器可以分析其流程的变量 - 您是在添加您已明确告诉编译器可以访问的 它可以预测的正常控制流之外。 volatile 限定符警告编译器,即使变量没有明显的转义方式,外部的某些东西也有办法获取它们的地址并随时写入它。所以它不能减少它们的生命周期,因为有人告诉函数外的代码可能仍会尝试写入该堆栈空间;显然,这意味着堆栈框架需要在其声明的整个生命周期内继续存在。

关于编译器优化 call-ret vs jmp,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26615246/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com