名词解释
- 链接
将所有关联的可重定位目标文件组合起来,以生成一个可执行文件
- 可重定位文件
- 可执行文件
- 符号解析
将每一个符号的引用于一个确定的符号敬意建立关联
- 重定位
- ELF头
位于ELF文件开始,包含文件结构说明信息。定义了ELF魔数、版本、小端/大端、操作系统平台、目标文件的类型、机器结构类型、节头表的起始位置和长度等
- 节头表
是ELF可重定位目标文件中最重要的部分内容描述每个节的节名、在文件中的偏移、大小、访问属性、对齐方式等
- 程序头表
描述可执行文件中的节与虚拟空间中的存储段之间的映射关系
- 只读代码段
- 可读/写数据段
- 全局符号
由模块m定义并能被其他模块引用的符号
- 外部符号
由其他模块定义并被模块m引用的全局符号
- 本地符号
在本模块定义并引用,其解析较简单,只要与本模块内唯一的定义符号关联即可。
- 强符号
- COMMON 符号
- 静态链接
- 共享库文件
- 动态链接
- 动态链接器
- 动态链接库
- 程序
指按某种方式组合形成的代码和数据集合,代码即是机器指令序列,因而程序是一种静态概念。
- 进程
指程序的一次运行过程。更确切说,进程是具有独立功能的一个程序关于某个数据集合的一次运行活动,因而进程具有动态含义 。同一个程序处理不同的数据就是不同的进程
进程是OS对CPU执行的程序的运行过程的一种抽象。进程有自己的生命周期,它由于任务的启动而创建,随着任务的完成(或终止)而消亡,它所占用的资源也随着进程的终止而释放。
一个可执行目标文件(即程序)可被加载执行多次,也即,一个程序可能对应多个不同的进程。
- 进程描述符
是某进程(任务)所有相关信息的描述结构
- 命令行解释程序
- 指令周期
CPU取出并执行一条指令的时间
- 指令译码器
- 内部异常
在CPU执行某指令时引起的与该指令相关的意外事件.
按处理方式分为故障、自陷和终止三类
中断或异常处理执行的代码不是一个进程,而是“内核控制路径”,它代表异常或中断发生时正在运行的当前进程在内核态执行一个独立的指令序列。
- 外部中断
在CPU外部发生的特殊事件,通过“中断请求”信号向CPU请求处理。
- 数据通路
指令执行过程中,数据所经过的路径,包括路径中的部件。它是指令的执行部件。
- 执行部件
- 功能部件
- 控制器
对指令进行译码,生成指令对应的控制信号,控制数据通路的动作。能对执行部件发出控制信号,是指令的控制部件。
- 时钟信号
- 指令流水线
简答
如何将多个C程序模块组合生成可执行文件?简述从源程序到可执行文件的转换过程?
预处理、编译、汇编、链接生成可执行文件。
编译阶段将源代码转换成目标文件,而链接阶段将所有目标文件合并成一个可执行文件
可重定位目标文件和可执行目标文件的主要差别是什么?
可重定向目标文件:通常用于存储编译后的源代码的中间结果,包含了代码段、数据段以及符号表等信息,但还未进行最终的链接。可重定位目标文件可以被链接器进一步处理,合并成可执行文件或者共享库。
可执行目标文件:是经过编译、链接等步骤处理后的最终产物,包含了所有的代码段、数据段以及符号表等信息,可以直接在操作系统上运行
链接器主要完成哪两方面的工作?
符号解析、地址重定位
符号解析:
- 在编译过程中,源文件中可能会引用其他模块(函数、变量等)的符号,但是这些符号的具体地址在编译时无法确定,因为它们可能位于其他模块中。
- 链接器的主要任务之一是解析这些未定义的符号引用,确定它们的具体地址或者与其他模块中的符号关联起来。
- 对于每个未定义的符号引用,链接器会在其他目标文件或库文件中查找对应的定义,然后将引用与定义进行关联
地址重定位: - 当所有的符号引用都已解析后,链接器会计算每个符号在最终可执行文件中的地址,并将这些地址信息更新到目标文件中。
- 在这个过程中,链接器会根据目标文件中的重定位表(Relocation Table)中的信息,计算出每个符号的最终地址,并将这些地址更新到目标文件的相应位置,从而使得目标文件中的各个模块能够正确地引用彼此。
可重定位文件的.text 节、.rodata 节、.data 节和.bss 节中分别主要包含什么信息?
text:主要包含可执行代码的机器指令,即程序的代码段。
rodata:包含重定位数据,用于指示链接器在链接时如何修改代码和数据段中的地址,以便正确处理外部符号引用。
data:包含程序中初始化的全局和静态变量的值。这些变量在程序执行之前就已经被赋予了初始值,因此需要存储在可执行文件中。
bss 节:包含程序中未初始化的全局和静态变量的声明。
这些变量在程序执行之前不需要分配存储空间,因此不需要在可执行文件中存储初始值,只需记录其大小即可。
可执行目标中有哪两种可装人段?哪些节组合成只读代码段?哪些节组合成可读/写数据段?
两种可装载段包括:只读代码段(.text 段)、可读/写数据段(.data 段)
只读代码段(.text 段):包括 .ELF头、程序头表、init,fini节、text 节和 .rodata 节等,其中 .rodata 节通常包含只读的静态数据,例如字符串常量等。
可读/写数据段(.data 段):通常包括程序的全局和静态变量等需要在运行时被修改的数据。在目标文件中,可能会包括 .data 节和 .bss 节等,其中 .data 节包含初始化的数据,而 .bss 节包含未初始化的全局和静态变量,在运行时会被初始化为零值
加载可执行文件时,加载器根据其中哪个表的信息对可装人段进行映射?
静态链接和动态链接的差别是什么?
静态链接会将所有的代码和数据都打包到一个可执行文件中,使得程序可以独立运行;而动态链接则将代码和数据与程序分离,使得程序可以在运行时动态加载所需的库文件,从而减少内存占用和依赖关系
在可执行文件中将可装人段映射到虚拟地址空间,以形成每个进程独立的虚拟地址空间,这种做法有什么好处?
简述通过 shell 命令行解释程序进行程序加载的过程
- shell命令行解释器构造argv和envp
- 调用fork()函数,创建一个子进程,与父进程shell完全相同(只读/共享),包括只读代码段、可读写数据段、堆以及用户栈等
- 调用execve()函数,在当前进程(新创建的子进程)的上下文中加载并运行hello程序。将hello中的.text节、.data节、.bss节等内容加载到当前进程的虚拟地址空间
- 调用程序的main()函数,程序开始在一个进程的上下文中运行。
CPU 的基本组成和基本功能各是什么?
cpu基本职能是周而复始的执行指令。
CPU 由 执行部件 和 控制部件组成,
包含 数据通路(执行部件) 和 控制器(控制部件)两种基本部件.
控制器主要 由 指令译码器 和 控制信号形成部件 组成.控制部件根据每条指令的功能的不同生成对数据通路控制信号,并正确的执行指令的流程
如何控制一条指令执行结束后能够接着另一条指令执行?
指令需要经过多个阶段取指令、指令译码(instruction decode)、计算资源操作数地址并取数、执行数据操作、计算目的操作数地址并存结果、计算下一条指令地址
通常一条指令的执行要经过哪些步骤?每条指令的执行步骤都一样吗?
指令需要经过多个阶段取指令、指令译码(instruction decode)、计算资源操作数地址并取数、执行数据操作、计算目的操作数地址并存结果、计算下一条指令地址
1、2 所有指令都一样
3~5 不同的指令操作可能不同是由第二步译码得到的控制信号控制
对于第6步若是字长指令字,处理器会在第一步取指令的同时计算出下一条指令地址并送PC,然后根据指令译码结果和条件标志决定是否在第6步修改PC的值,因此在顺序执行时,实际上是取指令时计算指令的地址,第6步什么也不做
流水线方式下,一条指令的执行时间缩短了还是加长了?程序的执行时间缩短了还是加长了?
流水线方式不能缩短一条指令的执行时间,但是对于整个程序来说,流水线方式可以大大增加指令执行的吞吐率。
具有什么特征的指令系统易于实现指令流水线?
1)长度尽量一致 有利于简化取指令和指令译码操作;MIPS指令32位,下址计算方便: PC+4;X86指令从1字节到17字节不等,使取指部件极其复杂。
2)指令格式应尽量规整,尽量保证源寄存器位置相同有利于在指令未知时就可取操作数;MIPS指令的rs和rt位置一定,在指令译码时就可读rs和rt的值.若位置随指令不同而不同,则需先确定指令类型才能取寄存器编号。
3) 采用装入/存储型指令风格load / Store指令才能访问存储器,可以把load / Store指令的地址计算和运算指令的执行步骤规整在同一个周期,因此有利于减少操作步骤,规整流水线。
4)数据和指令在内存中”对齐”存放,有利于减少访存次数,使所需数据在一个流水段内就能从存储器中得到。