链接之前用汇编语言调用函数

ark*_*rka 5 x86 assembly gcc x86-64 disassembly

我正在查看编译器生成的汇编代码。我正在使用 C 编程语言和GCC编译器。

我用 C 语言编写了一个函数,它通过调用另一个函数将两个数字相加,并将结果存储在作为参数传递给该函数的指针所指向的变量中。

void add_two_num(int x, int y, int * dest)
{
  int val;

  val = dummy(x, y);
  *dest = val;
}
Run Code Online (Sandbox Code Playgroud)

我将源代码编译为目标代码(链接未完成),然后使用反汇编代码objdump -d

+0x9行中数字的含义是什么call d <add_two_num+0x9>
当该行将被实际的函数调用替换时,这在链接阶段有用吗?

void add_two_num(int x, int y, int * dest)
{
  int val;

  val = dummy(x, y);
  *dest = val;
}
Run Code Online (Sandbox Code Playgroud)

fuz*_*fuz 7

您正在查看一个目标文件。该文件尚未链接,外部函数的地址尚未填写。您可以在指令编码中看到这一点:这00 00 00 00是稍后要修补的实际调用目标的虚拟对象。

不幸的是 objdump 不够聪明,无法在 x86 上了解这一点,因此它会反汇编,就好像偏移量实际上是 一样00 00 00 00,即调用转到下一条指令。该指令0x9位于最后一个标签之后的字节,因此您会看到它将该地址解释为add_two_num+0x9

您可以传递该-r选项objdump以让它显示您的搬迁信息。这样您就知道实际正在调用什么函数。它看起来像这样:

0000000000000000 <add_two_num>:
   0:   53                      push   %rbx
   1:   48 89 d3                mov    %rdx,%rbx
   4:   e8 00 00 00 00          call   9 <add_two_num+0x9>
            5: R_X86_64_PLT32   dummy-0x4
   9:   89 03                   mov    %eax,(%rbx)
   b:   5b                      pop    %rbx
   c:   c3                      ret    
Run Code Online (Sandbox Code Playgroud)