gcc -fomit-frame-pointer选项,-fno-dwarf2-cfi-asm 选项

来源:互联网 发布:java 局域网扫描 编辑:程序博客网 时间:2024/05/17 09:15

碰到或者找到了这两个选项,研究了一下,如下:

gcc 选项 -fomit-frame-pointer 省略框架指针

----------------------------------------
1. 测试程序
----------------------------------------
$ cat hello.c
#include <stdio.h>
void hi(void)
{
    printf("hello\n");
}

int main(int argc, char *argv[])
{
    hi();
    return 0;
}

c 调用框架:
pushl %ebp;
movl %ebp,%esp
...
pop %rbp
ret
是框架

----------------------------------------
2. gcc -o hello hello.c
----------------------------------------
有框架,有堆栈操作。
000000000040052d <hi>:
  40052d:    55                       push   %rbp
  40052e:    48 89 e5                 mov    %rsp,%rbp
  400531:    bf e4 05 40 00           mov    $0x4005e4,%edi
  400536:    e8 d5 fe ff ff           callq  400410 <puts@plt>
  40053b:    5d                       pop    %rbp
  40053c:    c3                       retq   


----------------------------------------
3. gcc -fomit-frame-pointer -o hello hello.c
----------------------------------------
省略了框架
000000000040052d <hi>:
  40052d:    48 83 ec 08              sub    $0x8,%rsp
  400531:    bf e4 05 40 00           mov    $0x4005e4,%edi
  400536:    e8 d5 fe ff ff           callq  400410 <puts@plt>
  40053b:    48 83 c4 08              add    $0x8,%rsp
  40053f:    c3                       retq   

----------------------------------------
4. gcc -fomit-frame-pointer -O2 -o hello hello.c
加 -O2 优化
----------------------------------------
该函数中没有看到使用堆栈
0000000000400540 <hi>:
  400540:    bf d4 05 40 00           mov    $0x4005d4,%edi
  400545:    e9 c6 fe ff ff           jmpq   400410 <puts@plt>
  40054a:    66 0f 1f 44 00 00        nopw   0x0(%rax,%rax,1)


--------------------------------------------------------------------------------
-fno-dwarf2-cfi-asm 选项
--------------------------------------------------------------------------------
 gcc -march=i386 -m32 -fno-dwarf2-cfi-asm -fno-builtin -c -o string.o string.c -Wa,-alh=string.lst
 加入 -fno-dwarf2-cfi-asm 将使.cfi 指令明显减少,如下为有和没有此选项的对比

CFA: 标准帧地址,调用其他函数时的堆栈指针地址
cfi_def_cfa_offset: 栈地址的改变用这个标识符表示。


                 memset:
 1035                  .LFB18:
 395:string.h      ****
 396:string.h      **** inline void * memset(void * s,char c,int count)
 397:string.h      **** {
 1036                      .loc 1 397 0
 1037                      .cfi_startproc
 1038 03ec 55               pushl    %ebp
 1039                      .cfi_def_cfa_offset 8
 1040                      .cfi_offset 5, -8
 1041 03ed 89E5             movl    %esp, %ebp
 1042                      .cfi_def_cfa_register 5
 1043 03ef 57               pushl    %edi
 1044 03f0 83EC04           subl    $4, %esp
 1045                      .cfi_offset 7, -12
 1046 03f3 8B450C           movl    12(%ebp), %eax
 1047 03f6 8845F8           movb    %al, -8(%ebp)
 398:string.h      **** __asm__("cld\n\t"
 1048                      .loc 1 398 0
 1049 03f9 8A45F8           movb    -8(%ebp), %al
 1050 03fc 8B5508           movl    8(%ebp), %edx
 1051 03ff 8B4D10           movl    16(%ebp), %ecx
 1052 0402 89D7             movl    %edx, %edi
 1053                  #APP
 1054                  # 398 "string.h" 1
 399 0405 F3               "rep\n\t"
 400 0406 AA               "stosb"
 401                      ::"a" (c),"D" (s),"c" (count)
 402:string.h      ****     );
 403:string.h      **** return s;
 1055                      cld
 1056                      rep
 1057                      stosb
 1058                  # 0 "" 2
 1059                      .loc 1 403 0
 1060                  #NO_APP
 1061 0407 8B4508           movl    8(%ebp), %eax
 404:string.h      **** }
 1062                      .loc 1 404 0
 1063 040a 83C404           addl    $4, %esp
 1064 040d 5F               popl    %edi
 1065                      .cfi_restore 7
 1066 040e 5D               popl    %ebp
 1067                      .cfi_restore 5
 1068                      .cfi_def_cfa 4, 4
 1069 040f C3               ret
 1070                      .cfi_endproc
 1071                  .LFE18:
 1072                      .size    memset, .-memset

--------------------------------------------------------------------------------

937                  memset:
 938                  .LFB18:
 395:string.h      ****
 396:string.h      **** inline void * memset(void * s,char c,int count)
 397:string.h      **** {
 939                      .loc 1 397 0
 940 03ec 55               pushl    %ebp
 941                  .LCFI115:
 942 03ed 89E5             movl    %esp, %ebp
 943                  .LCFI116:
 944 03ef 57               pushl    %edi
 945 03f0 83EC04           subl    $4, %esp
 946                  .LCFI117:
 947 03f3 8B450C           movl    12(%ebp), %eax
 948 03f6 8845F8           movb    %al, -8(%ebp)
 398:string.h      **** __asm__("cld\n\t"
 949                      .loc 1 398 0
 950 03f9 8A45F8           movb    -8(%ebp), %al
 951 03fc 8B5508           movl    8(%ebp), %edx
 952 03ff 8B4D10           movl    16(%ebp), %ecx
 953 0402 89D7             movl    %edx, %edi
 954                  #APP
 955                  # 398 "string.h" 1
 399 0405 F3               "rep\n\t"
 400 0406 AA               "stosb"
 401                      ::"a" (c),"D" (s),"c" (count)
 402:string.h      ****     );
 403:string.h      **** return s;
 956                      cld
 957                      rep
 958                      stosb
 959                  # 0 "" 2
 960                      .loc 1 403 0
 961                  #NO_APP
 962 0407 8B4508           movl    8(%ebp), %eax
 404:string.h      **** }
 963                      .loc 1 404 0
 964 040a 83C404           addl    $4, %esp
 965 040d 5F               popl    %edi
 966                  .LCFI118:
 967 040e 5D               popl    %ebp
 968                  .LCFI119:
 969 040f C3               ret
 970                  .LFE18:
 971                      .size    memset, .-memset



看完此代码,可以感到:
1. C 框架比直接用汇编效率差不少,(受框架限制)
2. 优化对C语言有什么含义? 不优化,有的代码倒來倒去没有意义。
   优化使代码在汇编级更简略,但可能对gdb调试不利,跳来跳去

0 0