我为Project Euler Q14编写了这两个解决方案,在汇编和C++中.它们是用于测试Collatz猜想的相同蛮力方法.装配解决方案与组装
nasm -felf64 p14.asm && gcc p14.o -o p14
Run Code Online (Sandbox Code Playgroud)
C++是用.编译的
g++ p14.cpp -o p14
Run Code Online (Sandbox Code Playgroud)
部件, p14.asm
section .data
fmt db "%d", 10, 0
global main
extern printf
section .text
main:
mov rcx, 1000000
xor rdi, rdi ; max i
xor rsi, rsi ; i
l1:
dec rcx
xor r10, r10 ; count
mov rax, rcx
l2:
test rax, 1
jpe even
mov rbx, 3
mul rbx
inc rax
jmp c1
even:
mov rbx, 2 …Run Code Online (Sandbox Code Playgroud) 我想知道如何在我的C源文件中使用GCC来转储机器代码的助记符版本,以便我可以看到我的代码被编译成什么.您可以使用Java执行此操作,但我无法找到GCC的方法.
我试图在汇编中重新编写一个C方法,看看GCC是如何做的,这将是一个很大的帮助.
我想检查boost::variant在我的代码中应用的程序集输出,以便查看哪些中间调用被优化掉了.
当我编译以下示例(使用GCC 5.3 g++ -O3 -std=c++14 -S)时,似乎编译器优化了所有内容并直接返回100:
(...)
main:
.LFB9320:
.cfi_startproc
movl $100, %eax
ret
.cfi_endproc
(...)
Run Code Online (Sandbox Code Playgroud)
#include <boost/variant.hpp>
struct Foo
{
int get() { return 100; }
};
struct Bar
{
int get() { return 999; }
};
using Variant = boost::variant<Foo, Bar>;
int run(Variant v)
{
return boost::apply_visitor([](auto& x){return x.get();}, v);
}
int main()
{
Foo f;
return run(f);
}
Run Code Online (Sandbox Code Playgroud)
但是,完整的程序集输出包含的内容远远超过上面的摘录,对我而言,它看起来永远不会被调用.有没有办法告诉GCC/clang删除所有"噪音"并输出程序运行时实际调用的内容?
完整装配输出:
.file "main1.cpp"
.section .rodata.str1.8,"aMS",@progbits,1
.align 8
.LC0:
.string "/opt/boost/include/boost/variant/detail/forced_return.hpp"
.section .rodata.str1.1,"aMS",@progbits,1
.LC1: …Run Code Online (Sandbox Code Playgroud) 我正在尝试将-S其中一个可执行文件传递给GCC.我试过这个:
set_target_properties(MyTarget PROPERTIES COMPILE_FLAGS "-S")
Run Code Online (Sandbox Code Playgroud)
但我得到"文件格式无法识别;视为链接器脚本"
(没有那条线就可以很好地建造)
这样传球有什么问题-S吗?或者是否有另一种方法让CMake输出汇编.s文件?
想知道是否有可能从clang生成交错的源和汇编?我正在寻找与gcc命令相当的东西(如http://www.fclose.com/240/generate-a-mixed-source-and-assembly-listing-using-gcc/所示)
gcc -Wa,-adhln -g source_code.c > assembly_list.s
Run Code Online (Sandbox Code Playgroud)
我访问过Link:如何在gcc中从C/C++源获得汇编程序输出?但它到目前为止列出了程序集 - 但没有交错.
此外,Visual Studio确实为您提供了非常好的交错式汇编输出,详细信息如下:如何使用Visual C++查看代码背后的程序集?
谢谢你的帮助.
萨朗
通常,可以使用GCC 和 Clang 中的标志从源文件中获取 GCC 的优化汇编器输出,-S如下例所示。
gcc -O3 -S -c -o foo.s foo.c
Run Code Online (Sandbox Code Playgroud)
但是假设我编译所有源文件-O3 -flto以启用链接时整个程序优化,并希望查看最终编译器生成的函数优化程序集,和/或查看代码在哪里/如何内联。
编译的结果是一堆.o文件,正如预期的那样,这些文件实际上是伪装成目标文件的 IR 文件。在链接可执行文件或共享库时,它们会被混合在一起,作为一个整体进行优化,然后编译成目标二进制文件。
但是如果我想要这个过程的汇编输出怎么办?也就是说,在链接时优化之后、在将 IR 编译为程序集期间以及在实际程序集和链接到最终可执行文件之前产生的程序集源。
我尝试简单地向-S链接步骤添加一个标志,但这并没有真正起作用。
我知道反汇编可执行文件是可能的,甚至与源代码交错,但有时查看实际编译器生成的程序集会更好,尤其是使用-fverbose-asm.
我发现这个问题为 C++ 提供了答案:
How do you get assembler output from C/C++ source in gcc?
对哈希进行简单的性能测试,看来C++版本比perl版本和golang版本都慢.
在我的PC上使用Core(TM)i7-2670QM CPU @ 2.20GHz,Ubuntu 14.04.3LTS,
有任何想法吗?
perl版本
use Time::HiRes qw( usleep ualarm gettimeofday tv_interval nanosleep
clock_gettime clock_getres clock_nanosleep clock
stat );
sub getTS {
my ($seconds, $microseconds) = gettimeofday;
return $seconds + (0.0+ $microseconds)/1000000.0;
}
my %mymap;
$mymap{"U.S."} = "Washington";
$mymap{"U.K."} = "London";
$mymap{"France"} = "Paris";
$mymap{"Russia"} = "Moscow";
$mymap{"China"} = "Beijing";
$mymap{"Germany"} = "Berlin";
$mymap{"Japan"} = "Tokyo";
$mymap{"China"} = "Beijing";
$mymap{"Italy"} = "Rome";
$mymap{"Spain"} = "Madrad";
$x = "";
$start = getTS();
for ($i=0; $i<1000000; …Run Code Online (Sandbox Code Playgroud) 我想知道是否/如何可以看到编译器在启用优化时如何使用clang ++/g ++重构一段代码.我知道英特尔编译器有一个标志来产生相关的输出,但我似乎无法找到其他编译器中的等价物.