【问题标题】:Where do I find the assembly code for a procedure called in the GCC assembly output?在哪里可以找到 GCC 汇编输出中调用的过程的汇编代码?
【发布时间】:2013-03-19 14:36:14
【问题描述】:

我一直在玩 GCC 的程序集输出开关:

gcc -S -c helloworld.c

helloworld.c

#include <stdio.h>

int main(void){
    printf("Hello World!\n");
    return 0;
}

helloworld.s

    .file   "helloworld.c"
    .section    .rodata
.LC0:
    .string "Hello World!"
    .text
    .globl  main
    .type   main, @function
main:
.LFB0:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    movl    $.LC0, %edi
    call    puts
    movl    $0, %eax
    popq    %rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE0:
    .size   main, .-main
    .ident  "GCC: (Debian 4.7.2-5) 4.7.2"
    .section    .note.GNU-stack,"",@progbits

在输出helloworld.s 文件中,我注意到汇编命令输出“Hello World!”文字很简单:

call puts

但是,helloworld.s1 文件中没有 puts 过程汇编代码。我在哪里可以查看此汇编代码?

【问题讨论】:

  • 这是因为您的 C 程序期望与标准 C 运行时库链接,其中包含 puts()。当然,如果您愿意,您可以在反汇编时挖掘系统上的库文件。
  • 这是libc.so 文件吗?
  • 是的,就是libc.so;我建议用gcc -O -S -fverbose-asm 编译
  • 我无法让 objdump 反汇编 libc.so,但我确实在 部分下的 libc.a 中找到了代码:objdump -d /usr/lib/x86_64-linux-gnu/libc.a
  • Debian 使用的是开源的 eglibc,所以你可以看到它的实际 C 源代码。

标签: c linux gcc assembly disassembly


【解决方案1】:

编辑:这实际上不是对原始问题的答案,但由于它得到了投票,所以信息似乎很有用,所以...


这是 GCC 的优化。由于您的字符串不包含任何格式字符并以换行符结尾,GCC 用puts 替换调用,它产生相同的输出但速度更快(因为它不需要扫描字符串以查找格式说明符)。尝试类似:

int main(int argc, char *argv[]){
    printf("Hello World!\nargc=%d", argc);
    return 0;
}

你会在程序集中看到你的printf

【讨论】:

  • 问题似乎是“puts 的程序集源在哪里?”,而不是“为什么使用puts 而不是printf?”
  • 啊,你说得对。我会对其进行编辑以更改答案,但这会窃取已经在 cmets 中回答 OP 的人的选票...
  • OP 在libc.a 上做了self-answerobjdump -d,所以这个问题确实有实际问题的答案。
【解决方案2】:

回答

使用 gcc 标志 -fno-builtin

说明

为了提高性能,GCC、Glibc 将共同对标准 C 库进行一些修改。由于 GCC 和 Glibc 几乎适用于所有用户空间应用程序,因此默认打开内置函数,它将只有一个参数的 printf() 函数调用转换为 puts() 函数调用。

您还可以使用-fno-builtin-printf 等标志告诉 GCC 不要转换特定的内置函数调用。 Here 是您可以阻止 GCC 转换的内置函数的完整列表。

here是flag的详细解释。

【讨论】:

    【解决方案3】:

    正如用户unwind 提到的:

    这是因为您的 C 程序期望与标准 C 链接 运行时库,其中包含puts()。你当然可以挖图书馆 如果您愿意,可以将其作为反汇编文件保存在您的系统上。

    于是我用objdump反汇编libc.a,在&lt;puts&gt;部分下找到汇编代码:objdump -d /usr/lib/x86_64-linux-gnu/libc.a

    【讨论】:

      猜你喜欢
      • 2011-01-10
      • 2011-08-25
      • 1970-01-01
      • 2013-01-22
      • 2013-07-25
      • 2023-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多