gcc - printf 编译器优化?在堆栈上的 gdb 中找不到 "%s"个字符

标签 gcc compiler-construction gdb printf

当我的程序在 gdb 中反汇编时,我可以看到 buf 的地址被压入堆栈,但我没有看到格式字符串被压入它。这是什么原因?是不是巧妙的编译器优化?

我尝试编译一些不同的 printf 语句变体,看看我是否可以模仿没有被压入堆栈的“%s”字符串(或它的地址),但我做不到。

这是程序代码:

int main(int argc, char **argv) {

    char buf[128];
    if(argc < 2) return 1;

    strcpy(buf, argv[1]);

    printf("%s\n", buf);

    return 0;
}

用 gcc 4.5.2 编译,32 位 linux

最佳答案

是的,gcc 似乎会丢弃 "printf ("%s\n", buff)"并用 "puts()"代替它:

vi tmp.c =>
#include <stdio.h>
#include <string.h>

int
main(int argc, char **argv)
{
    char buf[128];
    if(argc < 2)
      return 1;

    strcpy(buf, argv[1]);
    printf("%s\n", buf);

    return 0;
}

$ gcc -S -Wall -pedantic tmp.c less tmp.s =>

        .file   "tmp.c"
        .text
.globl main
        .type   main, @function
main:
        leal    4(%esp), %ecx
        andl    $-16, %esp
        pushl   -4(%ecx)
        pushl   %ebp
        movl    %esp, %ebp
        pushl   %ecx
        subl    $148, %esp
        movl    %ecx, -140(%ebp)
        movl    -140(%ebp), %eax
        cmpl    $1, (%eax)
        jg      .L2
        movl    $1, -136(%ebp)
        jmp     .L4
.L2:
        movl    -140(%ebp), %edx
        movl    4(%edx), %eax
        addl    $4, %eax
        movl    (%eax), %eax
        movl    %eax, 4(%esp)
        leal    -132(%ebp), %eax
        movl    %eax, (%esp)
        call    strcpy
        leal    -132(%ebp), %eax
        movl    %eax, (%esp)
        call    puts
        movl    $0, -136(%ebp)
.L4:
        movl    -136(%ebp), %eax
        addl    $148, %esp
        popl    %ecx
        popl    %ebp
        leal    -4(%ecx), %esp
        ret
        .size   main, .-main
        .ident  "GCC: (GNU) 4.1.2 20080704 (Red Hat 4.1.2-48)"
        .section        .note.GNU-stack,"",@progbits

关于gcc - printf 编译器优化?在堆栈上的 gdb 中找不到 "%s"个字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8454106/

相关文章:

c - 我们在哪里使用 .i 文件以及如何生成它们?

c - 如何调试实时服务器?

c++ - gdb中的inf是什么

c++ - #include <> 和 #include ""

linux - 在GDB中调试多线程程序时如何一次继续一个线程?

c++ - 在 GCC 而不是 Clang 中编写 SIGSEGV 代码

c - OpenMP:并行程序并不比串行程序快(或不是非常快)。我究竟做错了什么?

c++ - 旧发行版上的二进制兼容性(使用 C++11)

compiler-construction - 编译器 : Translation to assembly

c# - 为什么要使用小于 32 位的整数?