SFP是可以在编译时候优化掉的,用"-fomit-frame-pointer"选项
编译:
$ gcc -fomit-frame-pointer -c test.c -o no_SFP.o
$ objdump -D no_SFP.o
no_SFP.o: file format elf32-i386
Disassembly of section .text:
00000000 <a>:
0: 83 ec 08 sub $0x8,%esp
3: 8b 44 24 0c mov 0xc(%esp,1),%eax
7: 89 44 24 04 mov %eax,0x4(%esp,1)
b: 8b 44 24 10 mov 0x10(%esp,1),%eax
f: 89 04 24 mov %eax,(%esp,1)
12: 8d 44 24 04 lea 0x4(%esp,1),%eax
16: ff 00 incl (%eax)
18: 89 e0 mov %esp,%eax
1a: 83 00 02 addl $0x2,(%eax)
1d: 83 c4 08 add $0x8,%esp
20: c3 ret
Disassembly of section .data:
这里把EBP省掉了,ESP兼职了EBP的部分工作(索引临时变量)。
显而易见,代码难懂了;-P, 代码执行长度缩短了,应该能引起效率的提升。 可恶的是,不能用backtrace调试了。
看一下arm下面的情况:
含有SFP的版本:
$ arm-linux-objdump -D SFP_arm.o
SFP_arm.o : file format elf32-littlearm
Disassembly of section .text:
00000000 <a>:
0: e1a0c00d mov ip, sp
4: e92dd800 stmdb sp!, {fp, ip, lr, pc}
8: e24cb004 sub fp, ip, #4 ; 0x4
c: e24dd010 sub sp, sp, #16 ; 0x10
10: e50b0010 str r0, [fp, -#16]
14: e50b1014 str r1, [fp, -#20]
18: e51b3010 ldr r3, [fp, -#16]
1c: e50b3018 str r3, [fp, -#24]
20: e51b3014 ldr r3, [fp, -#20]
24: e50b301c str r3, [fp, -#28]
28: e51b3018 ldr r3, [fp, -#24]
2c: e2833001 add r3, r3, #1 ; 0x1
30: e50b3018 str r3, [fp, -#24]
34: e51b301c ldr r3, [fp, -#28]
38: e2833002 add r3, r3, #2 ; 0x2
3c: e50b301c str r3, [fp, -#28]
40: e91ba800 ldmdb fp, {fp, sp, pc}
Disassembly of section .data: