C++ 如何从C/C++;gcc中的来源?
如何做到这一点 如果我想分析某些东西是如何编译的,我将如何获得发出的汇编代码?使用-S开关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
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程序的整个汇编语言代码。最近我想知道程序中每个函数的汇编
我就是这样做的
$ 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
顺便说一句,这是我关于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