动态链接和静态链接

1.基本概念

1.加载地址

  程序中指令和变量等加载到RAM上的地址。每一个程序一开始都是存放在flash中的,而运行是在内存中,这个时候就需要从flash中将指令读取到内存中(运行地址),flash的地址就是加载地址。所以,加载地址指的是将代码从一个地址A搬移到地址B,这时候地址A就是加载地址。

2.运行地址

  CPU执行一条程序中指令的执行地址,也就是PC寄存器中的值。更简单的讲,就是要寻址到一个指令或者变量所使用的地址。程序实际在内存中运行时候的地址,比如CPU要执行一条指令,那么必然要通过给PC赋值,从对应的地址空间中去取出来,那么这个地址就是实际的运行地址。运行地址是动态的,如果你将程序加载到内存中时,改变存放在内存的地址,那么运行地址也就随之改变了。注意,CPU同样不关心运行地址是虚拟地址还是物理地址。

3.链接地址

链接
  链接过程中链接器为指令和变量分配的地址。在程序编译的时候,每个目标文件都是由源代码编译得到,最终多个目标文件链接生成一个最终的可执行文件,而链接地址就是指示链接器,各个目标文件的在可执行程序中的位置。比如,一个可执行程序a.out由a.o、b.o、c.o组成,那么最终的a.out中谁在前、谁在中间、谁在结尾,都可以通过制定链接地址来决定。链接地址是静态的,在进行程序编译的时候指定的。
注意,对于CPU来说是不管你这个链接地址是物理地址还是虚拟地址。

4.地址之间联系(迷糊)

  运行地址并不一定完全和链接地址相同,也不一定完全和加载地址相同。和PC值相关的就是位置无关代码(相对偏移)如指令mov、b,和PC无关的就是位置相关代码(绝对值)如指令ldr。

本质区别就是:指令中相关地址是运行地址还是链接地址,如果是运行地址那么就是位置无关代码,因为运行地址是变化的相对量;如果是加载地址,那么就是绝对量(链接时候指定了的),这就是位置相关代码了。

  1. 如果没有打开MMU,并且使用的是位置相关设计,那么加载地址、运行地址、链接地址三者需要一致。需要保证链接地址和加载地址是一致的,否则会导致程序跑飞,从uboot上可以理解。
  2. 当打开MMU之前,如果使用的是位置无关设计,那么运行地址和加载地址应该是一致的。如果打开了MMU,那么运行地址和链接地址相同。硬件会根据运行地址进行计算并自动寻址到对应的加载地址上。

2.静态链接

1.概念介绍

  静态链接库工程编译后,生成.lib文件。在目的程序使用静态链接库的场合,直接将.lib文件中的全部函数链接到目的程序中,即在链接的时候就链接好。运行生成的目的程序的场合,不再需要.lib文件就可以直接运行。当静态链接库发生变化的场合,目的程序必须要重新编译,否则执行时静态链接库的内容没有更新。

2.静态链接的大致过程

  静态链接分为两步第一步为相似段的合并,将.data和.text等段进行合并,然后分配各个段的初始地址。第二步主要是各个段内的符号进行重定位。每个段都有对应的.rel.XX重定位表。那么链接器就会去查找由输入目标文件的符号表组成的全局符号表中查找相应的符号进行重定位。

3.应用场合

  因为静态链接库会使得.exe文件的size变大,并且相对于动态链接库运行速度更快。故静态链接库适用于小型应用的开发。

3.动态链接

1.概念介绍

  动态链接库工程编译后,so(linux)和dll(win)文件。 .dll文件是作为共享函数库的可执行文件。不同编程语言编写的程序只要按照函数调用约定就可以调用同一个dll函数库。DLL文件的内容发生变化时,只要输出接口不变(即名称、参数、返回值类型和调用约定不变),更换dll文件就好,EXE文件不用再次编译也可以在执行时更新调用DLL函数的内容。极大地提高了可维护性和可扩展性。运行程序时,必须保证.dll是存在的,否则会出错。

2.应用场合

  1. 因为静态链接库不能链接其它链接库,无论静态接库或者动态链接库。所以,当该链接库还需要链接其它的链接库,包括静态或者动态链接库的场合,应该使用动态链接库。
  2. 因为动态链接库.dll可以独立于.exe而存在,当开发大型软件的场合,或者说多个应用程序需要链接到该.dll时,.dll的逻辑需要修正的场合,其应用程序不需要再次编译。减少软件的耦合。
  3. 由于动态链接库.dll可以链接到不同编程语言的工程,所以对于多语言的软件开发的场合也是适用的。

4.静态链接和动态链接的区别

  lib是编译时用到的,dll(so)是运行时用到的。如果要完成源代码的编译,只需要lib;如果要使动态链接的程序运行起来,只需要dll。
  在链接过程中,静态链接和动态链接就出现了区别。静态链接的过程就已经把要链接的内容已经链接到了生成的可执行文件中,就算你在去把静态库删除也不会影响可执行程序的执行;而动态链接这个过程却没有把内容链接进去,而是在执行的过程中,再去找要链接的内容,生成的可执行文件中并没有要链接的内容,所以当你删除动态库时,可执行程序就不能运行。

#秋招##面试#
武功秘籍--嵌入式 文章被收录于专栏

嵌入式学习笔记 内容设计C语言基础知识、Linux内存管理、操作系统、Linux进程&线程、串口协议、硬件、RAM汇编等 希望秋招的同学早点下车

全部评论
学到了
点赞 回复 分享
发布于 2022-11-20 11:01 上海
不错zi~
点赞 回复 分享
发布于 2022-10-24 10:48 上海
讲的很详细,明白了
点赞 回复 分享
发布于 2022-10-23 11:32 陕西

相关推荐

qq乃乃好喝到咩噗茶:院校后面加上211标签,放大加粗,招呼语也写上211
点赞 评论 收藏
分享
评论
3
11
分享

创作者周榜

更多
牛客网
牛客企业服务