链接之前,用汇编语言调用功能
我正在浏览编译器生成的装配代码。我正在使用C编程语言和 GCC
编译器。
我在C中编写了一个函数,该函数通过调用另一个函数来增加两个数字,并将结果存储在指向指向该函数的参数指向的变量中。
void add_two_num(int x, int y, int * dest)
{
int val;
val = dummy(x, y);
*dest = val;
}
我将源代码编译为对象代码(未完成链接),然后使用 objdump -d
在行中使用 objdump -d
在行+0x9 是什么含义。 >调用d< add_two_num+0x9> ?
在链接阶段,该线路将被实际函数调用替换时有用吗?
file format elf64-x86-64
0000000000000004 <add_two_num>:
4: 53 push %rbx
5: 48 89 d3 mov %rdx,%rbx
8: e8 00 00 00 00 call d <add_two_num+0x9>
d: 89 03 mov %eax,(%rbx)
f: 5b pop %rbx
10: c3 ret
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您正在查看对象文件。该文件尚未链接,外部功能的地址尚未填写。您可以在指令编码中看到这一点:
00 00 00 00
是稍后对实际调用目标进行修补的假人。不幸的是,Objdump还不够聪明,无法在X86上知道这一点,因此它将偏移量实际上是
00 00 00 00 00
,即呼叫转到下一个指令。该指令是0x9
在上一个标签之后的字节,因此您会看到该地址将其解释为add_two_num+0x9
。您可以将
-r
选项传递给objdump
使其显示重新定位信息。这样,您就会知道实际在称呼什么函数。看起来像这样:You are looking at an object file. This file has not been linked yet and the addresses of external functions have not been filled in yet. You can see this in the instruction encoding: the
00 00 00 00
is a dummy for the actual call target to be patched in later.Unfortunately objdump is not smart enough to know about this on x86, so it disassembles as if the offset was actually
00 00 00 00
, i.e. the call goes to the next instruction. This instruction is0x9
bytes after the last label, so you see it interprets this address asadd_two_num+0x9
.You can pass the
-r
option toobjdump
to have it show you relocation information. This way you know what function is actually being called. It'll look something like this:注意呼叫线上的代码字节;直接操作数是所有零。这显然是接头的占位符。
add_two_num+9
来自以下事实:call>呼叫
是呼叫目的地的偏移,相对于呼叫指令的结束。因此,零操作数意味着呼叫目标是呼叫后的下一个指令,恰好是从add_two_num offset 9处的mov
。拆卸器试图尽最大努力解释呼叫目标的含义,并认为呼叫目标在ADD_TWO_NUM中是(技术上)。Note the code bytes on the call line; the immediate operand is all zeros. This is clearly a placeholder for the linker.
The
add_two_num+9
comes from the fact that the immediate operand oncall
is an offset of the call destination, relative to the end of the call instruction. So a zero operand means the call target is the next instruction after call, which happens to be themov
at offset 9 from add_two_num. The disassembler tries to do its best to interpret the meaning of the call target, and it sees that the call target is (technically) within add_two_num.