C++ 如何从C/C++;gcc中的来源?

C++ 如何从C/C++;gcc中的来源?,c++,c,debugging,gcc,assembly,C++,C,Debugging,Gcc,Assembly,如何做到这一点 如果我想分析某些东西是如何编译的,我将如何获得发出的汇编代码?使用-S开关 g++ -S main.cpp 或者也可以使用gcc gcc -S main.c 另请参见使用-S选项: gcc -S program.c 如果您希望看到的内容取决于输出的链接,那么除了前面提到的gcc-S之外,输出对象文件/可执行文件上的objdump可能也很有用。下面是Loren Merritt编写的一个非常有用的脚本,它将默认的objdump语法转换为更可读的nasm语法: #!/usr/bi

如何做到这一点

如果我想分析某些东西是如何编译的,我将如何获得发出的汇编代码?

使用-S开关

g++ -S main.cpp
或者也可以使用gcc

gcc -S main.c
另请参见使用-S选项:

gcc -S program.c

如果您希望看到的内容取决于输出的链接,那么除了前面提到的gcc-S之外,输出对象文件/可执行文件上的objdump可能也很有用。下面是Loren Merritt编写的一个非常有用的脚本,它将默认的objdump语法转换为更可读的nasm语法:

#!/usr/bin/perl -w
$ptr='(BYTE|WORD|DWORD|QWORD|XMMWORD) PTR ';
$reg='(?:[er]?(?:[abcd]x|[sd]i|[sb]p)|[abcd][hl]|r1?[0-589][dwb]?|mm[0-7]|xmm1?[0-9])';
open FH, '-|', '/usr/bin/objdump', '-w', '-M', 'intel', @ARGV or die;
$prev = "";
while(<FH>){
    if(/$ptr/o) {
        s/$ptr(\[[^\[\]]+\],$reg)/$2/o or
        s/($reg,)$ptr(\[[^\[\]]+\])/$1$3/o or
        s/$ptr/lc $1/oe;
    }
    if($prev =~ /\t(repz )?ret / and
       $_ =~ /\tnop |\txchg *ax,ax$/) {
       # drop this line
    } else {
       print $prev;
       $prev = $_;
    }
}
print $prev;
close FH;
#/usr/bin/perl-w
$ptr='(字节|字|字|字|字|字;
$reg='(?:[er]?(?:[abcd]x |[sd]i |[sb]p)|[abcd][hl]| r1?[0-589][dwb]?| mm[0-7]| xmm1?[0-9]);
打开FH、'-|'、'/usr/bin/objdump'、'-w'、'-M'、'intel'、@ARGV或die;
$prev=“”;
while(){
如果(/$ptr/o){
s/$ptr(\[^\[\]]+\],$reg)/$2/o或
s/($reg,)$ptr(\[^\[\]+\])/$1$3/o或
s/$ptr/lc$1/oe;
}
如果($prev=~/\t(repz)?返回/和
$\uHg*ax,ax$/){
#放下这条线
}否则{
打印$prev;
$prev=$\ux;
}
}
打印$prev;
关闭FH;

我怀疑这也可以用于gcc-S的输出。

使用gcc(或g++)的
-S
选项

这将在helloworld.c上运行预处理器(cpp),执行初始编译,然后在运行汇编程序之前停止

默认情况下,这将输出一个文件
helloworld.s
。仍然可以使用
-o
选项设置输出文件

gcc -S -o my_asm_output.s helloworld.c
当然,这只有在拥有原始源的情况下才有效。 如果您只有生成的对象文件,另一种选择是通过设置
--discompose
选项(或缩写形式的
-d
)使用
objdump

如果为目标文件(
-g
在编译时)启用了调试选项,并且该文件未被剥离,则此选项效果最佳


运行
文件helloworld
将为您提供一些关于使用objdump将获得的详细程度的指示。

正如大家所指出的,使用GCC的
-S
选项。我还想补充一点,根据您是否添加优化选项,结果可能会有所不同(很大!)(
-O0
表示无,
-O2
表示渐进优化)


特别是在RISC体系结构上,编译器在进行优化时通常会对代码进行几乎无法识别的转换。这是令人印象深刻的和迷人的,看看结果

这将生成C代码+行号交织的汇编代码,以便更容易地查看哪些行生成了什么代码:

#创建汇编程序代码:
g++-S-fverbose asm-g-O2 test.cc-o test.S
#创建与源线交错的asm:
as-alhnd test.s>test.lst

如前所述,查看-S标志

还值得一看'-fdump tree'标志族,特别是'-fdump tree all',它可以让您看到一些gcc的中间形式。这些通常比汇编程序可读性更好(至少对我来说是这样),让您了解优化过程是如何执行的。

使用“-S”作为选项。它在终端中显示部件输出。

来自:

gcc-c-g-Wa,-a,-ad[其他gcc选项]foo.c>foo.lst

而不是Phyrephly的回答
或者像大家说的那样使用-S。

如果您正在寻找LLVM程序集:

llvm-gcc -emit-llvm -S hello.c
    .file   "main.c"
    .text
    .globl  myfunc
    .type   myfunc, @function
myfunc:
.LFB0:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    movl    %edi, -4(%rbp)
    movl    -4(%rbp), %eax
    addl    $1, %eax
    popq    %rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE0:
    .size   myfunc, .-myfunc
    .ident  "GCC: (Ubuntu 8.3.0-6ubuntu1) 8.3.0"
    .section    .note.GNU-stack,"",@progbits

正如大家所说,使用-S选项。
如果使用-save temps选项,还可以获取预处理文件(.i)、部件文件(.s)和对象文件(*.o)。(使用-E、-S和-c分别获取它们。)

以下命令行来自

我在WinXP上从DOS窗口运行了G++,运行的例程包含隐式强制转换

c:\gpp_code>g++ -g -O -Wa,-aslh horton_ex2_05.cpp >list.txt
horton_ex2_05.cpp: In function `int main()':
horton_ex2_05.cpp:92: warning: assignment to `int' from `double'

输出是用原始C++代码迭代的生成代码(C++代码在生成的ASM流中显示为注释)< /P>


我在答案中看不到这种可能性,可能是因为这个问题来自2008年,但在2018年,你可以使用马特·戈德博尔特的在线网站

您还可以本地git克隆并运行他的项目

下面是在Windows上查看/打印任何C程序的汇编代码的步骤

控制台/终端/命令提示符:

  • 在C代码编辑器(如codeblocks)中编写一个C程序,并用extension.C保存它

  • 编译并运行它

  • 成功运行后,转到安装gcc编译器的文件夹并给出

    执行以下命令以获取“.c”文件的“.s”文件

    C:\gcc>gcc-S输入C文件的完整路径

    示例命令(如我的示例)

    C:\gcc>gcc-sd:\Aa\u C\u Certified\alternate\u letters.C

    这将输出原始.c文件的.s文件

  • 四,。在此之后,键入以下命令

    C\gcc>cpp filename.s输入

    示例命令(如我的示例)

    C\gcc>cpp备选字母.s


    这将打印/输出C程序的整个汇编语言代码。

    最近我想知道程序中每个函数的汇编
    我就是这样做的

    $ gcc main.c                      // main.c source file
    $ gdb a.exe                       // gdb a.out in linux
      (gdb) disass main               // note here main is a function
                                      // similary it can be done for other functions
    

    下面是一个使用gcc的C解决方案:

    gcc -S program.c && gcc program.c -o output
    
  • 此处,第一个零件以与程序相同的文件名存储程序的程序集输出,但扩展名更改为.s,您可以将其作为任何普通文本文件打开

  • 这里的第二部分编译程序以供实际使用,并使用指定的文件名为程序生成可执行文件

  • 上面使用的program.c是程序名,output是要生成的可执行文件名


    顺便说一句,这是我关于StackOverFlow的第一篇文章:-}

    -save temps

    这是在会议上提到的,但让我进一步举例说明

    -S
    相比,此选项的最大优点是
      16:horton_ex2_05.cpp **** using std::setw;
      17:horton_ex2_05.cpp ****
      18:horton_ex2_05.cpp **** void disp_Time_Line (void);
      19:horton_ex2_05.cpp ****
      20:horton_ex2_05.cpp **** int main(void)
      21:horton_ex2_05.cpp **** {
     164                    %ebp
     165                            subl $128,%esp
    ?GAS LISTING C:\DOCUME~1\CRAIGM~1\LOCALS~1\Temp\ccx52rCc.s
    166 0128 55                    call ___main
    167 0129 89E5          .stabn 68,0,21,LM2-_main
    168 012b 81EC8000      LM2:
    168      0000
    169 0131 E8000000      LBB2:
    169      00
    170                    .stabn 68,0,25,LM3-_main
    171                    LM3:
    172                            movl $0,-16(%ebp)
    
    $ gcc main.c                      // main.c source file
    $ gdb a.exe                       // gdb a.out in linux
      (gdb) disass main               // note here main is a function
                                      // similary it can be done for other functions
    
    gcc -S program.c && gcc program.c -o output
    
    gcc -save-temps -c -o main.o main.c
    
    #define INC 1
    
    int myfunc(int i) {
        return i + INC;
    }
    
    # 1 "main.c"
    # 1 "<built-in>"
    # 1 "<command-line>"
    # 31 "<command-line>"
    # 1 "/usr/include/stdc-predef.h" 1 3 4
    # 32 "<command-line>" 2
    # 1 "main.c"
    
    
    int myfunc(int i) {
        return i + 1;
    }
    
        .file   "main.c"
        .text
        .globl  myfunc
        .type   myfunc, @function
    myfunc:
    .LFB0:
        .cfi_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register 6
        movl    %edi, -4(%rbp)
        movl    -4(%rbp), %eax
        addl    $1, %eax
        popq    %rbp
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
    .LFE0:
        .size   myfunc, .-myfunc
        .ident  "GCC: (Ubuntu 8.3.0-6ubuntu1) 8.3.0"
        .section    .note.GNU-stack,"",@progbits
    
     -save-temps=obj
    
    gcc -save-temps -c -o main.o -v main.c
    
    /usr/lib/gcc/x86_64-linux-gnu/8/cc1 -E -quiet -v -imultiarch x86_64-linux-gnu main.c -mtune=generic -march=x86-64 -fpch-preprocess -fstack-protector-strong -Wformat -Wformat-security -o main.i
    /usr/lib/gcc/x86_64-linux-gnu/8/cc1 -fpreprocessed main.i -quiet -dumpbase main.c -mtune=generic -march=x86-64 -auxbase-strip main.o -version -fstack-protector-strong -Wformat -Wformat-security -o main.s
    as -v --64 -o main.o main.s
    
    make help
    
    make main.s
    
    Compiling C source to assembly CMakeFiles/main.dir/main.c.s
    /usr/bin/cc    -S /home/ciro/hello/main.c -o CMakeFiles/main.dir/main.c.s