从一个小白也能看懂的例子,理解gcc编译-O选项的作用

首先来看一段简单的C代码

int foo(int m, int n)
{
    return m + n;
}

int main()
{
    int m = 1;
    int n = 2;
    return foo(m, n);
}

紧接着看一段未使用-O选项或使用-O0优化级别编译的反汇编代码

foo 函数开始
00010470 <foo>:
   10470:    e52db004     push    {fp}        ; (str fp, [sp, #-4]!)
   10474:    e28db000     add    fp, sp, #0
---------------------------------------------------------------------------------------------------
   10478:    e24dd00c     sub    sp, sp, #12
   1047c:    e50b0008     str    r0, [fp, #-8]      # r0 寄存器的值写入 fp - 8  地址处(从 main 函数可以发现,r0 = m = 1)
   10480:    e50b100c     str    r1, [fp, #-12]     # r1 寄存器的值写入 fp - 12 地址处(从 main 函数可以发现,r0 = n = 2)
   10484:    e51b2008     ldr    r2, [fp, #-8]      # fp - 8  地址处的值,加载到 r2
   10488:    e51b300c     ldr    r3, [fp, #-12]     # fp - 12 地址处的值,加载到 r3
   1048c:    e0823003     add    r3, r2, r3         # r3 = r2 + r3(就是 r3 = 1 + 2)
   10490:    e1a00003     mov    r0, r3             # 返回r3的值

上述汇编代码等价于C代码
   int a;
   int b;
   a = m;
   b = n;
   return a + b;
---------------------------------------------------------------------------------------------------
   10494:    e24bd000     sub    sp, fp, #0
   10498:    e49db004     pop    {fp}        ; (ldr fp, [sp], #4)
   1049c:    e12fff1e     bx    lr

main 函数开始
000104a0 <main>:
   104a0:    e92d4800     push    {fp, lr}
   104a4:    e28db004     add    fp, sp, #4
---------------------------------------------------------------------------------------------------
   104a8:    e24dd008     sub    sp, sp, #8
   104ac:    e3a03001     mov    r3, #1             # r3 寄存器等于1
   104b0:    e50b3008     str    r3, [fp, #-8]      # r3 寄存器的值写入 fp - 8  地址处
   104b4:    e3a03002     mov    r3, #2             # r3 寄存器等于2
   104b8:    e50b300c     str    r3, [fp, #-12]     # r3 寄存器的值写入 fp - 12 地址处
   104bc:    e51b100c     ldr    r1, [fp, #-12]     # r1 寄存器等于 fp - 12(可以将 r1 就是参数n)
   104c0:    e51b0008     ldr    r0, [fp, #-8]      # r0 寄存器等于 fp - 8 (可以将 r0 就是参数m)
   104c4:    ebffffe9     bl    10470 <foo>

上述汇编代码等价于C代码
   int a;
   int m;
   int n;
   a = 1;
   m = a;
   a = 2;
   n = a;
   foo(m, n);
---------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------
   104c8:    e1a03000     mov    r3, r0
   104cc:    e1a00003     mov    r0, r3

上述汇编代码等价于C代码
   将 foo 函数的返回值当做 main 函数的返回值
---------------------------------------------------------------------------------------------------
   104d0:    e24bd004     sub    sp, fp, #4
   104d4:    e8bd8800     pop    {fp, pc}

从上述的汇编代码可以发现,在未使用-O或使用-O0优化级别的情况下,编译出来的汇编代码基本与C语言的代码逻辑一一对应,没有做任何优化

接下来在看一段使用-O1 ~ -O3优化级别编译的反汇编代码

foo 函数开始
00010470 <foo>:
   10470:   e0800001    add r0, r0, r1  # foo 函数被优化成,直接返回参数 m 和 n 相加的结果。将临时存储的代码优化掉了
   10474:   e12fff1e    bx  lr

main 函数开始
00010478 <main>:
   10478:   e3a00003    mov r0, #3      # main 函数直接返回常数 3,将 foo 函数调用和变量定义的代码都优化掉了
   1047c:   e12fff1e    bx  lr

因为这里给出的C代码比较简单,所以-O1 ~ -O3编译出来的汇编代码是一样的(完全没必要进一步优化了啊,太简单了)。如果C代码复杂一点的话,可以看出-O1 ~ -O3每个等级的优化程度都是不一样的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值