如何使用Visual C ++查看代码背后的程序集?

我正在阅读关于两行代码的效率的另一个问题,OP说他看了代码背后的程序集,两行代码在汇编中是相同的。 除了撇开之外,我怎么看编译程序时创build的汇编代码。

我正在使用微软的Visual C ++,但我也想知道是否有可能查看在Visual Basic中编写的代码背后的程序集。

那么,如何查看用C ++和Visual Basic等高级语言编写的程序背后的汇编代码呢?

有几种方法:

  1. 在Visual Studio中debuggingC ++时通常可以看到汇编代码(也是eclipse)。 在Visual Studio中为这个代码放置一个断点,当debugging器击中它时,点击并find“Go To Assembly”(或按CTRL + ALT + D)

  2. 第二种方法是在编译时生成汇编列表。 为此进入项目设置 – > C / C ++ – >输出文件 – > ASM列表位置并填入文件名。 同样select“Assembly Output”到“Assembly Source Source”。

  3. 编译该程序并使用任何第三方debugging器。 您可以使用OllyDbg或WinDbg。 你也可以使用IDA(交互式反汇编)。 但是这是硬核的做法。

附加说明:Debug汇编器输出和Release 1之间有很大的区别。 第一个很好学习编译器如何从C ++生成汇编代码。 第二个是学习编译器如何优化各种C ++结构。 在这种情况下,一些C ++到asm的转换并不明显。

指定cl编译器的/ FA开关。 根据交换机的值,只集成汇编代码或高级代码和汇编代码。 文件名获得.asm文件扩展名。 以下是支持的值:


  • / FA汇编代码; .ASM
  • / FAc机器和汇编代码; .COD
  • / FAs源代码和汇编代码; .ASM
  • / FAcs机器,源代码和汇编代码; .COD

最简单的方法是启动debugging器并检查反汇编窗口

这个答案的早期版本(rextester.com的“hack”)现在基本上是多余的, http: //gcc.godbolt.org/提供了针对ARM,x86和x86-64的CL 19 RC (针对Windows调用约定,不像gcc,clang和icc在那个网站上)。

Godbolt编译器资源pipe理器是为了很好地格式化编译器的asm输出而devise的,去除了指令的“噪声”,所以我强烈推荐使用它来查看asm,获取参数并返回值的简单函数(所以它们不会优化了)。

有一段时间,CL在http://gcc.beta.godbolt.org/上可用,但不是主站点,但是现在它们都在。;


要从http://rextester.com/l/cpp_online_compiler_visual在线编译器获取MSVC asm输出:将/FAs添加到命令行选项。 让程序find自己的path,并找出.asm的path并将其转储。 或者在.exe上运行一个反汇编.exe

例如http://rextester.com/OKI40941

 #include <string> #include <boost/filesystem.hpp> #include <Windows.h> using namespace std; static string my_exe(void){ char buf[MAX_PATH]; DWORD tmp = GetModuleFileNameA( NULL, // self buf, MAX_PATH); return buf; } int main() { string dircmd = "dir "; boost::filesystem::path p( my_exe() ); //boost::filesystem::path dir = p.parent_path(); // transform c:\foo\bar\1234\a.exe // into c:\foo\bar\1234\1234.asm p.remove_filename(); system ( (dircmd + p.string()).c_str() ); auto subdir = p.end(); // pointing at one-past the end subdir--; // pointing at the last directory name p /= *subdir; // append the last dir name as a filename p.replace_extension(".asm"); system ( (string("type ") + p.string()).c_str() ); // std::cout << "Hello, world!\n"; } ... code of functions you want to see the asm for goes here ... 

typecat的DOS版本。 我不想包含更多的代码,这会使我很难find我想要看到的函数。 (虽然使用std :: string和boost运行反这些目标!一些C风格的string操作,使得更多的关于它正在处理的string的假设(并忽略最大长度安全/通过使用一个大缓冲区分配)的GetModuleFileNameA的结果总的机器码会less得多。)

IDK为什么,但cout << p.string() << endl只显示基本名称(即文件名,没有目录),即使打印其长度显示它不只是裸名。 (Ubuntu 15.10上的Chromium48)。 在cout中的某个点或程序的stdout和Web浏览器之间可能有一些反斜杠转义处理。

在Visual C ++项目选项下,输出文件,我相信有一个选项输出与源代码的ASM列表。 所以你会看到C / C ++源代码和生成的ASM都在同一个文件中。

对于MSVC,您可以使用链接器。

link.exe / dump / linenumbers / disasm /out:foo.dis foo.dll

foo.pdb需要可用来获取符号

红门的.NETreflection器是一个非常好的工具,已经帮了我不止几次。 这个实用工具的好处之一就是可以很容易地向你展示MSIL,你可以分析很多第三方DLL,并且让Reflector负责把MSIL转换成C#和VB。

我不希望代码会像源代码一样清晰,但你不应该有太多的麻烦。