c - 此优化代码中调用的内容

标签 c gcc optimization

我有一个简单的 C 代码:

#include <stdio.h>

void p(){
    printf("jjjj");
}

int main(){
    p();
}

如果我在 Mac OSX 上用 g++ 编译它并用 otool -tv 反汇编我可以看到 pmain 函数,那main 调用 p。使用优化 (-O3) 我得到了这个:

(__TEXT,__text) section
__Z1pv:
0000000100000f40    pushq   %rbp
0000000100000f41    movq    %rsp, %rbp
0000000100000f44    leaq    0x4b(%rip), %rdi
0000000100000f4b    xorl    %eax, %eax
0000000100000f4d    popq    %rbp
0000000100000f4e    jmp 0x100000f76
0000000100000f53    nopw    %cs:(%rax,%rax)
_main:
0000000100000f60    pushq   %rbp
0000000100000f61    movq    %rsp, %rbp
0000000100000f64    leaq    0x2b(%rip), %rdi
0000000100000f6b    xorl    %eax, %eax
0000000100000f6d    callq   0x100000f76
0000000100000f72    xorl    %eax, %eax
0000000100000f74    popq    %rbp
0000000100000f75    retq

main 似乎仍在地址 0x100000f76 调用某些东西。我如何查看此位置的内容? g++ 在这里做什么?

最佳答案

您没有将 p() 声明为 static,因此您看到的是 p() 的编译版本,它调用printf()(通过 jmp),然后您还在 main() 中获得 p() 的内联版本,它也只是转换为对 printf() 的调用。如果您将 p() 声明为 static,那么您只会在 main() 中看到内联调用。

虽然要回答您的问题,0x100000f76 似乎是 printf() 的入口点。

您可能会发现告诉编译器生成 asm 比反汇编您的代码更有指导意义,因为这将包含更多有用的信息,例如gcc -S -O3(在 OS X 上使用 clang)生成:

    .section    __TEXT,__text,regular,pure_instructions
    .macosx_version_min 10, 11
    .globl  _p
    .align  4, 0x90
_p:                                     ## @p
    .cfi_startproc
## BB#0:
    pushq   %rbp
Ltmp0:
    .cfi_def_cfa_offset 16
Ltmp1:
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
Ltmp2:
    .cfi_def_cfa_register %rbp
    leaq    L_.str(%rip), %rdi
    xorl    %eax, %eax
    popq    %rbp
    jmp _printf                 ## TAILCALL
    .cfi_endproc

    .globl  _main
    .align  4, 0x90
_main:                                  ## @main
    .cfi_startproc
## BB#0:
    pushq   %rbp
Ltmp3:
    .cfi_def_cfa_offset 16
Ltmp4:
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
Ltmp5:
    .cfi_def_cfa_register %rbp
    leaq    L_.str(%rip), %rdi
    xorl    %eax, %eax
    callq   _printf
    xorl    %eax, %eax
    popq    %rbp
    retq
    .cfi_endproc

    .section    __TEXT,__cstring,cstring_literals
L_.str:                                 ## @.str
    .asciz  "jjjj"


.subsections_via_symbols

在这里你可以看到 jmpcallqprintf 而不仅仅是一些未知地址。

关于c - 此优化代码中调用的内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34051056/

相关文章:

C程序: getenv return NULL in GDB/DDD

C 中无法在另一个函数中打印函数的返回值

c - "undefined reference to function"C 中的错误取决于定义的位置

c - 在 C 中丢弃数十和数百列的 int

c++ - fedora 21 上的 gcc-c++-4.1.2(双)安装

无法在 Gnu-Make 中禁用 "default"后缀规则

c# - 获取 List<T> 中最小值索引的快速/有效方法?

c - 从未知大小的文件描述符中完全读取

c# - 使用 yield 如何节省时间或内存?

android - Base64 图像的 Recyclerview - 滚动缓慢且滞后