【问题标题】:Understanding disassembly - Seeing two main()'s了解反汇编 - 查看两个 main()
【发布时间】:2010-11-15 04:05:45
【问题描述】:

以下 C 程序的转储:

int main() {
    int i,j;
    for(i=0; i<2; i++) {
        j++;
    }
    return 0;
}

正在生产:

08048394 <main>:
int main() {
 8048394:   8d 4c 24 04             lea    0x4(%esp),%ecx
 8048398:   83 e4 f0                and    $0xfffffff0,%esp
 804839b:   ff 71 fc                pushl  -0x4(%ecx)
 804839e:   55                      push   %ebp
 804839f:   89 e5                   mov    %esp,%ebp
 80483a1:   51                      push   %ecx
 80483a2:   83 ec 10                sub    $0x10,%esp
    int i,j;
    for(i=0; i<2; i++) {
 80483a5:   c7 45 f8 00 00 00 00    movl   $0x0,-0x8(%ebp)
 80483ac:   eb 08                   jmp    80483b6 <main+0x22>
        j++;
 80483ae:   83 45 f4 01             addl   $0x1,-0xc(%ebp)
int main() {
    int i,j;
    for(i=0; i<2; i++) {
 80483b2:   83 45 f8 01             addl   $0x1,-0x8(%ebp)
 80483b6:   83 7d f8 01             cmpl   $0x1,-0x8(%ebp)
 80483ba:   7e f2                   jle    80483ae <main+0x1a>
        j++;
    }
    return 0;
 80483bc:   b8 00 00 00 00          mov    $0x0,%eax
}

无论我输入i&lt;2 还是i&lt;10,我都看到两个main() 具有相同的结构。有人能告诉我为什么会这样吗?

【问题讨论】:

    标签: c assembly disassembly


    【解决方案1】:

    您没有看到两个main()s。您会看到一个反汇编程序被for 循环完全弄糊涂了。实际的程序集,如果你通读一遍,正好代表一个函数,main(),逻辑路径与 C 代码相同。

    简而言之:插入到程序集中的 C 是错误。

    【讨论】:

    • 哦!那你能告诉我这些在做什么吗:jmp 80483b6 &lt;main+0x22&gt; 和jle 80483ae &lt;main+0x1a&gt;?最后,有没有办法改进这种反汇编?
    • 我不会责怪反汇编器,反汇编看起来不错;它只是模仿目标文件中的调试信息,其中包含从源文件:行到输出的映射,并不总是准确的。
    • @Legend:jmp 正在从 for 循环中跳转s initialization code (i=0) to the test (i). The jle` 是一个跳转等于,将i 与1 进行比较(i&lt;2 被编译器优化为i&lt;=1)。如果小于等于 1,则控制权转移到 for 循环体。
    【解决方案2】:

    反汇编程序尽职尽责地交错源代码,正如编译器的输出调试信息所说的那样。在 Linux 上,您可以通过 objdump -W 看到这一点:

    … 行号语句: 扩展操作码 2:将地址设置为 0x80483e4 复制 特殊操作码 91:提前地址 6 到 0x80483ea 和行 2 到 3 特殊操作码 132:提前地址 9 到 0x80483f3 和行 1 到 4 特殊操作码 60:提前地址 4 到 0x80483f7 和行 -1 到 3 特殊操作码 148:提前地址 10 到 0x8048401 和行 3 到 6 特殊操作码 76:提前地址 5 到 0x8048406 和行 1 到 7 将 PC 前进 2 到 0x8048408 扩展操作码 1:序列结束 …

    我的编译器显然与您的编译器有些不同,因为地址不同,但您会看到它是如何工作的:输出程序集中的地址和输入源文件中的行之间的映射不精确。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-18
      • 2011-06-16
      • 2011-06-12
      • 2018-09-22
      • 2012-03-26
      • 2013-06-04
      • 2013-02-01
      • 2017-12-20
      相关资源
      最近更新 更多