You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何阻止GCC将return指令替换为跳转到最后一条的jmp指令

如何阻止GCC在-O0下将return替换为统一跳转的优化?

在使用-O0禁用大多数优化的情况下,GCC会将以下C函数编译为对应的汇编代码:

int dummy_function(int x)
{
    if (x == 1) {
        return 1;
    } else if (x == 2) {
        return 2;
    } else if (x == 3) {
        return 3;
    } else if (x == 4) {
        return 4;
    } else if (x == 5) {
        return 5;
    } else if (x == 6) {
        return 6;
    } else {
        return 10;
    }
}

编译后的汇编代码如下:

0:    55                      push   rbp
  1:    48 89 e5                mov    rbp,rsp
  4:    89 7d fc                mov    DWORD PTR [rbp-0x4],edi
  7:    83 7d fc 01             cmp    DWORD PTR [rbp-0x4],0x1
  b:    75 07                   jne    14 <test+0x14>
  d:    b8 01 00 00 00          mov    eax,0x1
 12:    eb 46                   jmp    5a <test+0x5a>
 14:    83 7d fc 02             cmp    DWORD PTR [rbp-0x4],0x2
 18:    75 07                   jne    21 <test+0x21>
 1a:    b8 02 00 00 00          mov    eax,0x2
 1f:    eb 39                   jmp    5a <test+0x5a>
 21:    83 7d fc 03             cmp    DWORD PTR [rbp-0x4],0x3
 25:    75 07                   jne    2e <test+0x2e>
 27:    b8 03 00 00 00          mov    eax,0x3
 2c:    eb 2c                   jmp    5a <test+0x5a>
 2e:    83 7d fc 04             cmp    DWORD PTR [rbp-0x4],0x4
 32:    75 07                   jne    3b <test+0x3b>
 34:    b8 04 00 00 00          mov    eax,0x4
 39:    eb 1f                   jmp    5a <test+0x5a>
 3b:    83 7d fc 05             cmp    DWORD PTR [rbp-0x4],0x5
 3f:    75 07                   jne    48 <test+0x48>
 41:    b8 05 00 00 00          mov    eax,0x5
 46:    eb 12                   jmp    5a <test+0x5a>
 48:    83 7d fc 06             cmp    DWORD PTR [rbp-0x4],0x6
 4c:    75 07                   jne    55 <test+0x55>
 4e:    b8 06 00 00 00          mov    eax,0x6
 53:    eb 05                   jmp    5a <test+0x5a>
 55:    b8 0a 00 00 00          mov    eax,0xa
 5a:    5d                      pop    rbp
 5b:    c3                      ret    

可以看到,即便启用了-O0,GCC仍会将各分支中的return替换为跳转到函数末尾统一ret的jmp指令。要阻止这个优化,有两种可行方法:

  • 全局禁用该优化:编译时添加-fno-optimize-sibling-calls选项,该选项会禁用兄弟调用相关的优化,强制GCC在每个分支生成独立的ret指令。
  • 仅对目标函数禁用:给目标函数添加__attribute__((optimize("-fno-optimize-sibling-calls")))属性,避免影响其他代码,示例代码如下:
__attribute__((optimize("-fno-optimize-sibling-calls")))
int dummy_function(int x)
{
    if (x == 1) {
        return 1;
    } else if (x == 2) {
        return 2;
    } else if (x == 3) {
        return 3;
    } else if (x == 4) {
        return 4;
    } else if (x == 5) {
        return 5;
    } else if (x == 6) {
        return 6;
    } else {
        return 10;
    }
}

内容的提问来源于stack exchange,提问作者Yacine Hebbal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 17:20:26