你如何在gcc中从C / C ++源获得汇编程序输出?
290334 观看
17回复
回应 (17)
377像
使用-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
在编译时)并且文件尚未被剥离,则此选项最有效。
运行file helloworld
将为您提供使用objdump获得的详细程度的一些指示。
165像
这将生成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页(这是PDF的整体第15页)。
作者: PhirePhly 发布者: 26.09.2008 02:5144像
以下命令行来自Christian Garbin的博客
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 $0,-16(%ebp)
作者: Cr McDonough
发布者: 29.09.2013 10:07
22像
12像
如果你想看到的东西取决于输出的链接,那么除了前面提到的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;
我怀疑这也可以用在gcc -S的输出上。
作者: Dark Shikari 发布者: 26.09.2008 12:148像
好吧,正如大家所说,使用-S选项。如果使用-save-temps选项,还可以获得预处理文件(.i),汇编文件( .s)和目标文件(* .o)。(使用-E,-S和-c获取每个。)
作者: METADATA 发布者: 13.06.2013 08:567像
正如大家所指出的,使用-S
GCC选项。我还想补充一点,结果可能会有所不同(非常!),具体取决于您是否添加优化选项(-O0
对于没有优化选项-O2
)。
特别是在RISC体系结构中,编译器通常会在进行优化时将代码转换为几乎无法识别。看结果令人印象深刻,令人着迷!
作者: Dan Lenski 发布者: 26.09.2008 02:067像
如前所述,请查看-S标志。
同样值得看看'-fdump-tree'标志系列,特别是'-fdump-tree-all',它可以让你看到一些gcc的中间形式。这些通常比汇编程序更具可读性(至少对我而言),并让您了解优化通过的执行方式。
作者: Chris Jefferson 发布者: 11.10.2008 04:316像
6像
6像
我没有在答案中看到这种可能性,可能是因为问题是从2008年开始,但在2018年你可以使用Matt Goldbolt的在线网站https://godbolt.org
你也可以在本地git克隆并运行他的项目https://github.com/mattgodbolt/compiler-explorer
作者: Antonin GAVREL 发布者: 24.01.2018 03:274像
来自:http://www.delorie.com/djgpp/v2faq/faq8_20.html
gcc -c -g -Wa,-a,-ad [其他GCC选项] foo.c> foo.lst
替代PhirePhly的答案或只是使用-S,正如大家所说。
作者: Anonymous 发布者: 04.01.2011 12:022像
以下是在Windows上查看/打印任何C程序的汇编代码的步骤
console / terminal /命令提示符:
在C代码编辑器中编写C程序,如代码块,并使用扩展名.c保存
编译并运行它。
成功运行后,转到已安装gcc编译器的文件夹并提供
以下命令获取'.c'文件的'.s'文件
C:\ gcc> gcc -S C文件的完整路径
一个示例命令(在我的例子中)
C:\ gcc> gcc -SD:\ Aa_C_Certified \ alternate_letters.c
这将输出原始“.c”文件的“.s”文件
4。在此之后,键入以下命令
C; \ gcc> cpp filename.s ENTER
示例命令(在我的例子中)
C; \ gcc> cpp alternate_letters.s
这将打印/输出C程序的整个汇编语言代码。
作者: Ashutosh K Singh 发布者: 25.02.2018 03:031像
1像
最近我想知道程序中每个函数的汇编,
这就是我的工作方式。
$ 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
作者: Abhishek D K
发布者: 28.11.2018 06:13
1像
-save-temps
这在https://stackoverflow.com/a/17083009/895245中提到过,但让我进一步举例说明。当你这样做时:
gcc -save-temps -c -o main.o main.c
main.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
对象输出相同的目录而不是当前工作目录,从而避免潜在的基名冲突。
此选项的优点-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
在Ubuntu 19.04 amd64,GCC 8.3.0中测试。
作者: Ciro Santilli 新疆改造中心996ICU六四事件 发布者: 28.06.2019 06:280像
这是使用gcc的C解决方案:
gcc -S program.c && gcc program.c -o output
这里第一部分以与Program相同的文件名存储程序的程序集输出,但是具有更改的.s扩展名,您可以将其作为任何普通文本文件打开。
这里的第二部分将编译您的程序以供实际使用,并使用指定的文件名为您的程序生成可执行文件。
上面使用的program.c是程序的名称,输出是要生成的可执行文件的名称。
BTW这是我在StackOverFlow上的第一篇文章: - }
作者: Himanshu Pal 发布者: 26.12.2018 04:28来自类别的问题 :
- c++ 理解指针有什么障碍,克服它们可以做些什么?
- c++ 在C ++中解析INI文件的最简单方法是什么?
- c++ 什么时候应该在C ++中使用“朋友”?
- c++ 你如何清除stringstream变量?
- c 如何使用printf格式化unsigned long long int?
- c 如何实现延续?
- c How do you pass a function as a parameter in C?
- debugging 你如何调试PHP脚本?
- debugging 如何在Google Chrome中启动JavaScript调试程序?
- debugging 如何将调试断点添加到Visual Studio的“查找结果”窗口中显示的行
- debugging 调试LINQ to SQL SubmitChanges()
- gcc 为什么库链接的顺序有时会导致GCC错误?
- gcc 如何在GCC中摆脱从字符串常量到'char *'的过时转换警告?
- gcc 我的程序崩溃时如何自动生成堆栈跟踪
- gcc 如何模拟内存分配错误
- assembly x86中“非暂时”内存访问的含义是什么?
- assembly 你如何在gcc中从C / C ++源获得汇编程序输出?
- assembly 什么是好的C反编译器?
- assembly 在主要C / C ++编译器生成的代码中注册分配规则