【问题标题】:What are these extra instructions when disassembling simple binary?反汇编简单二进制文件时这些额外的指令是什么?
【发布时间】:2017-08-25 12:04:45
【问题描述】:

这是一个有点幼稚的问题...这里有一点背景知识。 我正在学习汇编,所以我写了一个非常简单的 C 程序,用gcc -m32 -O0 -o prog.elf 编译它,然后用objdump -M intel -d prog.elf 对其运行 objdump。

C代码是:

#include <stdio.h>

int main() {
    int a = 1;
    int b = 2;
    a = a + b;

    return (0);
}

这看起来很简单。生成的 Intel 程序集(带有我的 cmets)是:

push   ebp                       ; Push previous stack frame.
mov    ebp, esp                  ; Move SP to EBP to set new stack frame.
sub    esp, 0xc                  ; Reserve 0xc bytes for local variables.
xor    eax, eax                  ; Clear eax.
mov    DWORD PTR [ebp-0x4], 0x0  ; Move 0x0 into local variable ebp-0x4.
mov    DWORD PTR [ebp-0x8], 0x1  ; Move 0x1 into local variable ebp-0x8.
mov    DWORD PTR [ebp-0xc], 0x2  ; Move 0x2 into local variable ebp-0xc.
mov    ecx, DWORD PTR [ebp-0x8]  ; Move local variable ebp-0x8 into ecx.
add    ecx, DWORD PTR [ebp-0xc]  ; Add local variable ebp-0xc to ecx.
mov    DWORD PTR [ebp-0x8], ecx  ; Move value of ecx into local variable ebp-0x8.
add    esp, 0xc                  ; Set SP back to location before.
pop    ebp                       ; Restore base pointer.
ret                              ; Return

我的问题是,ebp-0x4 在那里做什么?它似乎什么也没做。 我会猜测并说它来自 main() 的参数,它没有,但由于某种原因,如果没有提供,它仍然将 0x0 作为参数推送? 还有,为什么xor eax, eax好像没有用...

我只是有点困惑他们为什么会在那里。 如果有人可以帮助我理解为什么那会很棒。提前致谢!

【问题讨论】:

  • 你的 gcc 版本显然与我不同,我得到不同的结果。我很好奇您是否将返回值更改为不同的值,例如 7 或 ebp-0x04 是否更改为该值。我不会感到惊讶的是,他们在堆栈上为返回值保留了一个位置并设置它,但实际上并没有使用它。
  • 您在编译时没有优化。当然,当您不允许编译器优化其代码时,它会做一些毫无意义的事情。
  • @old_timer 我仍然将 ebp-0x4 初始化为 0,即使我返回 a,哈哈。我认为它一定是像 paxdiablo 所说的编译器人工制品。
  • @Michael Petch LLVM 8.0 on OSX,哈哈哈。
  • 那是什么版本的 OS/X? OS/X 上的一些编译器(默认安装的编译器)可能已经很老了。如前所述,它可能只是代码生成器的产物。打开优化可能会看到它消失。

标签: gcc assembly reverse-engineering disassembly objdump


【解决方案1】:

我不确定您为什么认为xor eax, eax 未被使用,这是将eax 设置为零的简单方法。由于它通常是函数的返回码,因此它相当于您的return 0;(顺便说一下,它不需要括号)。

至于为什么ebp-0x4 在那里,我不能说。我说其余的代码都没有经过优化,所以它可能只是编译过程的产物。它很可能在更高的优化级别上消失,尤其是因为整个函数基本上可以用你认为多余的一行替换:-)

【讨论】:

  • 我有点忘了eax是用来退货的,哈哈。这现在更有意义了。谢谢!
  • @needshelpwithassembly 你应该返回 a,而不是 0。
  • @JeremyP 谢谢,但我只是想处理一些简单的说明,不必处理整个退货过程,但我现在正在努力理解这一点。 :)
  • @needshelpwithassembly 我建议这样做的原因是任何优化都不会去掉你想看的东西。此外,您还可以了解 return 的工作原理。
猜你喜欢
  • 2016-04-04
  • 2012-07-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-23
  • 1970-01-01
  • 1970-01-01
  • 2015-05-15
相关资源
最近更新 更多