【问题标题】:function call seems not working properly in disassembled code [duplicate]函数调用在反汇编代码中似乎无法正常工作[重复]
【发布时间】:2014-04-15 00:10:01
【问题描述】:

我写了一个简单的程序,然后编译组装它。

tfc.cpp

int i = 0;

void f(int a)
{
  i += a;
};

int main()
{
  f(9);
  return 0;
};

我通过运行得到了 tfc.o

$ g++ -c -O1 tfc.cpp

然后我使用gobjdumpobjdump)来反汇编二进制文件。

$ gobjdump -d tfc.o

然后我得到了

0000000000000000 <__Z1fi>:
   0: 55                    push   %rbp
   1: 48 89 e5              mov    %rsp,%rbp
   4: 01 3d 00 00 00 00     add    %edi,0x0(%rip)        # a <__Z1fi+0xa>
   a: 5d                    pop    %rbp
   b: c3                    retq   
   c: 0f 1f 40 00           nopl   0x0(%rax)

0000000000000010 <_main>:
  10: 55                    push   %rbp
  11: 48 89 e5              mov    %rsp,%rbp
  14: bf 09 00 00 00        mov    $0x9,%edi
  19: e8 00 00 00 00        callq  1e <_main+0xe>
  1e: 31 c0                 xor    %eax,%eax
  20: 5d                    pop    %rbp
  21: c3                    retq  

奇怪的事情发生了,callq 指令后面跟着1e &lt;_main+0xe&gt;。不应该是&lt;__Z1fi&gt;的地址吗?如果不是,main 函数如何调用f 函数?

编辑 仅供参考:

$ g++ -v
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin13.1.0
Thread model: posix

【问题讨论】:

  • 试试objdump -M intel -d tfc.o
  • 我想知道反汇编是否没有显示 callq -> 跳转到 0x00 <__z1fi> ?
  • @ooga 我还是得到了19: e8 00 00 00 00 call 1e &lt;_main+0xe&gt;
  • 查看@GriffinG提供的答案,很有帮助!

标签: c++


【解决方案1】:

调用地址0,即f函数的地址。

e8 是 x86 中的调用指令,根据:

http://www.cs.cmu.edu/~fp/courses/15213-s07/misc/asm64-handout.pdf

call 使用相对于下一条指令的位移,在内存位置 1e。这成为内存位置 0。所以它是 callq 1e,而实际上它正在调用地址 0。

【讨论】:

  • 在您的回答中包括呼叫地址全为零的原因。原因是链接器将在链接后将 ACTUAL 调用地址写入该位置。这就是搬迁。
  • 知道了。链接后我应该会看到反汇编的代码,只需运行g++ tfc.cpp -o tfc即可。
  • 正如 Zan 所说,实际调用地址尚未写入 - 这就是为什么对象有 0 并且反汇编程序报告“callq 1e <_main>” - 在链接时 e8 00 00 00 00 将用 -0x1e 的 32 位有符号值覆盖地址部分,这样 callq 会推送 0x1e 十六进制的返回地址,然后将两者添加到地址 0 处的 __Z1fi 调用。链接后,反汇编将实际显示 -0x1e 字节(E8 FF FF FF E2)和callq __Z1fi
  • @TonyD 在大多数机器上实际上是E8 E2 FF FF FF,因为它是大端表示。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-10
  • 1970-01-01
  • 2017-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多