GCC 的 -O (-O1) 会打开 -fomit-frame-pointer,也就是,去掉函数调用时的frame pointer.
我们可以看一个例子。
int Calculator::Multiply(int a, int b)
{
printf("%d * %d = %d\n", a, b, a * b);
return a * b;
}
上面的函数,如果加上 -O2选项,汇编如下:
=> 0x000086a0 <+0>: push {r4, lr}
0x000086a4 <+4>: mul r4, r2, r1
0x000086a8 <+8>: movw r0, #34704 ; 0x8790
0x000086ac <+12>: movt r0, #0
0x000086b0 <+16>: mov r3, r4
0x000086b4 <+20>: bl 0x8518 <printf>
0x000086b8 <+24>: mov r0, r4
0x000086bc <+28>: pop {r4, pc}
End of assembler dump.
可以看到, frame pointer 却是被忽略了。
frame pointer 在函数调用回溯的时候,还是比较有用的,因此,可以用 -fno-omit-frame-pointer 保留.
此时, 生成的汇编如下:
=> 0x00008684 <+0>: push {r3, r4, r11, lr}
0x00008688 <+4>: mul r4, r2, r1
0x0000868c <+8>: movw r0, #34696 ; 0x8788
0x00008690 <+12>: add r11, sp, #12
0x00008694 <+16>: movt r0, #0
0x00008698 <+20>: mov r3, r4
0x0000869c <+24>: bl 0x84e8 <printf>
0x000086a0 <+28>: mov r0, r4
0x000086a4 <+32>: pop {r3, r4, r11, pc}
End of assembler dump.