【动态库与静态库】-3-静态链接与加载

静态链接与加载

准备好两个文件:

c 复制代码
// hello.c
#include <stdio.h>

void run();

int main()
{
    printf("hello world.\n");
    run();

    return 0;
}
c 复制代码
// code.c
#include <stdio.h>

void run()
{
    printf("running...\n");
}

静态编译成可执行文件main。(static)

然后使用objdump指令,做好文件code.s hello.s main.s,以方便观察其中信息。

1、静态链接------函数地址重定向

目标文件.o为什么执行不了呢?

除了一些使用的方法没有定义,.o执行不了的另一个原因,就是.o文件涉及函数调用的位置,无法定位被调用函数的地址。即调用函数的地址没有被设置。







而编译器在链接成可执行文件的过程中,就设置好了要去到的地址。未来CPU根据这些地址,就能找到对应的方法。





静态链接做的工作,除了把要用到的方法全部拷贝到可执行文件中,还有一件事,就是对.o文件的函数地址进行重定向。所以.o文件又叫做"可重定位目标文件"。

2、再谈虚拟地址------逻辑地址与虚拟地址

上面说编译器在链接的过程中就已经设置好了地址。我们观察.s汇编文件也确实看到了地址。但这与我们之前的"操作系统设置地址"的观念不符。

事实上,代码、变量等数据的地址,在静态编译中就是由编译器在链接形成可执行文件过程中确定的。

如何理解我们在.s文件中看到的地址?

可执行程序的地址分为三类:逻辑地址、虚拟地址、物理地址



地址类别 内涵解释
逻辑地址 数据在磁盘中地址的叫法。相对编址,即起始地址 + 偏移量
虚拟地址 数据加载到内存中地址的叫法,其实和逻辑地址是几乎等价的。绝对编址,也是起始地址 + 偏移量,只不过起始地址是0x0
物理地址 加载时由操作系统分配


比如,我们在.s文件中看到的地址,就是逻辑地址 。



内存中CPU根据输入的虚拟地址 ,在页表中查找物理地址,然后找到并执行指令。

而相对编址的方法,可以和绝对编址合并,因为起始地址都可以从0x0开始。合并的结果就是"平坦模式编址",也就是虚拟地址的编址方式。

3、静态加载

静态链接形成的可执行文件,加载到内存中,需要经过如下的一系列过程。我们用一张图就能搞定。

相关推荐
谙弆悕博士1 小时前
debian快速换源
linux·运维·windows·debian·下载·换源·网络问题
.道阻且长.2 小时前
Linux基本开发工具:编译器gcc/g++
linux·运维·服务器·职场和发展
Industio_触觉智能2 小时前
瑞芯微RK系列调试工具与量产测试手册-上|串口日志打通与JTAG兜底调试
linux·sdk·jtag·瑞芯微·调试工具·rk3576·量产调试
HideF10 小时前
Linux
linux·服务器·网络
Ruiery12 小时前
Linux 6.6内核内存管理深度解析(十三):slab/slub 分配器
linux·运维·服务器
丰锋ff15 小时前
压缩命令笔记
linux
GeW16 小时前
产业新优势基础软件的人才底盘,从Linux与数据库开始
linux·数据库
by2099916 小时前
Linux GCC/G++ 编译与 Makefile 构建
linux·运维·服务器·经验分享
cq林志炫17 小时前
两个Linux服务器之间同步文件
linux·运维·服务器