gpt4 book ai didi

c - 可执行和可重定位目标文件中的疑问

转载 作者:太空狗 更新时间:2023-10-29 17:05:37 28 4
gpt4 key购买 nike

我编写了一个简单的 Hello World 程序。

   #include <stdio.h>
int main() {
printf("Hello World");
return 0;
}

我想了解可重定位目标文件和可执行文件的外观。main函数对应的目标文件为

0000000000000000 <main>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: bf 00 00 00 00 mov $0x0,%edi
9: b8 00 00 00 00 mov $0x0,%eax
e: e8 00 00 00 00 callq 13 <main+0x13>
13: b8 00 00 00 00 mov $0x0,%eax
18: c9 leaveq
19: c3 retq

这里 printf 的函数调用是 callq 13。我不明白为什么是 13。这意味着调用地址 13 的函数,对吧??。 13 有下一条指令,对吧??请解释一下这是什么意思??

main对应的可执行代码为

00000000004004cc <main>:
4004cc: 55 push %rbp
4004cd: 48 89 e5 mov %rsp,%rbp
4004d0: bf dc 05 40 00 mov $0x4005dc,%edi
4004d5: b8 00 00 00 00 mov $0x0,%eax
4004da: e8 e1 fe ff ff callq 4003c0 <printf@plt>
4004df: b8 00 00 00 00 mov $0x0,%eax
4004e4: c9 leaveq
4004e5: c3 retq

这里是 callq 4003c0。但是二进制指令是e8 e1 fe ff ff。没有对应于 4003c0 的内容。我错了什么?

谢谢。巴拉

最佳答案

在第一种情况下,查看指令编码 - 函数地址所在的位置全为零。那是因为对象还没有被链接,所以外部符号的地址还没有被连接起来。当您最终链接到可执行格式时,系统会在其中插入另一个占位符,然后动态链接器最终会在运行时为 printf() 添加正确的地址。这是我编写的“Hello, world”程序的一个简单示例。

一、目标文件的反汇编:

00000000 <_main>:
0: 8d 4c 24 04 lea 0x4(%esp),%ecx
4: 83 e4 f0 and $0xfffffff0,%esp
7: ff 71 fc pushl -0x4(%ecx)
a: 55 push %ebp
b: 89 e5 mov %esp,%ebp
d: 51 push %ecx
e: 83 ec 04 sub $0x4,%esp
11: e8 00 00 00 00 call 16 <_main+0x16>
16: c7 04 24 00 00 00 00 movl $0x0,(%esp)
1d: e8 00 00 00 00 call 22 <_main+0x22>
22: b8 00 00 00 00 mov $0x0,%eax
27: 83 c4 04 add $0x4,%esp
2a: 59 pop %ecx
2b: 5d pop %ebp
2c: 8d 61 fc lea -0x4(%ecx),%esp
2f: c3 ret

然后是搬迁:

main.o:     file format pe-i386

RELOCATION RECORDS FOR [.text]:
OFFSET TYPE VALUE
00000012 DISP32 ___main
00000019 dir32 .rdata
0000001e DISP32 _puts

如您所见,那里有一个用于 _puts 的重定位,这是对 printf 调用的结果。该重定位将在链接时引起注意并得到修复。在动态库链接的情况下,在程序运行之前,重定位和修复可能不会完全解决,但我希望您会从这个示例中得到启发。

关于c - 可执行和可重定位目标文件中的疑问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2784874/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com