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

时间:2009-06-19 23:40:50

标签: visual-c++ assembly

我正在阅读关于两行代码效率的另一个问题,并且OP说他查看了代码背后的程序集,两行在程序集中是相同的。除了离题之外,我怎样才能查看编译程序时创建的汇编代码。

我正在使用Microsoft的Visual C ++,但我也想知道是否可以查看用Visual Basic编写的代码后面的程序集。

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

10 个答案:

答案 0 :(得分:139)

有几种方法:

  1. 在Visual Studio中调试C ++时,通常可以看到汇编代码(也是eclipse)。为此,在Visual Studio中为有问题的代码设置断点,当调试器点击它时,点击并找到“Go To Assembly”(或按CTRL + ALT + D)

  2. 第二种方法是在编译时生成汇编列表。为此,请转到项目设置 - > C / C ++ - >输出文件 - > ASM列表位置并填写文件名。同时选择“装配输出”为“使用源代码进行装配”。

  3. 编译程序并使用任何第三方调试程序。您可以使用OllyDbg或WinDbg。您也可以使用IDA(交互式反汇编程序)。但这是做这件事的核心方式。

答案 1 :(得分:26)

补充说明:Debug汇编程序输出和Release 1之间存在很大差异。第一个是很好的学习编译器如何从C ++生成汇编代码。第二个是很好的学习编译器如何优化各种C ++结构。在这种情况下,一些C ++ - to-asm转换并不明显。

答案 2 :(得分:21)

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


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

答案 3 :(得分:9)

最简单的方法是触发调试器并检查反汇编窗口

答案 4 :(得分:6)

此答案的早期版本(rextester.com的“hack”)现在大部分都是冗余的,因为http://gcc.godbolt.org/为ARM,x86和x86-64提供了 CL 19 RC (定位Windows调用约定,与该站点上的gcc,clang和icc不同。)

Godbolt编译器浏览器专为很好地格式化编译器asm输出而设计,消除了指令的“噪音”,因此我强烈建议使用它来查看asm以获取带有args并返回值的简单函数(因此他们赢了不要优化了。

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

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

e.g。 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版本。我不想包含更多的代码,这些代码会更难找到我想要查看asm的函数。 (虽然使用std :: string和boost运行计数器来实现这些目标!一些C风格的字符串操作对{}的结果做出更多关于它正在处理的字符串的假设(并忽略使用大缓冲区的最大长度安全/分配) {1}}总计机器代码会少得多。)

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

答案 5 :(得分:4)

在Visual C ++中的项目选项,输出文件我相信有一个选项,用于输出带有源代码的ASM列表。因此,您将在同一文件中看到C / C ++源代码和生成的ASM。

答案 6 :(得分:4)

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

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

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

答案 7 :(得分:1)

Red Gate's .NET Reflector是一个非常棒的工具,它帮了我几次。除了轻松向您显示MSIL之外,此实用程序的优点是,您可以分析许多第三方DLL并让Reflector负责将MSIL转换为C#和VB。

我不承诺代码会像源代码一样清晰,但你不应该遇到很多麻烦。

答案 8 :(得分:1)

如果您正在谈论调试以查看汇编代码,最简单的方法是Debug-> Windows-> Disassembly(或Alt-8)。这将使您进入被调用的函数并停留在反汇编中。

答案 9 :(得分:0)

使用 Visual Studio 6.0

点击菜单项“项目”

点击“设置”

选择标签页头 C/C++

将“类别”更改为“列出文件”

在“列表文件类型”下将组合框从“无列表”更改为“使用机器代码组装”

汇编源代码文件将作为 .cod 文件出现在“Release”文件夹中