你怎么做这个?

如果我想要分析一些东西是如何得到编制,我将如何获得中发现大会的代码?

有帮助吗?

解决方案

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

gcc -S helloworld.c

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

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

gcc -S -o my_asm_output.s helloworld.c

当然,只有拥有原始来源才有效。 如果你只有结果对象文件的另一种选择是使用 objdump ,通过设置 - disassemble 选项(或 -d 为缩写)形式)。

objdump -S --disassemble helloworld > helloworld.dump

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

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

其他提示

这将生成asm代码,其中交叉编码C代码+行号,以便更容易地看到哪些行生成了什么代码。

# create assembler code:
c++ -S -fverbose-asm -g -O2 test.cc -o test.s
# create asm interlaced with source lines:
as -alhnd test.s > test.lst

程序员算法中找到,第3页(这是第15页) PDF)。

以下命令行来自 Christian Garbin's博客

g++ -g -O -Wa,-aslh horton_ex2_05.cpp >list.txt

我在Win-XP的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流中显示为注释)

  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 <*>,-16(%ebp)

使用-S开关

g++ -S main.cpp

或与gcc

gcc -S main.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
       

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

<*>

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

=~ /\tnop |\txchg *ax,ax$/) { # drop this line } else { print $prev; $prev =

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

<*>

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

; } } print $prev; close FH;

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

好吧,正如大家所说,使用-S选项。 如果使用-save-temps选项,还可以获得预处理文件( .i),程序集文件( .s)和目标文件(* .o)。 (通过使用-E,-S和-c获取每个。)

正如大家所指出的,使用GCC的 -S 选项。我还想补充说,结果可能会有所不同(非常!),具体取决于您是否添加优化选项( -O0 表示无, -O2 用于进行优化)

特别是在RISC架构上,编译器通常会在进行优化时将代码转换为几乎无法识别。看结果令人印象深刻,令人着迷!

如前所述,请查看-S标志。

同样值得看看'-fdump-tree'标志系列,特别是'-fdump-tree-all',它可以让你看到一些gcc的中间形式。这些通常比汇编程序更具可读性(至少对我而言),并让您了解优化通过的执行情况。

使用-S选项:

gcc -S program.c

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

llvm-gcc -emit-llvm -S hello.c

我没有在答案中看到这种可能性,可能是因为这个问题来自2008年,但是在2018年你可以使用Matt Goldbolt的在线网站 https://godbolt.org

你也可以在本地git克隆并运行他的项目 https://github.com/mattgodbolt/compiler-探险

来自: http://www.delorie.com/djgpp/v2faq/faq8_20 html的

gcc -c -g -Wa,-a,-ad [其他GCC选项] foo.c&gt; foo.lst

替代PhirePhly的回答 或者只是按照每个人的说法使用-S。

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

console / terminal / command prompt:

  1. 在C代码编辑器中编写C程序,如代码块,并使用扩展名保存.c

  2. 编译并运行它。

  3. 成功运行后,转到已安装gcc编译器的文件夹并提供

    按照命令获取“.c”文件的“.s”文件

    C:\ gcc&gt; gcc -S C文件的完整路径ENTER

    示例命令(在我的例子中)

    C:\ GCC&GT; gcc -S D:\ Aa_C_Certified \ alternate_letters.c

    这会输出原始“.c”文件的“.s”文件

  4. 4。在此之后,键入以下命令

    C。; \&GCC GT; cpp filename.s ENTER

    示例命令(在我的例子中)

    C。; \&GCC GT; cpp alternate_letters.s

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

使用“-S”作为一种选择。它在终端显示汇编输出。

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

$ 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

-save-temps

这是提到在 https://stackoverflow.com/a/17083009/895245 但是,让我进一步体现它。当你这样做:

gcc -save-temps -c -o main.o main.c

主。c

#define INC 1

int myfunc(int i) {
    return i + INC;
}

而现在,除了正常的输出 main.o, ,目前的工作目录中还包含以下文件:

  • main.i 是一个红利并包含的期望的好感文件:

    # 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;
    }
    
  • main.s 中包含的期望产生的组件:

        .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

这节省了中间的文件目录 -o 目产出,而不是目前的工作目录,从而避免潜在的basename冲突。

利用这个选项 -S 是的,很容易将它添加任何建立脚本,而不干扰在建立本身。

另一个很酷的事情关于这个选择是如果你加入 -v:

gcc -save-temps -c -o main.o -v main.c

实际上,它表示了明确的文件被用于替代丑陋的临时下 /tmp, ,因此很容易知道究竟是怎么回事,其中包括预处理/编制/组件的步骤:

/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

测试Ubuntu19.04amd64,海湾合作委员会8.3.0.

以下是使用gcc的C解决方案:

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

  2. 此处的第二部分将编译您的程序以供实际使用,并为您的程序生成具有指定文件名的可执行文件。

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

    BTW这是我在StackOverFlow上的第一篇文章: - }

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top