欢迎来到三一办公! | 帮助中心 三一办公31ppt.com(应用文档模板下载平台)
三一办公
全部分类
  • 办公文档>
  • PPT模板>
  • 建筑/施工/环境>
  • 毕业设计>
  • 工程图纸>
  • 教育教学>
  • 素材源码>
  • 生活休闲>
  • 临时分类>
  • ImageVerifierCode 换一换
    首页 三一办公 > 资源分类 > PPT文档下载  

    《程序的链接》PPT课件.ppt

    • 资源ID:5564363       资源大小:533KB        全文页数:49页
    • 资源格式: PPT        下载积分:15金币
    快捷下载 游客一键下载
    会员登录下载
    三方登录下载: 微信开放平台登录 QQ登录  
    下载资源需要15金币
    邮箱/手机:
    温馨提示:
    用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP免费专享
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    《程序的链接》PPT课件.ppt

    本学期考核方法,本学期平时分占60%,期末考试占40%小测试共2次,每次6分,共20分作业加考勤基础分20分,少一次扣4分,作业不交加考勤不到场超过5次将取消考试资格。实验课有两个实验,每次10分,共20各种加分,回答问题,实验提前做完等。期末考试形式为闭卷考试,第四章 程序的链接目标文件格式符号解析与重定位共享库与动态链接,可执行文件的链接生成,主要教学目标使学生了解链接器是如何工作的,从而能够养成良好的程序设计习惯,并增加程序调试能力。通过了解可执行文件的存储器映像来进一步深入理解进程的虚拟地址空间的概念。包括以下内容链接和静态链接概念三种目标文件格式符号及符号表、符号解析使用静态库链接重定位信息及重定位过程可执行文件的存储器映像可执行文件的加载共享(动态)库链接,程序的链接,分以下三个部分介绍第一讲:目标文件格式程序的链接概述、链接的意义与过程ELF目标文件、重定位目标文件格式、可执行目标文件格式第二讲:符号解析与重定位符号和符号表、符号解析与静态库的链接重定位信息第三讲:动态链接动态链接的特性、程序加载时的动态链接、程序运行时的动态链接,一个典型程序的转换处理过程,1#include 23 int main()4 5 printf(hello,worldn);6,经典的“hello.c”C-源程序,#i n c l u d e n n i n t m a i n()n 104 62 10 10 105 110 116 32 109 97 105 110 40 41 10 123n p r i n t f(h e l10 32 32 32 32 112 114 105 110 116 102 40 34 104 101 108l o,w o r l d n);n 108 111 44 32 119 111 114 108 100 92 110 34 41 59 10 125,hello.c的ASCII文本表示,计算机能够直接识别hello.c源程序吗?,不能,需要转换为机器语言代码!即:编译、汇编等,功能:输出“hello,world”,一个C语言程序举例,int buf2=1,2;void swap();int main()swap();return 0;,main.c,swap.c,extern int buf;int*bufp0=,(1)预处理(cpp)。在高级语言源程序中插入所有用#include命令指定的文件和用#define声明指定的宏。(2)编译(cc1)。将预处理后的源程序文件编译生成相应的汇编语言程序。(3)汇编(as)。由汇编程序将汇编语言源程序文件转换为可重定位目标文件。(4)链接(ld)。由链接器将多个可重定位目标文件及库例程(如printf.o)链接起来,生成可执行文件。,可执行文件的生成,使用GCC编译器编译并链接生成可执行程序P:unix gcc-O2-g-o p main.c swap.cunix./p,GCC编译器的静态链接过程,引用符号的地址需要重定位,main(),main.o,int*bufp0=&buf0,swap(),swap.o,System code,int buf2=1,2,System data,可重定位目标文件,可执行目标文件,.text,.data,.text,.data,.text,.data,static int*bufp1,.bss,虽然是swap的本地符号,也需在.bss节重定位,使用链接的优点,链接带来的好处1:模块化(1)一个程序可以分成很多源程序文件(2)可构建公共函数库,如数学库,标准C库等,链接带来的好处2:效率高(1)时间上,可分开编译只需重新编译修改的源程序文件,然后重新链接(2)空间上,无需包含共享库所有代码 源文件中无需包含共享库函数的源码,只要直接调用即可 可执行文件和运行时的内存中只需包含所调用函数的代码 而不需要包含整个共享库,链接操作的步骤,Step 1.符号解析(Symbol resolution)程序中有定义和引用的符号(包括变量和函数等)void swap()/*定义符号swap*/swap();/*引用符号swap*/int*xp=/*定义符号 xp,引用符号 x*/编译器将定义的符号存放在一个符号表(symbol table)中.符号表是一个结构数组每个表项包含符号名、长度和位置等信息链接器将每个符号的引用都与一个确定的符号定义建立关联Step 2.重定位将多个代码段与数据段分别合并为一个单独的代码段和数据段将.o文件中每个符号的相对位置重定位为可执行文件中的绝对存储位置将原来符号表中的位置信息修改为重定位后的位置信息,三类目标文件,可重定位目标文件(.o file)其代码和数据可和其他可重定位文件合并为可执行文件每个.o 文件由对应的.c文件生成每个.o文件代码和数据地址都从0开始可执行目标文件(.a file)包含的代码和数据可以被直接复制到内存并被执行代码和数据地址为虚拟地址空间中的地址共享的目标文件(.so file)特殊的可重定位目标文件,能在装入或运行时被装入到内存并自动被链接Windows 中称其为 Dynamic Link Libraries(DLLs),00000000:0:55 push%ebp 1:89 e5 mov%esp,%ebp 3:83 ec 10 sub$0 x10,%esp6:8b 45 0c mov 0 xc(%ebp),%eax 9:8b 55 08 mov 0 x8(%ebp),%edx c:8d 04 02 lea(%edx,%eax,1),%eax f:89 45 fc mov%eax,-0 x4(%ebp)12:8b 45 fc mov-0 x4(%ebp),%eax 15:c9 leave 16:c3 ret,080483d4:80483d4:55 push%ebp 80483d5:89 e5 mov%esp,%ebp 80483d7:83 ec 10 sub$0 x10,%esp 80483da:8b 45 0c mov 0 xc(%ebp),%eax 80483dd:8b 55 08 mov 0 x8(%ebp),%edx 80483e0:8d 04 02 lea(%edx,%eax,1),%eax 80483e3:89 45 fc mov%eax,-0 x4(%ebp)80483e6:8b 45 fc mov-0 x4(%ebp),%eax 80483e9:c9 leave 80483ea:c3 ret,objdump-d test.o,objdump-d test,/*main.c*/int add(int,int);int main()return add(20,13);,/*test.c*/int add(int i,int j)int x=i+j;return x;,Executable and Linkable Format(ELF),两种视图 链接视图:Relocatable object files执行视图:Executable object files,节(section)是 ELF 文件中具有相同特征的最小可处理单位.text节:代码.data节:数据.rodata:只读数据.bss:未初始化数据,由不同的段(segment)组成,描述节如何映射到存储段中,可多个节映射到同一段,如:可合并.data节和.bss节,并映射到一个可读可写数据段中,可重定位目标文件格式,ELF 头占16字节,包括字长、字节序(大端/小端)、文件类型(.o,exec,.so)、机器类型(如 IA-32)、节头表的偏移、节头表的表项大小及表项个数.text 节编译后的代码部分.rodata 节只读数据,如 printf 格式串、switch 跳转表等.data 节已初始化的全局变量.bss 节未初始化全局变量,仅是占位符,不占据任何实际磁盘空间。目标文件格式区分初始化和非初始化是为了空间效率,可重定位目标文件格式,.symtab 节存放函数和全局变量(符号表)信息,它不包括局部变量条目.rel.text 节.text节的重定位信息,用于重新修改代码段的指令中的地址信息.rel.data 节.data节的重定位信息,用于对被模块使用或定义的全局变量进行重定位的信息.debug 节调试用符号表(gcc-g)strtab 节包含symtab和debug节中符号及节名Section header table(节头表)每个节的节名、偏移和大小,可执行目标文件格式,与.o文件稍有不同:ELF头中字段e_entry给出执行程序时第一条指令的地址,而在可重定位文件中,此字段为0多一个.init节,用于定义_init函数,该函数用来进行可执行目标文件开始执行时的初始化工作少两.rel节(无需重定位)多一个程序头表,也称段头表(segment header table),是一个结构数组,可执行文件的存储器映像,0,%esp(栈顶),brk,0 xC00000000,0 x08048000,从可执行文件装入,程序(段)头表描述如何映射,可执行文件中的程序头表,typedef struct Elf32_Word p_type;Elf32_Off p_offset;Elf32_Addr p_vaddr;Elf32_Addr p_paddr;Elf32_Word p_filesz;Elf32_Word p_memsz;Elf32_Word p_flags;Elf32_Word p_align;Elf32_Phdr;,程序头表能够描述可执行文件中的节与虚拟空间中的存储段之间的映射关系一个表项说明虚拟地址空间中一个连续的片段或一个特殊的节 以下是GNU READELF显示的某可执行目标文件的程序头表信息,可执行文件中的程序头表,程序头表中有8个表项,其中有两个是可装入段(type=LOAD)对应表项。第一可装入段对应第0 x000000 x004d3字节(包括ELF头、程序头表、.init、.text和.rodata节),映射到虚拟地址0 x8048000开始长度为0 x4d4字节的区域,按0 x1000=212=4K字节对齐,具有只读/执行权限(Flg=RE),是只读代码段(read-only code)。第二可装入段对应第0 x000f0c开始长度为0 x108字节的.data节,映射到虚拟地址0 x8049f0c开始的长度为0 x110字节的存储区域,在0 x110=272字节的存储区中,前0 x108=264字节用.data节内容初始化,而后面272-264=8个字节对应.bss节,初始化为0,该段按0 x1000=4KB对齐,具有可读可写权限(Flg=RW),因此,它是一个可读写数据段(read/write data segment)。,程序的链接,分以下三个部分介绍第一讲:目标文件格式程序的链接概述、链接的意义与过程ELF目标文件、重定位目标文件格式、可执行目标文件格式第二讲:符号解析与重定位符号和符号表、符号解析与静态库的链接重定位信息第三讲:动态链接动态链接的特性、程序加载时的动态链接、程序运行时的动态链接,符号和符号解析,每个可重定位目标模块m都有一个符号表,它包含了在m中定义和引用的所有符号。有三种链接器符号:Global symbols(模块内部定义的全局符号)由模块m定义并能被其他模块引用的符号。例如,非static C函数和非static的C全局变量(指不带static的全局变量)如,main.c 中的全局变量名bufExternal symbols(外部定义的全局符号)由其他模块定义并被模块m引用的全局符号 如,main.c 中的函数名swapLocal symbols(本模块的局部符号)仅由模块m定义和引用的本地符号。例如,在模块m中定义的带static的C函数和全局变量如,swap.c 中的static变量名bufp1 链接器局部符号不是指程序中的局部变量(分配在栈中的临时性变量),链接器不关心这种局部变量,符号和符号解析,int buf2=1,2;void swap();int main()swap();return 0;,main.c,extern int buf;int*bufp0=,swap.c,Global,External,External,Local,Global,局部变量,目标文件中的符号表,符号表(symtab)中每个条目的结构如下,typedef struct int name;/*指向符号对应字符串在strtab节中的偏移*/int value;/*在对应section中的偏移量,可执行文件中是虚拟地址*/int size;/*符号对应目标所占字节数*/char type:4,/*符号对应目标的类型:数据、函数、源文件、节*/binding:4;/*符号对应目标是全局符号还是局部符号*/char reserved;char section;/*符号对应目标所在的section,或其他情况*/Elf_Symbol;,其他情况:ABS表示不该被重定位;UND表示未定义;COM表示未初始化数据(.bss),此时,value表示对齐要求,size给出最小大小,目标文件中的符号表,main.o中的符号表中最后三个条目,Num:valueSizeTypeBindOtNdxName8:08DataGlobal 03buf9:033FuncGlobal01main10:00NotypeGlobal0UNDswap,swap.o中的符号表中最后4个条目,Num:valueSizeType Bind OtNdxName8:04 Data Global 03bufp09:00 Notype Global 0UND buf10:036 Func Global 01swap11:44 Data Local 0COMbufp1,buf是main.o中第3节(.data)偏移为0的符号,是全局变量,占8B;main是第1节(.text)偏移为0的符号,是全局函数,占33B;swap是main.o中未定义的符号,不知道类型和大小,全局的(在其他模块定义),bufp1是未分配地址且未初始化的本地变量(ndx=COM),按4B对齐且占4B,符号解析,目的:将每个模块中引用的符号与某个目标模块中的定义符号建立关联。每个定义符号在代码段或数据段中都被分配了存储空间,将引用符号与对应定义符号建立关联后,就可在重定位时将引用符号的地址重定位为相关联的定义符号的地址。本地符号在本模块内定义并引用,因此,其解析较简单,只要与本模块内唯一的定义符号关联即可。全局符号(外部定义的、内部定义的)的解析涉及多个模块,故较复杂,“符号的定义”其实质是什么?,是指符号被分配了虚拟地址空间。符号为函数名即指其代码所在区;符号为变量即指其占的静态数据区。,全局符号的符号解析,全局符号的强/弱特性函数名和已初始化的全局变量名是强符号未初始化的全局变量名是弱符号,int foo=5;p1(),int foo;p2(),p1.c,p2.c,以下符号哪些是强符号?哪些是弱符号?,全局符号的符号解析,int buf2=1,2;void swap();int main()swap();return 0;,main.c,extern int buf;int*bufp0=,swap.c,强符号,此处为引用,弱符号,本地符号,强符号,局部变量,以下符号哪些是强符号?哪些是弱符号?,链接器对符号的解析规则,多重定义符号的处理规则 Rule 1:强符号不能多次定义强符号只能被定义一次,否则链接错误 Rule 2:若一个符号被定义为一次强符号和多次弱符号,则按强定义为准对弱符号的引用被解析为其强定义符号 Rule 3:若有多个弱符号定义,则任选其中一个使用命令 gcc fno-common链接时,会告诉链接器在遇到多个弱定义的全局符号时输出一条警告信息。,多重定义符号的解析举例,int x=10;int p1(void);int main()x=p1();return x;,main.c,int x=20;int p1()return x;,p1.c,main只有一次强定义p1有一次强定义,一次弱定义x有两次强定义,所以,链接器将输出一条出错信息,以下程序会发生链接出错吗?,多重定义符号的解析举例,p1.c,y一次强定义,一次弱定义z两次弱定义p1一次强定义,一次弱定义main一次强定义,#include int y=100;int z;void p1(void);int main()z=1000;p1();printf(“y=%d,z=%dn”,y,z);return 0;,main.c,int y;int z;void p1()y=200;z=2000;,问题:打印结果是什么?y=200,z=2000,以下程序会发生链接出错吗?,该例说明:在两个不同模块定义相同变量名,很可能发生意想不到的结果!,多重定义符号的解析举例,p1.c,该例说明:两个重复定义的变量具有不同类型时,更容易出现难以理解的结果!,main.c,问题:打印结果是什么?d=0,x=1 072 693 248,以下程序会发生链接出错吗?,1#include 2 int d=100;3 int x=200;4 void p1(void);5 int main()6 7 p1();8 printf(“d=%d,x=%dn”,d,x);9 return 0;10,1 double d;23 void p1()4 5 d=1.0;6,p1执行后d和x处内容是什么?,1.0:0 01111111111 00B=3FF0 0000 0000 0000H,多重定义符号的解析举例,打印结果:d=0,x=1 072 693 248Why?,1 double d;2 3 void p1()4 5 d=1.0;6,.1 int d=100;2 int x=200;3 int main()4 5 p1();6 printf(“d=%d,x=%dn”,d,x);7 return 0;8,main.c p1.c,理解该问题需要知道:机器级数据的表示与存储链接器的符号解析规则,double型数1.0对应的机器数3FF0 0000 0000 0000H,IA-32是小端方式,多重定义全局符号的问题,尽量避免使用全局变量一定需要用的话,就按以下规则使用尽量使用本地变量(static)全局变量要赋初值外部全局变量要使用extern,多重定义全局变量会造成一些意想不到的错误,而且是默默发生的,编译系统不会警告,并会在程序执行很久后才能表现出来,且远离错误引发处。特别是在一个具有几百个模块的大型软件中,这类错误很难修正。大部分程序员并不了解链接器如何工作,因而养成良好的编程习惯是非常重要的。,头文件(.h文件)的作用,#include global.hint f()return g+1;,c1.c,global.h,#ifdef INITIALIZE int g=23;static int init=1;#else int g;static int init=0;#endif,#include#include global.hint main()if(!init)g=37;int t=f();printf(Calling f yields%dn,t);return 0;,c2.c,预处理操作,#include global.hint f()return g+1;,c1.c,global.h,#ifdef INITIALIZE int g=23;static int init=1;#else int g;static int init=0;#endif,int g=23;static int init=1;int f()return g+1;,int g;static int init=0;int f()return g+1;,定义 INITIALIZE,没有定义 INITIALIZE,#include指示被执行,插入.h文件的内容到源文件中,如何划分模块?,许多函数无需自己写,可使用共享库函数Math,I/O,memory management,string manipulation,etc.避免以下两种极端做法将所有函数都放在一个源文件中修改一个函数需要对所有函数重新编译时间和空间两方面的效率都不高一个函数放在一个源文件中需要程序员显式地进行链接效率高,但模块太多,故太繁琐,静态共享库,静态库(.a archive files)将所有相关的目标模块打包为一个单独的文件,称为静态库文件,也称为存档文件(archive)增强链接器功能,使其能通过查找一个或多个库文件中的符号来解析符号在构建可执行文件时只需指定库文件名,链接器会自动到库中寻找那些应用程序用到的目标模块,并且只把用到的模块从库中拷贝出来在gcc命令行中无需明显指定C标准库libc.a(默认库),静态库的创建,Translator,atoi.c,atoi.o,Translator,printf.c,printf.o,libc.a,Archiver(ar),.,Translator,random.c,random.o,unixar rs libc.a atoi.o printf.o random.o,C standard library,Archiver(归档器)允许增量更新,只要重新编译需修改的源码并将其.o文件替换到静态库中。,自定义一个静态库文件,#include void myfunc1()printf(%s,This is myfunc1!n);,#include void myfunc2()printf(%s,This is myfunc2n);,gcc c myproc1.c myproc2.car rcs mylib.a myproc1.o myproc2.o,myproc1.c,myproc2.c,链接器中符号解析的全过程,void myfunc1(viod);int main()myfunc1();return 0;,main.c,调用关系:mainmyfunc1printf,gcc c main.c gcc static o myproc main.o./mylib.a,开始E、U、D为空,首先扫描main.o,把它加入E,同时把myfun1加入U,main加入D。接着扫描到mylib.a,将U中所有符号(本例中为myfunc1)与mylib.a中所有目标模块(myproc1.o和myproc2.o)依次匹配,发现在myproc1.o中定义了myfunc1,故myproc1.o加入E,myfunc1从U转移到D。在myproc1.o中发现还有未解析符号printf,将其加到U。不断在mylib.a的各模块上进行迭代以匹配U中的符号,直到U、D都不再变化。此时U中只有一个未解析符号printf,而D中有main和myfunc1。因为模块myproc2.o没有被加入E中,因而它被丢弃。,E 将被合并以组成可执行文件的所有目标文件集合U 当前所有未解析的引用符号的集合D 当前所有定义符号的集合,接着,扫描默认的库文件libc.a,发现其目标模块printf.o定义了printf,于是printf也从U移到D,并将printf.o加入E,同时把它定义的所有符号加入D,而所有未解析符号加入U。处理完libc.a时,U一定是空的。,libc.a无需明显指出!,链接器中符号解析的全过程,main.c,void myfunc1(viod);int main()myfunc1();return 0;,gcc c main.c gcc static o myproc main.o./mylib.a,问题:若命令为:gcc static o myproc./mylib.a main.o,结果怎样?,main.o中的myfunc1不能被解析,故出现链接错误!,链接顺序问题,假设调用关系如下:func.o libx.a 和 liby.a 中的函数 libx.a libz.a 中的函数 libx.a 和 liby.a 之间、liby.a 和 libz.a 相互独立 则以下几个命令行都是可行的:gcc-static o myfunc func.o libx.a liby.a libz.agcc-static o myfunc func.o liby.a libx.a libz.agcc-static o myfunc func.o libx.a libz.a liby.a假设调用关系如下:func.o libx.a 和 liby.a 中的函数 libx.a liby.a 同时 liby.a libx.a 则以下命令行可行:gcc-static o myfunc func.o libx.a liby.a libx.a,重定位,符号解析完成后,可进行重定位工作,分两步对节和定义符号进行重定位将集合E的所有目标模块中相同的节合并成新节,并将运行时的虚拟地址赋给每个新节中所有的定义符号。例如,所有.text节合并作为可执行文件中的.text节,并为每个.text节确定在新.text节中的绝对地址,从而为其中定义的函数确定首地址(含有多个函数时),进而确定每条指令的地址。完成这一步后,每条指令和每个全局变量都可确定地址。对节中的引用符号进行重定位修改.text节和.data节中对每个符号的引用(地址)。需要用到在.rel_data和.rel_text节中保存的重定位信息。,重定位信息,汇编器遇到对位置未知的目标引用时,生成一个重定位条目数据引用的重定位条目在.rel_data节中指令中引用的重定位条目在.rel_text节中ELF中重定位条目格式如下:有两种最基本的重定位类型R_386_PC32:使用32位PC相对地址的引用,重定位指令R_386_32:使用32位绝对地址重定位数据,typedef struct int offset;/*需重定位的引用的节偏移*/int symbol:24,/*需重定位的引用所指向的符号*/type:8;/*重定位类型(即修改方式)*/Elf32_Rel;,例如,在rel_text节中有重定位条目 offset:0 x12 symbol:swap type:R_386_PC32,说明在.text节中偏移为0 x12的地方需重定位,按PC相对地址方式修改,引用的符号为swap,程序的链接,分以下三个部分介绍第一讲:目标文件格式程序的链接概述、链接的意义与过程ELF目标文件、重定位目标文件格式、可执行目标文件格式第二讲:符号解析与重定位符号和符号表、符号解析与静态库的链接重定位信息第三讲:动态链接动态链接的特性、程序加载时的动态链接、程序运行时的动态链接,动态链接的共享库(Shared Libraries),静态库有一些缺点:静态库中的常用函数(如printf)被包含在每一个运行进程的代码段中,这对于并发运行50-100个进程的系统,造成极大的主存资源浪费程序员需关注是否有新版本出现,并须定期维护和更新链接现代解决方案:Shared Libraries 是一个目标文件,包含有代码和数据可以动态地在装入时或运行时被加载并链接也被称为 dynamic link libraries(动态链接库),DLLs,.so files,共享库(Shared Libraries),动态链接可以按以下两种方式进行:在第一次加载并运行时进行(load-time linking).Linux通常由动态链接器(ld-linux.so)自动处理 标准C库(libc.so)通常按这种方式动态被链接在已经开始运行后进行(run-time linking).在Linux中,通过调用 dlopen()接口来实现.Distributing software.High-performance web servers.Runtime library interpositioning.共享库例程在系统中只有一个备份,被所有进程共享,本章小结,链接处理涉及到三种目标文件格式:可重定位目标文件、可执行目标文件和共享目标文件。共享库文件是一种特殊的可重定位目标。ELF目标文件格式有链接视图和执行视图两种,前者是可重定位目标格式,后者是可执行目标格式。链接视图中包含ELF头、各个节以及节头表执行视图中包含ELF头、程序头表(段头表)以及各种节组成的段链接分为静态链接和动态链接两种静态链接将多个可重定位目标模块中相同类型的节合并起来,以生成完全链接的可执行目标文件,其中所有符号的引用都是在虚拟地址空间中确定的最终地址,因而可以直接被加载执行。动态链接的可执行目标文件是部分链接的,还有一部分符号的引用地址没有确定,需要利用共享库中定义的符号进行重定位,因而需要由动态链接器来加载共享库并重定位可执行文件中部分符号的引用。加载时进行共享库的动态链接执行时进行共享库的动态链接,本章小结,链接过程需要完成符号解析和重定位两方面的工作符号解析的目的就是将符号的引用与符号的定义关联起来重定位的目的是分别合并代码和数据,并根据代码和数据在虚拟地址空间中的位置,确定每个符号的最终存储地址,然后根据符号的确切地址来修改符号的引用处的地址。在不同目标模块中可能会定义相同符号,因为相同的多个符号只能分配一个地址,因而链接器需要确定以哪个符号为准。编译器通过对定义符号标识其为强符号还是弱符号,由链接器根据一套规则来确定多重定义符号中哪个是唯一的定义符号,如果不了解这些规则,则可能无法理解程序执行的有些结果。加载器在加载可执行目标文件时,实际上只是把可执行目标文件中的只读代码段和可读写数据段通过页表映射到了虚拟地址空间中确定的位置,并没有真正把代码和数据从磁盘装入主存。,

    注意事项

    本文(《程序的链接》PPT课件.ppt)为本站会员(小飞机)主动上传,三一办公仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知三一办公(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    备案号:宁ICP备20000045号-2

    经营许可证:宁B2-20210002

    宁公网安备 64010402000987号

    三一办公
    收起
    展开