我做了一些实验,其中我创建了一个指向指向printf
的函数的指针类型的局部变量。然后,我定期调用printf
并使用该变量,如下所示:
#include<stdio.h>
typedef int (*func)(const char*,...);
int main()
{
func x=printf;
printf("%p\n", x);
x("%p\n", x);
return 0;
}
我已经编译了它,并使用gdb查看了main的反汇编,得到了以下结果:
0x000000000000063a <+0>: push %rbp
0x000000000000063b <+1>: mov %rsp,%rbp
0x000000000000063e <+4>: sub $0x10,%rsp
0x0000000000000642 <+8>: mov 0x20098f(%rip),%rax # 0x200fd8
0x0000000000000649 <+15>: mov %rax,-0x8(%rbp)
0x000000000000064d <+19>: mov -0x8(%rbp),%rax
0x0000000000000651 <+23>: mov %rax,%rsi
0x0000000000000654 <+26>: lea 0xb9(%rip),%rdi # 0x714
0x000000000000065b <+33>: mov $0x0,%eax
0x0000000000000660 <+38>: callq 0x520 <printf@plt>
0x0000000000000665 <+43>: mov -0x8(%rbp),%rax
0x0000000000000669 <+47>: mov -0x8(%rbp),%rdx
0x000000000000066d <+51>: mov %rax,%rsi
0x0000000000000670 <+54>: lea 0x9d(%rip),%rdi # 0x714
0x0000000000000677 <+61>: mov $0x0,%eax
0x000000000000067c <+66>: callq *%rdx
0x000000000000067e <+68>: mov $0x0,%eax
0x0000000000000683 <+73>: leaveq
0x0000000000000684 <+74>: retq
对我来说奇怪的是,对printf
的调用直接使用plt (不出所料),但使用本地变量调用它的使用完全不同的地址(正如您在程序集的第4行中看到的那样,存储在局部变量x中的值不是plt条目的地址)。
这怎么可能呢?不是所有对未在可执行文件中定义的函数的调用都首先通过plt来获得更好的性能和pic代码吗?
https://stackoverflow.com/questions/56760086
复制相似问题