在这个优化的代码中调用了什么

时间:2015-12-02 19:13:18

标签: 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++在这做什么?

1 个答案:

答案 0 :(得分:3)

您没有将p()声明为static,因此您看到的是p()的编译版本,该版本调用printf()(通过jmp ),然后您还在p()内获得main()的内联版本,该版本也会转换为对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,而不仅仅是某个未知地址。