gpt4 book ai didi

c - 函数调用是如何解决的?

转载 作者:太空宇宙 更新时间:2023-11-04 03:38:29 25 4
gpt4 key购买 nike

调用函数时,执行将转移到函数指针指示的点。在执行开始时,可​​执行代码必须从磁盘加载。

如何调用正确的函数指针?可执行代码不会每次都映射到同一位置的虚拟内存中,对吗?那么运行时如何确保对函数的调用始终调用正确的函数,即使每次执行的可执行代码的位置都不同?

考虑以下代码:

void func(void); //Func defined in another dynamic library

int main()
{
func();
//How is the pointer to func known if the file containing func is loaded from disk at run time?
};

最佳答案

解析函数指针的方式真的很简单。当编译器链吐出可执行二进制文件时,所有内部地址都与“基地址”相关。在某些可执行格式中,此基地址是指定的,在其他格式中则是隐含的。

基本上,编译器说它假设执行将从地址 A 开始。运行时决定它实际上应该从 B 开始。然后运行时减去 A 并将 B 添加到二进制文件中的所有非相对地址,然后再执行它。

这个过程也适用于 DLL 之类的东西。动态库存储相对于指向每个导出函数的基指针的地址列表。名称通常也与列表相关联,因此您可以通过名称引用函数。加载库时,地址转换将应用于所有内容,包括地址表。届时,调用者只需在转换后的表中查找地址,然后他们就会获得给定函数的绝对地址。

在很久很久以前(在某些情况下甚至是今天)的旧操作系统中,在地址空间布局随机化、内存页和多任务操作系统之前,程序只会被复制到指定的基地址然后执行的内存。

在现代操作系统中,可能会发生以下几种情况之一,具体取决于平台和应用程序的功能或要求。大多数操作系统都按照我在第二段中描述的方式处理 native 二进制文件,但是某些应用程序(例如在更高版本的体系结构上运行 16 位 x86)可能涉及更复杂的策略。其中一种策略涉及为代码提供静态虚拟地址空间。这有各种限制,例如如果您希望它与外部代码(如窗口控制台或网络堆栈)交互,则需要仿真/兼容层。

不过,随着对 16 位支持的需求下降,这种方案的使用越来越少。为所有程序提供它们自己的唯一地址空间(而不是让它重叠)促进共享库、服务和其他共享好东西的使用。

关于c - 函数调用是如何解决的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30406290/

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