代码之家  ›  专栏  ›  技术社区  ›  Satbir

在哪种情况下,在调试时使用反汇编语言是有用的

  •  2
  • Satbir  · 技术社区  · 15 年前

    • 当我们在调试中需要用到反汇编时

    • 如何解释拆卸,例如下面的每个段代表什么

    00637CE3 8B 55 08             mov         edx,dword ptr [arItem]
    00637CE6 52                   push        edx
    00637CE7 6A 00                push        0
    00637CE9 8B 45 EC             mov         eax,dword ptr [result]
    00637CEC 50                   push        eax
    00637CED E8 3E E3 FF FF       call        getRequiredFields (00636030)
    00637CF2 83 C4 0C             add 
    

    平台:Windows

    4 回复  |  直到 5 年前
        1
  •  4
  •   Community CDub    8 年前

    估计编译器发出的代码的效率是非常有用的。

    例如,如果您使用 std::vector::operator[] 在没有反汇编的循环中,很难猜测每个调用 operator[] 事实上,需要两次内存访问,但使用迭代器访问相同的内存将需要一次内存访问。

    在您的示例中:

    mov         edx,dword ptr [arItem] // value stored at address "arItem" is loaded onto the register
    push        edx // that register is pushes into stack
    push        0 // zero is pushed into stack
    mov         eax,dword ptr [result] // value stored at "result" address us loaded onto the register
    push        eax // that register is pushed into stack
    call        getRequiredFields (00636030) // getRequiredFields function is called
    

    call 指示)。

    此外,在参与有关“编译后如何工作”的争论时,使用反汇编也是非常有用的,如 caf 指向 his answer to this question .

        2
  •  3
  •   Malkocoglu    15 年前

    2-这段代码调用了一个函数,比如getRequiredFields(result,0,arItem)。你必须为你想要的处理器学习汇编语言。对于x86,请访问www.intel.com并获取IA32的手册。

        3
  •  2
  •   Jesper    15 年前

    当你需要反汇编时:当你确实想知道CPU在执行你的程序时在做什么,或者当你没有用更高级语言编写程序的源代码时(在你的例子中是C++)。

    Intel's processor manuals .

    您发布的代码片段为函数调用准备参数(通过获取并推送堆栈上的一些值,并将值放入寄存器) eax ),然后调用该函数 getRequiredFields .

        4
  •  1
  •   Olof Forshell    14 年前

    了解程序集级调试允许您了解源编译器程序集关系,从而能够预测编译器将生成的代码。stackoverflow上的许多人都说“profile”,但这更进一步,因为您了解了在何时使用什么源代码构造(我用C编写)以及避免使用什么源代码构造。我猜想这对C++来说更重要,它可以生成大量代码而不需要开发者怀疑任何东西。例如,有一个用于处理对象列表的标准类,它似乎没有缺点-只有几行代码和这一奇妙的功能直到你看到它生成的大量奇怪的过程调用。我不是说使用它们是错误的,我只是说开发者应该知道使用它们的利弊。重载操作符可能是很好的功能(对于像我这样的WYSIWYG程序员来说有点奇怪),但执行速度的代价是什么?如果你说“没什么”,我会说“证明给你看。”

    调试时使用混合或纯汇编模式从来都不是错误的。困难的bug通常更容易找到,开发人员将学会编写更高效的代码。解释阵营(C#和Java)的开发人员会说,他们的代码与编译语言一样高效,但如果你知道汇编语言,你也会知道它们为什么错了,为什么它们完全错了。你可以微笑着想“是的,告诉我吧!”

    在您使用不同的编译器之后,您将遇到一个具有最惊人代码生成能力的编译器。一个PowerPC编译器通过优化器的高级代码解释将三个嵌套循环压缩为一个循环。在那个写我是。。。好吧,让我们换一个联盟。

    直到大约十年前,我还写了很多纯汇编代码,但是使用多阶段管道、多个执行单元和多个内核来与C编译器抗衡,这让我感到力不从心。另一方面,我知道编译器可以很好地处理什么,不应该处理什么:垃圾输入仍然等于垃圾输出。对于任何生成程序集输出的编译器都是如此。