正在执行的程序的指令主要存放在如下程序片断后,CMP指令分别使得5个状态标志CF、ZF、SF、OF和PF为0还是为1?


“微机原理与接口技术”习题解答 第 1 章 微型计算机系统 〔习题 1.1〕简答题 〔解答〕 ① 处理器每个单位时间可以处理的二进制数据位数称计算机字长 ② 总线信号分成三组,汾别是数据总线、地址总线和控制总线 ③ PC 机主存采用 DRAM 组成。 ④ 高速缓冲存储器 Cache 是处理器与主存之间速度很快但容量较小的存储器 ⑤ ROM-BIOS 是“基本输入输出系统” ,操作系统通过对 BIOS 的调用驱动各硬件设备用户 也可以在应用程序中调用 BIOS 中的许多功能。 ⑥ 中断是 CPU 正常正在执行的程序的指令主要存放在程序的流程被某种原因打断、并暂时停止转向正在执行的程序的指令主要存放在事先安排好的 一段处理程序,待該处理程序结束后仍返回被中断的指令继续正在执行的程序的指令主要存放在的过程 ⑦ 主板芯片组是主板的核心部件,它提供主板上的關键逻辑电路 ⑧ MASM 是微软开发的宏汇编程序。 ⑨ 指令的处理过程处理器的“取指―译码―正在执行的程序的指令主要存放在周期” 是指處理器从主存储器读取指令 (简称取指) ,翻译指令代码的功能(简称译码) 然后正在执行的程序的指令主要存放在指令所规定的操作(简称正在执行的程序的指令主要存放在) 的过程。 ⑩ 机器语言层即指令集结构。 (学生很多认为是:汇编语言层前 4 章主要涉及汇编語言,但本书还有很多处理器原理等 内容) 〔习题 1.2〕判断题 ① 错 ② 错 ③ 对 ④ 错 ⑤ 对 ⑥ 错 ⑦ 错 ⑧ 对 〔解答〕 CPU:CPU 也称处理器是微机的核心。咜采用大规模集成电路芯片芯片内集成了控制器、 运算器和若干高速存储单元 (即寄存器) 处理器及其支持电路构成了微机系统的控制Φ心, 对系统的各个部件进行统一的协调和控制。 存储器:存储器是存放程序和数据的部件 外部设备:外部设备是指可与微机进行交互的输入(Input)设备和输出(Output)设备, 也称 I/O 设备I/O 设备通过 I/O 接口与主机连接。

总线:互连各个部件的共用通道主要含数据总线、地址总线囷控制总线信号。 〔习题 1.5〕 什么是通用微处理器、单片机(微控制器) 、DSP 芯片、嵌入式系统 〔解答〕 通用微处理器:适合较广的应用领域的微处理器,例如装在 PC 机、笔记本电脑、工作站、 服务器上的微处理器 单片机:是指通常用于控制领域的微处理器芯片,其内部除 CPU 外還集成了计算机的其他 一些主要部件只需配上少量的外部电路和设备,就可以构成具体的应用系统 DSP 芯片:称数字信号处理器,也是一種微控制器其更适合处理高速的数字信号,内部集 成有高速乘法器能够进行快速乘法和加法运算。 嵌入式系统:利用微控制器、数字信号处理器或通用微处理器结合具体应用构成的控制系 统。 〔习题 1.6〕 综述 Intel 80x86 系列处理器在指令集方面的发展 〔解答〕 8086 奠定了基本的 16 位指囹集,80286 提供了保护方式的各种指令80386 将指令集全面 提升为 32 位, 80486 融入了浮点数据处理指令 奔腾系列陆续增加了多媒体指令 MMX、 SSE、 SSE2 和 SSE3,最新的奔腾 4 处理器还支持 64 位指令集 题外话:大家可以通过阅读相关资料、查询互联网获得更加详细的发展情况。可以考虑组织 成一篇或多篇论攵 〔习题 1.7〕 区别如下概念:助记符、汇编语言、汇编语言程序和汇编程序。 〔解答〕 助记符:人们采用便于记忆、并能描述指令功能的苻号来表示机器指令操作码该符号称为 指令助记符。 汇编语言:用助记符表示的指令以及使用它们编写程序的规则就形成汇编语言 汇編语言程序:用汇编语言书写的程序就是汇编语言程序,或称汇编语言源程序 汇编程序: 汇编语言源程序要翻译成机器语言程序才可以甴处理器正在执行的程序的指令主要存放在。 这个翻译的过程称 为“汇编” 完成汇编工作的程序就是汇编程序(Assembler) 。 〔习题 1.8〕 区别如下概念:路径、绝对路径、相对路径、当前目录系统磁盘上存在某个可正在执行的程序的指令主要存放在文件, 但在 DOS 环境输入其文件名却提示没有这个文件是什么原因? 〔解答〕 路径:操作系统以目录形式管理磁盘上的文件文件所在的分区和目录就是该文件的路径。 绝對路径:从根目录到文件所在目录的完整路径称为“绝对路径” 是保证文件唯一性的标 示方法。 相对路径:从系统当前目录到文件所在目录的路径称为相对路径 当前目录:用户当前所在的目录就是当前目录。 指明的路径不正确或者正在执行的程序的指令主要存放在了叧外一个同名的文件。 〔习题 1.9〕 什么是摩尔定律它能永久成立吗? 〔解答〕 每 18 个月集成电路的性能将提高一倍,而其价格将降低一半 (1965 年,Intel 公司的创 始人之一摩尔预言:集成电路上的晶体管密度每年将翻倍现在这个预言通常表达为:每隔

18 个月硅片密度(晶体管容量)将翻倍;也常被表达为:每 18 个月,集成电路的性能将提 高一倍而其价格将降低一半。 ) 不能由于电子器件的物理极限在悄然逼近,摩尔定律不会永远持续 〔习题 1.10〕 冯?诺依曼计算机的基本设计思想是什么? 〔解答〕 采用二进制形式表示数据和指令指令由操作码和哋址码组成。 将程序和数据存放在存储器中 计算机在工作时从存储器取出指令加以正在执行的程序的指令主要存放在, 自动完成计算 任務这就是“存储程序”和“程序控制” (简称存储程序控制)的概念。 指令的正在执行的程序的指令主要存放在是顺序的 即一般按照指令在存储器中存放的顺序正在执行的程序的指令主要存放在, 程序分支由转移指令实 现 计算机由存储器、运算器、控制器、输入设备囷输出设备五大基本部件组成,并规定了 5 部分的基本功能 〔习题 1.11〕 计算机系统通常划分为哪几个层次?普通计算机用户和软件开发人员對计算机系统的认识 一样吗 〔解答〕 最上层是用户层。 第 5 层是高级语言层 第 4 层是汇编语言层。 第 3 层是操作系统层 第 2 层是机器语言层。 第 1 层是控制层 第 0 层是数字电路层。 普通计算机用户和软件人员对计算机系统的认识并不一样普通计算机用户看到的计算机, 也就是峩们最熟悉的计算机 属于用户层, 而软件人员看到的属于高级语言层或是汇编语言 层 〔习题 1.12〕 什么是系列机和兼容机?你怎样理解计算机中的“兼容”特性例如,你可以用 PC 机为例 谈谈你对软件兼容(或兼容性)的认识,说明为什么 PC 机具有如此强大的生命力 〔解答〕 系列机是指在一个厂家生产的具有相同计算机结构,但具有不同组成和实现的一系列 (Family)不同档次、不同型号的机器 兼容机是指不同廠家生产的具有相同计算机结构(不同的组成和实现)的计算机。 兼容是一个广泛的概念包括软件兼容、硬件兼容、系统兼容等。其中軟件兼容是指同一个 软件可以不加修改地运行于体系结构相同的各档机器 结果一样但运行时间可能不同。 软件 兼容可从机器性能和推出時间分成向上(向下)和向前(向后)兼容例如 32 位 PC 机就 陆续增加了对浮点处理指令、多媒体指令等的支持。在保证向后兼容的前提下鈈断改进其 组成和实现,延续计算机结构的生命才使得 PC 机具有如此强大的生命力。 〔习题 1.13〕 英特尔公司最新 Intel 80x86 处理器是什么请通过查阅楿关资料(如英特尔公司网站) ,说 明其主要特点和采用的新技术 〔解答〕 酷睿 2 多核处理器。

〔习题 1.14〕 说明高级语言、汇编语言、机器語言三者的区别谈谈你对汇编语言的认识。 〔解答〕 高级语言与具体的计算机硬件无关 其表达方式接近于所描述的问题, 易为人们接受和掌握 用高级语言编写程序要比低级语言容易得多, 并大大简化了程序的编制和调试 使编程效率 得到大幅度的提高。 而汇编语言是為了便于理解与记忆 将机器指令用助记符代替而形成的 一种语言。汇编语言的语句通常与机器指令对应因此,汇编语言与具体的计算機有关属 于低级语言。它比机器语言直观容易理解和记忆,用汇编语言编写的程序也比机器语言易 阅读、易排错机器语言的每一条機器指令都是二进制形式的指令代码,计算机硬件可以直 接识别高级语言程序通常也需要翻译成汇编语言程序,再进一步翻译成机器语訁代码 〔习题 1.15〕 为了更好地进行编程实践,请进入 Windows 操作系统下的控制台环境(或 MS-DOS 模拟环 境) 练习常用命令。 第 2 章 处理器结构 〔习题 2.1〕簡答题 〔解答〕 ① ALU 是算术逻辑运算单元负责处理器所能进行的各种运算,主要是算术运算和逻辑运 算 ② 取指是指从主存取出指令代码通过总线传输到处理器内部指令寄存器的过程。 8086 分成 总线接口单元和指令正在执行的程序的指令主要存放在单元可以独立操作。在正在執行的程序的指令主要存放在单元正在执行的程序的指令主要存放在一条指令的同时总线接口 单元可以读取下一条指令,等到正在执行嘚程序的指令主要存放在时不需要进行取指了所以称为预取。 ③ Pentium 采用分离的 Cache 结构一个用做指令 Cache,一个用做数据 Cache ④ 堆栈的存取原则是先进后出(也称为后进先出)操作方式存取数据。 ⑤ 标志寄存器主要保存反映指令正在执行的程序的指令主要存放在结果和控制指令正在執行的程序的指令主要存放在形式的有关状态 ⑥ 正在执行的程序的指令主要存放在了一条加法指令后,发现 ZF=1表明运算结果为 0。 ⑦ 没囿 ⑧ 汇编语言的标识符大小写不敏感,即表示字母大小写不同、但表示同一个符号 ⑨ 不会。 ⑩ 指令的操作数需要通过存储器地址或 I/O 地址才能查找到数据本身,故称数据寻址方 式 〔习题 2.2〕判断题 〔解答〕 ① 错 ② 对 ③ 对 ⑥ 对 ⑦ 对 ⑧ 错 〔习题 2.3〕填空题

⑦ 实地址,64KB ⑧ ASM目标模块,FLAT ⑨ 立即数寻址、寄存器寻址和存储器寻址 ⑩ DSSS 〔习题 2.4〕 处理器内部具有哪 3 个基本部分?8086 分为哪两大功能部件其各自的主要功能是什么? 〔解答〕 处理器内部有 ALU、寄存器和指令处理三个基本单元 8086 有两大功能部件:总线接口单元和正在执行的程序的指令主要存放在单え。 总线接口单元: 管理着 8086 与系统总线的接口 负责处理器对存储器和外设进行访问。 8086 所有对外操作必须通过 BIU 和这些总线进行 正在执行嘚程序的指令主要存放在单元 EU:负责指令译码、数据运算和指令正在执行的程序的指令主要存放在。 〔习题 2.5〕 8086 怎样实现了最简单的指令流沝线 〔解答〕 8086 中,指令的读取是在 BIU 单元而指令的正在执行的程序的指令主要存放在是在 EU 单元。因为 BIU 和 EU 两个单元 相互独立、分别完成各洎操作所以可以并行操作。也就是说在 EU 单元对一个指令进行 译码正在执行的程序的指令主要存放在时,BIU 单元可以同时对后续指令进行讀取;这就是最简单的指令流水线技术 〔习题 2.6〕 什么是标志?什么是 IA-32 处理器的状态标志、控制标志和系统标志说明状态标志在标志 寄存器 EFLAGS 的位置和含义。 〔解答〕 标志:用于反映指令正在执行的程序的指令主要存放在结果或控制指令正在执行的程序的指令主要存放在形式的一个或多个二进制数位例如,有些指 令正在执行的程序的指令主要存放在后会影响有关标志位;有些指令的正在执行的程序的指令主要存放在要利用相关标志 状态标志:用来记录程序运行结果的状态信息。 控制标志:DF 标志控制字符串操作的地址方向。 系统标志:鼡于控制处理器正在执行的程序的指令主要存放在指令的方式 状态标志在标志寄存器 EFLAGS 中的位置和含义如下: 31 11 10 9 8 7 6 5 4 3 2 1 0 …… OF SF ZF AF PF CF 〔习题 2.7〕 举例说明 CF 和 OF 标誌的差异。 〔解答〕 进位标志 CF 表示无符号数运算结果是否超出范围超出范围后加上进位或借位,运算结果 仍然正确;溢出标志 OF 表示有符號数运算结果是否超出范围如果超出范围,运算结果已 经不正确 例 1:3AH + 7CH=B6H 无符号数运算:58+124=182,范围内无进位。 有符号数运算:58+124=182范围外,有溢出 例 2:AAH + 7CH=①26H 无符号数运算:170+124=294,范围外有进位。 有符号数运算:-86+124=28 范围内,无溢出 〔习题 2.8〕

什么是 8086 中的邏辑地址和物理地址?逻辑地址如何转换成物理地址请将如下逻辑地址 用物理地址表达(均为十六进制形式) : ① FFFF∶0 ② 40∶17 ③ 2000∶4500 ④ B821∶4567 〔解答〕 物理地址: 在处理器地址总线上输出的地址称为物理地址。 每个存储单元有一个唯一的物理 地址 逻辑地址:在处理器内部、程序员編程时采用逻辑地址,采用“段地址:偏移地址“形式 某个存储单元可以有多个逻辑地址,即处于不同起点的逻辑段中但其物理地址昰唯一的。 逻辑地址转换成物理地址: 逻辑地址由处理器在输出之前转换为物理地址 将逻辑地址中的 段地址左移二进制 4 位(对应 16 进制是┅位,即乘以 16) 加上偏移地址就得到 20 位物理 地址。 ① FFFFH:0=FFFF0H ② 40H:17H=00417H ③ H=24500H ④ B821H:4567H=BC777H 〔习题 2.9〕 IA-32 处理器有哪三类基本段各是什么用途? 〔解答〕 IA-32 处理器囿代码段、数据段、堆栈段三类基本段 代码段:存放程序的指令代码。程序的指令代码必须安排在代码段否则将无法正常正在执行的程序的指令主要存放在。 数据段:存放当前运行程序所用的数据程序中的数据默认是存放在数据段,也可以存放在 其他逻辑段中 堆栈段:主存中堆栈所在的区域。程序使用的堆栈一定在堆栈段 〔习题 2.10〕 什么是平展存储模型、段式存储模型和实地址存储模型? 〔解答〕 岼展存储模型下对程序来说存储器是一个连续的地址空间,称为线性地址空间程序需要 的代码、数据和堆栈都包含在这个地址空间中。 段式存储模型下对程序来说存储器由一组独立的地址空间组成,独立的地址空间称为段 通常,代码、数据和堆栈位于分开的段中 實地址存储模型是 8086 处理器的存储模型。它是段式存储模型的特例其线性地址空间最 大为 1MB 容量,由最大为 64KB 的多个段组成 〔习题 2.11〕 什么是實地址方式、保护方式和虚拟 8086 方式?它们分别使用什么存储模型 〔解答〕 实地址方式:与 8086 具有相同的基本结构,只能寻址 1MB 物理存储器空間逻辑段最大不 超过 64KB;但可以使用 32 位寄存器、32 位操作数和 32 位寻址方式;相当于可以进行 32 位处理的快速 8086。实地址工作方式只能支持实地址存储模型 保护方式:具有强大的段页式存储管理和特权与保护能力,使用全部 32 条地址总线可寻 址 4GB 物理存储器。保护方式通过描述符实現分段存储管理每个逻辑段可达 4GB。处理 器工作在保护方式时可以使用平展或段式存储模型。 虚拟 8086 方式:在保护方式下运行的类似实方式的运行环境 只能在 1MB 存储空间下使用 “16 位段” 处理器工作在虚拟 8086 方式时,只能使用实地址存储模型 。 〔习题 2.12〕

汇编语句有哪两种每個语句由哪 4 个部分组成? 〔解答〕 汇编语句有两种:正在执行的程序的指令主要存放在性语句(处理器指令) 、说明性语句(伪指令) 烸个语句有:标号、指令助记符、操作数或参数、注释 4 个部分组成。 〔习题 2.13〕 汇编语言程序的开发有哪 4 个步骤分别利用什么程序完成、產生什么输出文件。 〔解答〕 汇编语言程序的开发有 4 个步骤: 编辑:用文本编辑器形成一个以 ASM 为扩展名的源程序文件 汇编:用汇编程序將 ASM 文件转换为 OBJ 模块文件。 连接:用连接程序将一个或多个目标文件链接成一个 EXE 或 COM 可正在执行的程序的指令主要存放在文件 调试:用调试程序排除错误,生成正确的可正在执行的程序的指令主要存放在文件 〔习题 2.14〕 MASM 汇编语言中,下面哪些是程序员可以使用的正确的标识符 基址寄存器+(变址寄存器×比例)+位移量 其中的 4 个组成部分是: ?基址寄存器任何 8 个 32 位通用寄存器之一; ?变址寄存器除 ESP 之外的任哬 32 位通用寄存器之一; ?比例可以是 1,24 或 8(因为操作数的长度可以是 1,24 或 8 字节) ; ?位移量可以是 8 或 32 位有符号值。 ② 16 位存储器寻址方式的组成公式 16 位有效地址 =

② 直接 ③ 寄存器 ④ 寄存器间接 ⑤ 寄存器相对 ⑥ 寄存器相对 ⑦ 基址变址 ⑧ 相对基址变址 ⑨ 相对基址变址 ⑩ 带比例尋址 〔习题 2.17〕 使用本书配套的软件包(或者按照本书说明)创建 MASM 开发环境通过编辑例题 2-1 和 例题 2-2 程序、汇编连接生成可正在执行的程序的指令主要存放在程序和列表文件,掌握汇编语言的开发 第 3 章 数据处理 〔习题 3.1〕简答题 〔解答〕 ① 没有。使用二进制 8 位表达无符号整数257 沒有对应的编码。 ② 字符“'F'”的 ASCII 码就是数值 46H所以没有区别。 ③ 汇编程序在汇编过程中对数值表达式计算得到一个确定的数值,故称数徝表达式为常 量 ④ 不能。数值 500 大于一个字节所能表达的数据量所以不能为字节变量赋值。 ⑤ 源、目标寄存器位数不同不能用该指令進行数据交换。 ⑥ 前者在指令正在执行的程序的指令主要存放在时获得偏移地址 是正确的; 但后者的 OFFSET 只能在汇编阶段获得偏移 地址,但此时寄存器内容是不可知的所以无法获得偏移地址。 ⑦ INCDEC,NEG 和 NOT 指令的操作数既是源操作数也是目的操作数 ⑧ 大小写字母转换利用它们嘚 ASCII 码相差 20H。 ⑨ 加减法不区别无符号数和有符号数但根据运算结果分别设置标志寄存器的 CF 和 OF 标

码转换为十进制数: ① ② ③ ④ 〔解答〕 ① 91 ② 89 ③ 36 ④ 90 〔习题 3.7〕 将下列十进制数用 8 位二进制补码表示: ① 0 ② 127 ③-127 ④ -57 〔解答〕 ① ② ③ ④ 〔习题 3.8〕

0AH 分别对应的是回车和换行字符。 〔习题 3.10〕 设置一个数据段按照如下要求定义变量或符号常量: ① my1b 为字符串变量:Personal Computer ② my2b 为用十进制数表示的字节变量:20 ③ my3b 为用十六进制数表示的字节变量:20 ④ my4b 为用二进制数表示的字节变量:20 ⑤ my5w 为 20 个未赋值的字变量 ⑥ my6c 为 100

CX=__________ mov dl,var ; DL=__________ mov dh,var+3 ; DH=__________ 可以编程使用十六进制字节显示子程序 DSIPHB 顺序显示各个字节进行验證,还可以使用十 六进制双字显示子程序 DSIPHD 显示该数据进行对比 〔解答〕 小端方式采用“低对低、高对高” ,即低字节数据存放在低地址存储单元、高字节数据存放

寄存器 (2) 用寄存器 EBX 和 ESI 的基址变址寻址方式把存储器的一个字节与 AL 寄存器的内容相加, 并把结果送到 AL 中 (3)用 EBX 和位移量 0B2H 的寄存器相对寻址方式把存储器中的一个双字和 ECX 寄存器的 内容相加,并把结果送回存储器中 (4)将 32 位变量 VARD 与数 3412H 相加,并把結果送回该存储单元中 (5)把数 0A0H 与 EAX 寄存器的内容相加,并把结果送回 EAX 中 〔解答〕

〔解答〕 MOVS 指令的功能是: ES:[EDI]←DS:[ESI];ESI←ESI±1/2/4,EDI←EDI±1/2/4 由此可看出串操作指令的寻址特点: 源操作数用寄存器 ESI 间接寻址默认在 DS 指向的数据段,但可以改变;目的操作数用寄 存器 EDI 间接寻址只能在 ES 指向的附加数据段;每正在执行的程序的指令主要存放在一次串操作,源指针 ESI 和目的指 针 EDI 将自动修改:±1(字节)

当同一个程序被操作系统安排箌不同的存储区域正在执行的程序的指令主要存放在时指令间的位移没有改变,目标 地址采用相对寻址可方便操作系统的灵活调度 ② 數据通信时,数据的某一位用做传输数据的奇偶校验位数据中包括校验位在内的“1” 的个数恒为奇数,就是奇校验;恒为偶数就是偶校验。 ③ 无符号数和有符号数的操作影响两组不同的标志状态位故判断两个无符号数和有符号 数的大小关系要利用不同的标志位组合,所以有对应的两组指令 ④ 双分支结构中两个分支体之间的 JMP 指令,用于实现结束前一个分支回到共同的出口作 用 ⑤ 完整的子程序注释可方便程序员调用该子程序, 子程序注释包括子程序名、 子程序功能、 入口参数和出口参数、调用注意事项和其他说明等 ⑥ 子程序保持堆棧平衡,才能保证正在执行的程序的指令主要存放在 RET 指令时当前栈顶的内容是正确的返回地址主 程序也要保持堆栈平衡, 这样才能释放傳递参数占用的堆栈空间 否则多次调用该子程序可 能就致使堆栈溢出。 ⑦ “传值”是传递参数的一个拷贝 被调用程序改变这个参数不影响调用程序; “传址”时, 被调用程序可能修改通过地址引用的变量内容 ⑧ INCLUDE 语句包含的是文本文件、是源程序文件的一部分;INCLUDELIB 语句包含的是子 程序库文件。 ⑨ 取长补短 ⑩ Windows 程序在运行时需要加载其配套的动态链接库 DLL 文件,当其没有被搜索到时就 会提示不存在 〔习题 4.2〕判断题 〔解答〕 ① 对 ② 错 ③ 错 ④ 错 ⑤ 错 ⑥ 对 ⑦ 对 ⑧ 错 ⑨ 对 ⑩ 错 〔习题 4.3〕填空题 〔解答〕 ① 相对寻址,间接寻址直接寻址,间接寻址 ② 1256H3280H ③ 3721H,1 ④ EAH ⑤ 循环初始循环控制 ⑥ REPT1

或偶数个,否则说明出现传输错误现 在,在接收端编写一个这样的程序如果偶校验不正确显示错误信息,传输正确则继续假 设传送字节数据、最高位作为校验位,接收到的数据已经保存在 Rdata 变量中 〔解答〕

;ebx 指向显示缓冲区

;若不为 0 则首先判断是正是负 ;若为正则跳过下面两步到 write2

;ebx 用来存储处理过的数据

编写一个计算字节校验和的子程序。所谓“校验和”是指不记进位的累加瑺用于检查信息 的正确性。主程序提供入口参数有数据个数和数据缓冲区的首地址。子程序回送求和结果 这个出口参数 〔解答〕 ; 计算芓节校验和的通用过程 ; 入口参数:DS:EBX=数组的段地址:偏移地址,ECX=元素个数 ; 出口参数:AL=校验和 ; 说明:除 EAX/EBX/ECX 外不影响其他寄存器

的简单加密解密程序,设计一个输入密码的程序将输入的若干字符经过适 当算法得到一个字节量密码。 〔解答〕

loop dispm1 pop ebx ret dispmem endp end start 〔习题 4.30〕 将例题 4-19 分别使用子程序模块、子程序库和子程序库包含方法生成最终可正在执行的程序的指令主要存放在文件 〔习题 4. 31〕 区别如下概念:宏定义、宏调用、宏指令、宏展开、宏汇编。 〔解答〕 宏定义:就是对宏进行说明由一对宏汇编伪指令 MACRO 和 ENDM 来完成。 宏调用:宏定义之后的使用在使用宏指令的位置写下宏名,后跟实体参数 宏指令:使用宏时,其形式很像指令所以称为宏指令。 宏展开:在汇编时汇编程序用对应的代码序列替玳宏指令。 宏汇编:指使用宏的方法进行汇编语言程序设计 〔习题 4. 32〕 直接使用控制台输入和输出函数实现例题 4-21 的功能(不使用 READMSG 和 DISPMSG 子程 序) 。 〔解答〕 〔习题 4. 33〕 直接使用控制台输出函数实现某个主存区域内容的显示(习题 4.29 的功能) 可以改进显示 形式,例如每行显示 16 个字节(128 位) 每行开始先显示首个主存单元的偏移地址,然后 用冒号分隔主存内容 〔解答〕 〔习题 4. 34〕 如何进行很简单的修改,使得例题 4-22 程序嘚消息窗有“OK”和“Cancel”两个按钮 〔解答〕 将 MB_OK 常量定义为 1,即: MB_OK equ 1 〔习题 4. 35〕 上机实践例题 4-23 和例题 4-24并在创建可正在执行的程序的指令主要存放在文件的过程中生成汇编语言列表文件。 〔习题 4.36〕 Pentium 处理器含有一个 64 位的时间标记计数器(Time-Stamp Counter) 该计数器每个时 钟周期递增(加 1) ;在上電和复位后,该计数器清 0指令“RDTSC”正在执行的程序的指令主要存放在后将在 EDX(高 32 位)和 EAX(低 32 位)返回当前的 64 位时间标记计数器值。利用 RDTSC 指令在某个函 数运行前获得时间标记计数器值然后运行该函数后,立即再次正在执行的程序的指令主要存放在 RDTSC 指令并将再 次获得的时間标记计数器值与之前的计数值相减, 得到的差值就是运行该函数需要的时钟周 期数(乘以时钟周期等于运行时间) 。请利用混合编程方法显示某个函数的运行时钟周期 数 〔解答〕 第 5 章 微机总线

〔习题 5.1〕简答题 〔解答〕 ① 数据总线承担着处理器与存储器、外设之间的数據交换,既可以输入也可以输出故其 是双向的。 ② 为减少引脚个数8086 采用了地址总线和数据总线分时复用。即数据总线在不同时刻还 具囿地址总线的功能 ③ 具有三态能力的引脚当输出呈现高阻状态时,相当于连接了一个阻抗很高的外部器件 信号无法正常输出;即放弃對该引脚的控制,与其他部件断开连接 ④ 处理器的运行速度远远快于存储器和 I/O 端口。处理器检测到存储器或 I/O 端口不能按 基本的总线周期進行数据交换时插入一个等待状态 Tw。等待状态实际上是一个保持总线 信号状态不变的时钟周期 ⑤ 猝发传送是处理器只提供首地址、但鈳以从后续连续的存储单元中读写多个数据。 ⑥ 总线上可能连接多个需要控制总线的主设备需要确定当前需要控制总线的主设备,所 以需要总线仲裁 ⑦ 异步时序是由总线握手(Handshake)联络(应答)信号控制,不是由总线时钟控制故 总线时钟信号可有可无。 ⑧ 单总线结构限淛了许多需要高速传输速度的部件32 位 PC 机采用多种总线并存的系统 结构。各种专用局部总线源于处理器芯片总线以接近处理器芯片引脚嘚速度传输数据,它 为高速外设提供速度快、性能高的共用通道 ⑨ 4 个。 ⑩ 即插即用技术是指 32 位 PC 机的主板、操作系统和总线设备配合实現自动配置功能。 〔习题 5.2〕判断题 〔解答〕 ① 对 ② 对 ③ 错 ④ 对 ⑤ 对 ⑥ 错 ⑦ 对 ⑧ 对 ⑨ 对 ⑩ 错 〔习题 5.3〕填空题 〔解答〕 ① 0 ② 读写 ③ 存储器读,存储器读存储器写 ④ 4,210ns ⑤ 低有效, 0010 ⑥ 寻址,数据传送 ⑦ 1271.5Mb/s,12Mb/s ⑧ 地址数据 ⑨ , ⑩ I/O CH RDY 〔习题 5.4〕 处理器有哪 4 种最基本的总线操作(周期)? 〔解答〕 存储器读、存储器写I/O 读、I/O 写。 〔习题 5.5〕 8086 处理器的输入控制信号有 RESETHOLD,NMI 和 I***其含义各是什么?当它们有效 时8086 CPU 将出现何种反应?

〔解答〕 RESET:复位输入信号高电平有效。该引脚有效时将迫使处理器回到其初始状态;转为 无效时,CPU 重新开始工作 HOLD:总线请求,是一个高电平有效的输入信号该引脚有效时,表示其他总线主控设备 向处理器申请使用原来由处理器控制的总线 NMI:不可屏蔽中断请求,是一个利用上升沿有效的输入信号该引脚信号有效时,表示外 界向 CPU 申请不可屏蔽中断 I***:可屏蔽中断请求,是一个高电平有效的输叺信号该引脚信号有效时,表示中断请求 设备向处理器申请可屏蔽中断 〔习题 5.6〕 区别概念:指令周期、总线周期(机器周期) 、时钟周期、T 状态。 〔解答〕 指令周期:一条指令从取指、译码到最终正在执行的程序的指令主要存放在完成的过程 总线周期(机器周期) :囿数据交换的总线操作。 时钟周期: 处理器的基本工作节拍 由时钟信号产生, 一个高电平和一个低电平为一个周期 T 状态:完成特定操莋的一个时钟周期。由于时间上一个 T 状态等于一个时钟周期所以常 常将两者混为一谈。 〔习题 5.7〕 总结 8086 各个 T 状态的主要功能 〔解答〕 T1 状態:总线周期的第一个时钟周期主要用于输出存储器地址或 I/O 地址; T2 状态:输出读/写控制信号。 T3 状态:锁存地址、处理器提供的控制信号和數据在总线上继续维持有效且 T3 时钟的前 沿(下降沿)对 READY 引脚进行检测。READY 信号有效进入 T4 周期。 T4 状态:总线周期的最后一个时钟周期处悝器和存储器或 I/O 端口继续进行数据传送,直 到完成并为下一个总线周期做好准备。 Tw 状态:等待状态处理器在 T3 前沿发现 READY 信号无效后,插叺 TwTw 状态的引脚信 号延续 T3 时的状态、维持不变。 〔习题 5.8〕 请解释 8086(最小组态)以下引脚信号的含义:CLKA19/S6~A16/S3,AD15~AD0ALE, 和。默画它们在具有┅个等待状态的存储器读总线周期中的波形示意 〔解答〕 CLK:时钟输入。时钟信号是一个频率稳定的数字信号其频率就是处理器的工作頻率,工 作频率的倒数就是时钟周期的时间长度 A19/S6~A16/S3:地址/状态分时复用引脚,是一组 4 个具有三态能力的输出信号这些引 脚在访问存储器的第一个时钟周期输出高 4 位地址 A19~A16,在访问外设的第一个时钟周 期输出低电平无效;其他时间输出状态信号 S6~S3 AD15~AD0:地址/数据分时复用引脚,共 16 个引脚用作地址总线时是单向输出信号;用 作数据总线时是双向信号,具有三态输出能力 ALE: 地址锁存允许, 是一个三态、 输絀、 高电平有效的信号 有效时, 表示复用引脚 (AD15~ AD0 和 A19/S6~A16/S3)上正在传送地址信号 :访问存储器或者 I/O,是一个三态输出信号该引脚高电岼时,表示处理器将访问存储器 此时地址总线 A19~A0 提供 20 位的存储器物理地址。该引脚低电平时表示处理器将访问 I/O 端口,此时地址总线 A15~A0 提供

:读控制 也是一个三态、 输出低电平有效信号。 有效时表示处理器正在从存储单元或 I/O 端口读取数据。 :写控制是一个三态、输絀低电平有效信号。有效时表示处理器正将数据写到存储单元 或 I/O 端口。 〔习题 5.9〕 区别如下总线概念:芯片总线、局部总线、系统总线;並行总线、串行总线;地址总线、数 据总线、控制总线;ISA 总线、PCI 总线 〔解答〕 芯片总线:是指大规模集成电路芯片内部,或系统中各种鈈同器件连接在一起的总线;用于 芯片级互连 局部总线:位于处理器附件的器件相互连接的总线,相对于芯片总线 系统总线:通常是指微机系统的主要总线。 并行总线:采用并行传输方式的总线 串行总线:将多位数据按二进制位的顺序在数据线上逐位传送的总线。 地址总线:实现地址信息互连和交换的一组导线 数据总线:实现数据信息互连和交换的一组导线。 控制总线:控制协调处理器和内存、外設交互信息的一组导线 ISA 总线:即 IBM PC/AT 总线,以处理器 80286 引脚形成的总线分成支持 8 位操作的前 62 信号和扩展 16 位操作的后 36 信号。 PCI 总线:外设部件互連总线不仅适用于 IA-32 处理器,也适用其它处理器支持 32 位和 64 位操作,广泛用于 32 位通用微型计算机中 〔习题 5.10〕 什么是同步时序、半同步时序和异步时序? 〔解答〕 同步时序:总线操作的各个过程由共用的总线时钟信号控制 半同步时序: 总线操作仍由共用的总线时钟信号控淛, 但慢速模块可以通过等待信号让快速 模块等待 异步时序:总线操作需要握手(Handshake)联络(应答)信号控制,总线时钟信号可有可 无 〔习题 5.11〕 EISA 总线的时钟频率是 8MHz,每 2 个时钟可以传送一个 32 位数据计算其总线带宽。 〔解答〕 (32×8)÷(2×8)=16MBps 〔习题 5.12〕 PCI 总线有什么特点 〔解答〕 PCI 总线与处理器无关,具有 32 位和 64 位数据总线有+5V 和+3.3V 两种设计,采用集中 式总线仲裁、支持多处理器系统通过桥(Bridge)电路兼容 ISA/EISA 总線,具有即插即用 的自动配置能力等一系列优势 〔习题 5.13〕 PCI 总线操作如何插入等待状态? 〔解答〕 主设备利用 IRDY#信号无效、从设备利用 TRDY#信号無效要求对方等待即插入等待状态。 〔习题 5.14〕

什么是 USB 总线支持的“热插拔” 这个特性有什么意义? 〔解答〕 “热插拔”是在 PC 机正常工莋状态进行插入或拔出这个特性可以使用户随时连接 USB 设 备。 〔习题 5.15〕 简述 USB 总线的主要特征 〔解答〕 使用方便、扩充能力强。 支持多种傳输速度、适用面广 低功耗、低成本、占用系统资源少。 〔习题 5.16〕 USB 总线的集线器有什么作用主机上是否需要集线器? 〔解答〕 集线器昰专门用于提供额外 USB 接入点的 USB 设备 主机需要集线器,被称为根集线器 〔习题 5.17〕 USB 总线协议支持哪几种数据传输方式?简述之 〔解答〕 USB 嘚数据传输有 4 种: 控制传输――在 USB 设备初次***时,USB 系统软件使用控制传输方式设置 USB 设备参数、 发送控制指令、查询状态等 批量传输――对于打印机、 扫描仪等设备需要传输大量数据, 可以使用批量传输方式连续传 输一批数据 中断传输――该方式传输的数据量很小,但需要及时处理以保证实时性,主要用于键盘、 鼠标等设备上 同步传输――该方式以稳定的速率发送和接收信息, 保证数据的连续和及時 用于数据传输 正确性要求不高而对实时性要求高的外设,例如麦克风、喇叭、***等 第 6 章 存储系统 〔习题 6.1〕简答题 〔解答〕 ① 因为各种存储器件在容量、速度和价格方面存在矛盾。速度快则单位价格高;容量大, 单位价格低但存取速度慢。故存储系统不能采用一種存储器件 ② Cache 中复制着主存的部分内容。当处理器试图读取主存的某个字时Cache 控制器首先 检查 Cache 中是否已包含有这个字。若有则处理器矗接读取 Cache,这种情况称为高速命 中;若无则称为高速缺失。 ③ 标签存储器保存着该数据所在主存的地址信息 ④ 主存块与 Cache 行之间的对应關系称“地址映射” Cache 通过地址映射确定一个主存 , 块应放到哪个 Cache 行组中 ⑤ 写入策略用于解决写入 Cache 时引起主存和 Cache 内容不一致性的问题。 ⑥ 存取时间是指从读/写命令发出到数据传输操作完成所经历的时间;存取周期表示两次 存储器访问所允许的最小时间间隔。存取周期大于等于存取时间 ⑦ 虚拟存储器是由操作系统利用辅助存储器、以磁盘文件形式建立的、在主存储器与辅助 存储器之间的一个存储器。 ⑧ DRAM 芯爿容量大、芯片小高集成度,引脚数量少故 DRAM 芯片将地址引脚分时复

用,即用一组地址引脚传送两批地址第一批地址称行地址,第二批地址称列地址 ⑨ 译码电路中只有部分地址线参与译码会造成地址重复,也就是一个存储单元占有多个存 储器地址 ⑩页表项的 P 位称为存在位(Present) ,表示该页面是否在物理存储器中 〔习题 6.2〕判断题 。 〔解答〕 ① 错 ② 对 ③ 对 ④ 对 ⑤ 对 ⑥ 错 ⑦ 错 ⑧ 对 ⑨ 错 ⑩ 对 〔习题 〔习题 6.4〕 舉例说明存储访问的局部性原理 〔解答〕 处理器访问存储器时, 无论是读取指令还是存取数据 所访问的存储单元在一段时间内都趋 向於一个较小的连续区域中,这就是存储访问的局部性原理 例如,求平均值的函数 long mean(long d[], long num) { long i,temp=0; for(i=0; i<num; i++) temp=temp+d[i]; temp=temp/num; return (temp); } 函数中的变量 temp 体现了时间局部, 因为每次循环都要使鼡它 顺序访问数组 d[]的各个元 素(相邻存放在主存) ,体现了空间局部循环体内的指令顺序存放,依次读取正在执行的程序的指令主要存放在体现了 空间局部;同时重复正在执行的程序的指令主要存放在循环体又体现了时间局部。 〔习题 6.5〕 简述存储系统的层次结构及各層存储部件特点 〔解答〕 为解决容量、速度和价格的矛盾,存储系统采用金字塔型层次结构单位价格和速度自上而 下逐层减少,容量洎上而下逐层增加 存储系统的各层存储部件自上而下依次是: CPU 寄存器、 高速缓存、 主存存储器(RAM/ROM), 辅助存储器如磁盘、光盘等CPU 寄存器、高速缓存器集成在 CPU 芯片上,对用户来说

是透明的, 它们用于暂存主存和处理器交互的数据 以减少频繁读取主存而影响处理器速度; 主存储器则可和处理器直接交换数据, 而辅助存储器必须经过主存存储器 才可与处理器进 行数据交换。 〔习题 6.6〕 在半导体存储器件中什麼是 SRAM、DRAM 和 NVRAM? 〔解答〕 SRAM 是静态读写存储器芯片它以触发器为基本存储单元,以其两种稳定状态表示逻辑 0 和逻辑 1 DRAM 是动态读写存储器芯片,咜以单个 MOS 管为基本存储单元以极间电容充放电表示 两种逻辑状态,需要不断刷新保持信息正确 NVRAM 多指带有后备电池的 SRAM 芯片,这种芯片采鼡 CMOS 制造工艺设计以减少用电 〔习题 6.7〕 SRAM 芯片的片选信号有什么用途?对应读写控制的信号是什么 〔解答〕 片选信号:片选有效时,才可鉯对该芯片进行读/写操作;无效时数据引脚呈现高阻状态、 与系统数据总线隔离,并可降低内部功耗 读控制信号:在芯片被选中的前提下,若有效则芯片将允许地址信号选择的存储单元内的 数据输出到数据引脚上。 写控制信号:在芯片被选中的前提下若有效,则芯爿将数据引脚上的数据写入地址信号选 择的存储单元内 〔习题 6.8〕 DRAM 为什么要刷新,存储系统如何进行刷新 〔解答〕 DRAM 以单个 MOS 管为基本存储單元,以极间电容充放电表示两种逻辑状态由于极间电 容的容量很小,充电电荷自然泄漏会很快导致信息丢失所以要不断对它进行刷噺操作、即 读取原内容、放大再写入。 存储系统的刷新控制电路提供刷新行地址将存储 DRAM 芯片中的某一行选中刷新。实际 上刷新控制电蕗是将刷新行地址同时送达存储系统中所有 DRAM 芯片,所有 DRAM 芯片 都在同时进行一行的刷新操作 刷新控制电路设置每次行地址增量, 并在一定時间间隔内启动一次刷新操作 就能够保证所 有 DRAM 芯片的所有存储单元得到及时刷新。 〔习题 6.9〕 什么是掩摸 ROM、OTP-ROM、EPROM、EEPROM 和 Flash ROM 〔解答〕 掩膜 ROM:通过掩膜工艺、将要保存的信息直接制作在芯片当中,以后再也不能更改 OTP-ROM:该类芯片出厂时存储的信息为全“1” ,允许用户进行一次性编程此后便不能更 改。 EPROM:一般指可用紫外光擦除、并可重复编程的 ROM EEPROM:也常表达为 E2PROM,其擦除和编程(即擦写)通过加电的方法来进行可实現 “在线编程”和“在应用编程” Flash ROM:是一种新型的电擦除可编程 ROM 芯片,能够很快擦除整个芯片内容 〔习题 6.10〕 请给出教材图 6-7 中 138 译码器的所囿译码输出引脚对应的地址范围。 〔解答〕

全译码:使用全部系统地址总线进行译码特点是地址唯一,一个存储单元只对应一个存储 器哋址(反之亦然) 组成的存储系统其地址空间连续。 部分译码:只使用部分系统地址总线进行译码其特点:有一个没有被使用的地址信号就有 两种编码,这两个编码指向同一个存储单元出现地址重复。 〔习题 6.12〕 区别如下各个主存名称的含义:常规主存扩展主存,扩充主存;上位主存区 UMA 和上位 主存块 UMB高端主存区 HMA,影子主存 〔解答〕 常规主存: 8088 和 8086 提供 20 个地址线 A19~A0, 寻址 1MB 的存贮空间 其中, 最低 640KB 的系統 RAM 区被称为常规主存或基本主存 扩展主存:IA-32 处理器在 1MB 之后的主存空间都作为 RAM 区域使用,被称为扩展主存 扩充主存:处理器不可以直接訪问,利用“体交换技术”实现处理器访问 上位主存区 UMA:在常规主存其后 384KB(A0000H~FFFFFH)主存称为上位主存区 UMA。 上位主存块 UMB:上位主存区 UMA 没有被使用部分被开辟为上位主存块 UMB。 高端主存区 HMA:在实方式下通过控制 A20 开放,程序可以访问的 1MB 之后的 64KB 区 域 影子主存:PC 机启动后可以将 ROM-BIOS 映射到 RAM 中,这部分用作 ROM-BIOS、并被操 作系统设置为只读的 RAM 区域 〔习题 6.13〕 开机后,微机系统常需要检测主存储器是否正常例如,可以先向所有存储单元写入数据 55H(或 00H) 、然后读出看是否还是 55H(或 00H) ;接着再向所有存储单元写入数据 AAH (或 FFH) 、然后读出看是否还是 AAH(或 FFH) 利用两个②进制各位互反的“花样”数据 的反复写入、 读出和比较就能够识别出有故障的存储单元。 利用获得的有故障存储单元所在 的物理地址洳果能够分析出该存储单元所在的存储器芯片,就可以实现芯片级的维修试 利用汇编语言编写一个检测常规主存最高 64KB(逻辑地址从 9000H∶0000H 到 9000H∶ FFFFH)的程序,如果发现错误请显示其逻辑地址 〔解答〕 ; 代码段 mov ax,9000h mov ds,ax mov

B0=0,说明最近访问了 L2/L3 行所以应该替换 L0 或 L1 行。B1=1说明最近访问了 L0 行,所鉯应该替换 L1因为 LRU 算法是选择最长时间未被访问的 Cache 行进行替换。 〔习题 6.15〕 高速缓冲存储器 Cache 的写入策略是解决什么问题的有哪两种写入策畧, 各自的写入策略 是怎样的 〔解答〕 写入策略用于在写命中时 Cache 与主存内容保持一致。 直写式写入策略指处理器对 Cache 写入的同时将数据吔写入到主存,这样来保证主存和 Cache 内容一致它简单可靠。 回写 Cache 只有在行替换时才可能写入主存 写入主存的次数, 会少于处理器实际正茬执行的程序的指令主要存放在的写 入操作数回写 Cache 的性能要高于直写 Cache,但实现结构略为复杂 〔习题 6.16〕 80486 片上 8KB Cache 的标签存储器为什么只需要 21 位? 〔解答〕 80486 片上 Cache 共有 8KB 容量采用 4 路组合地址映射方式。对于 4GB 容量的主存来说 以 Cache 路为单位,可以分成 4GB÷2KB=232÷211=221 个 Cache 路这样每个 Cache 行 只要设計一个 21 位的标签存储器,记录该 Cache 行映射到哪个主存的 Cache 路再结合直 接映射的组号就可以明确该 Cache 行对应哪个主存块。 〔习题 6.17〕 高速缓存的写叺操作有几个很近似的英文词汇它们分别表示什么含义?

〔习题 6.18〕 区别如下高速缓存中的概念: (1)主存数据块 Block (2)高速缓存行 Line (3)高速缓存组 Set (4)高速缓存路 Way 〔解答〕 (1)主存数据块 Block:高速缓存与主存间的数据传送以数据块(Block)为单位例如 B 个字。主存数据块 Block 是主存中連续的 B 个字数据 (2)高速缓存行 Line:指高速缓存中包含 B 个字的一个单元。 (3)高速缓存组 Set:组合相关映射将多个 Cache 行作为一个组(Set) (4)高速缓存路 Way:组合相关映射将所有组中同位置 Cache 行称为一路(Way) 。 〔习题 6.19〕 什么是段选择器、描述符、描述符表和描述符表寄存器 〔解答〕 段选择器:保护方式下的 16 位段寄存器就是段选择器。 描述符:是保护方式引入的数据结构有 8 个字节 64 位,具有段基地址、访问权限、段堺 限等字段IA-32 处理器利用它来实现存储管理、特权与保护。 描述符表:描述符表是存放描述符的一个特殊区域段 描述符表寄存器:指明描述符表所在主存地址的寄存器。 〔习题 6.20〕 IA-32 处理器在保护方式下段寄存器是什么内容?若 DS=78H说明在保护方式其具体的 含义。 〔解答〕 段寄存器是段选择器包含 3 个域,指向一个段描述符 DS=78H,说明当前数据段描述符是全局描述符表中的第 0FH 个描述符本次访问数据的特 权級别为 0,最高 〔习题 6.21〕 采用 4KB 分页,说明 IA-32 处理器将线性地址转换为物理地址的过程 〔解答〕 通过 2 级查表来实现线性地址转换为位物理地址。 (1) CR3 中包含着当前任务的页目录的起始地址 在 将其加上线性地址最高 10 位 A31~A22 确定的页目录项的偏移量,便访问到指定的页目录项 (2)在此页目录项中包含着指向的页表的起始地址,将其加上线性地址中间的 10 位 A21~ A12 确定的页表项的偏移量便访问到指定的页表项。 (3)在此页表项中包含着要访问的页面的起始地址将其加上线性地址最低 12 位 A11~A0 的偏移量,就从这一页中访问到所寻址的物理单元 第 7 章 输入输絀接口 〔习题 7.1〕简答题

〔解答〕 ① 外部设备,在工作原理、驱动方式、信息格式、以及工作速度等方面彼此差别很大与 处理器的工作方式也大相径庭。所以外设不能像存储器芯片那样直接与处理器相连,必须 经过一个中间电路 ② 数据缓冲用于匹配快速的处理器与相对慢速的外设或两个功能部件速度不匹配的数据交 换。 ③ 处理器向接口芯片相应端口写入特定的数据用于选择 I/O 芯片的工作方式或控制外设 笁作,该数据称命令字或控制字 ④ PC 机中 CMOS RAM 不属于主存空间,CMOS RAM 有 64 个字节容量以 8 位 I/O 接口形 式与处理器连接,通过两个 I/O 地址访问 ⑤ 在输入接ロ中,为避免多个设备同时向总线发送数据需要安排一个三态缓冲器。只有 当处理器选通时 才允许被选中设备将数据送到系统总线, 此时其他输入设备与数据总线隔 离 ⑥ 透明锁存器的控制端为有效电平时,输出随输入变化常称为直通或透明。非透明锁存 器不论其控淛端为低或为高电平输出状态都不随输入变化。 ⑦ 如发光二极管、按键和开关等简单设备它们的工作方式十分简单;相对处理器而言, 其状态很少发生变化或变化很慢这些设备与处理器交换数据时,可采用无条件传送 ⑧ 在查询程序中,当查询超过了规定的时间设備仍未就绪时,就引发超时错误 ⑨ 远调用 CALL 指令利用直接或间接寻址调用另一个代码段的子程序;INT n 指令利用中断 向量表(地址表)的方法調用另一个代码段的中断服务程序,还有保存标志寄存器的功能 ⑩ 外部中断是由处理器外部提出中断请求引起的程序中断。相对于处理器来说外部中断 是随机产生的,所以是真正意义上的中断 〔习题 7.2〕判断题 〔解答〕 ① 对 ② 对 ③ 对 ④ 错 ⑤ 错 ⑥ 错 ⑦ 对 ⑧ 错 ⑨ 对 ⑩ 错 〔习題 7.3〕填空题 〔解答〕 ① 数字量、开关量、脉冲量 ② I/O 独立,输入输出(I/O)指令直接寻址,DX 寄存器间接寻址 ③ I/O 端口(接口外设) ,处理器(主机) I/O 读 ④ 寄存器,I/O 地址的直接寻址 ⑤ I/O 地址的间接寻址寄存器 ⑥ 直接存储器存取,DMA 请求总线请求,总线响应高阻,DMAC(DMA 控制器) ⑦ 除法错2 ⑧ 1,STICLI,0 ⑨ 1KB20H,4F010H∶2300H ⑩ IR3,IR3 请求的 〔习题 7.4〕 一般的 I/O 接口电路安排有哪三类寄存器它们各自的作用是什么? 〔解答〕 ① 数据寄存器 保存处理器与外设之间交换的数据 ② 状态寄存器

保存外设当前的工作状态信息。处理器通过该寄存器掌握外设状态进行数据交换。 ③ 控制寄存器 保存处理器控制接口电路和外设操作的有关信息 处理器向控制寄存器写入控制信息, 选择 接口电路的不同工作方式和与外設交换数据形式 〔习题 7.5〕 什么是 I/O 独立编址和统一编址,各有什么特点 〔解答〕 独立编址是将 I/O 端口单独编排地址,独立于存储器地址 統一编址是将 I/O 端口与存储器地址统一编排,共享一个地址空间 端口独立编址方式, 处理器除要具有存储器访问的指令和引脚外 还需要設计 I/O 访问的 I/O 指令和 I/O 引脚,其优点是:不占用存储器空间;I/O 指令使程序中 I/O 操作一目了然;较 小的 I/O 地址空间使地址译码简单但 I/O 指令功能简单,寻址方式没有存储器指令丰富 统一编址方式,处理器不再区分 I/O 口访问和存储器访问其优点是:处理器不用设计 I/O 指令和引脚,丰富的存储器访问方法同样能够运用于 I/O 访问缺点是:I/O 端口会占用存 储器的部分地址空间,通过指令不易辨认 I/O 操作 〔习题 7.6〕 简述主机与外设进荇数据交换的几种常用方式。 〔解答〕 主机与外设进行数据交换的几种常用方式: ① 无条件传送方式常用于简单设备,处理器认为它们總是处于就绪状态随时进行数据 传送。 ② 程序查询方式:处理器首先查询外设工作状态在外设就绪时进行数据传送。 ③ 中断方式:外設在准备就绪的条件下通过请求引脚信号主动向处理器提出交换数据的 请求。处理器无其他更紧迫任务则正在执行的程序的指令主要存放在中断服务程序完成一次数据传送。 ④ DMA 传送: DMA 控制器可接管总线作为总线的主控设备,通过系统总线来控制存储 器和外设直接进行數据交换此种方式适用于需要大量数据高速传送的场合。 〔习题 7.7〕 参看图 7-5编程实现以下功能:当 K0 键单独按下时,发光二极管 L0~L7 将依次點亮(L0 L1,L2……L7) ,每个维持 200ms;当 K1 键单独按下时发光二极管 L0~L7 将反向依次

dx,0ffe0h in al,dx ; 输入一个字节 mov [bx],al inc bx loop again ; 循环,输入 100 个字节 〔习题 7.9〕 某个字符输出设备其数据端口和状态端口的地址均为 80H。在读取状态时当标志位 D7 =0 时,表明该设备闲可以接收一个字符。请编写利用查询方式进行数据傳送的程序段 要求将存放于缓冲区 ADDR 处的一串字符(以 0

jmp again ; 循环 done: 〔习题 7.10〕 以可屏蔽中断为例,说明一次完整的中断过程主要包括哪些环节 〔解答〕

中断请求:外设通过硬件信号的形式、向处理器引脚发送有效请求信号。 中断响应:在满足一定条件时处理器进入中断响应总线周期。 关中断:处理器在响应中断后会自动关闭中断 断点保护:处理器在响应中断后将自动保护断点地址。 中断源识别: 处理器识别出當前究竟是哪个中断源提出了请求 并明确与之相应的中断服务 程序所在主存位置。 现场保护:对处理器正在执行的程序的指令主要存放茬程序有影响的工作环境(主要是寄存器)进行保护 中断服务:处理器正在执行的程序的指令主要存放在相应的中断服务程序,进行数據传送等处理工作 恢复现场:完成中断服务后,恢复处理器原来的工作环境 开中断:处理器允许新的可屏蔽中断。 中断返回:处理器囸在执行的程序的指令主要存放在中断返回指令程序返回断点继续正在执行的程序的指令主要存放在原来的程序。 〔习题 7.11〕 什么是中断源为什么要安排中断优先级?什么是中断嵌套什么情况下程序会发生中断 嵌套? 〔解答〕 计算机系统中凡是能引起中断的事件或原洇,被称为中断源 处理器随时可能会收到多个中断源提出的中断请求, 因此 为每个中断源分配一级中断优先 权,根据它们的高低顺序決定响应的先后 一个中断处理过程中又有一个中断请求、并被响应处理,被称为中断嵌套 必须在中断服务程序中打开中断,程序才会發生中断嵌套 〔习题 7.12〕 明确如下中断有关的概念:中断源、中断请求、中断响应、关中断、开中断、中断返回、中 断识别、中断优先权、中断嵌套、中断处理、中断服务。 〔解答〕 中断源:能引起中断的事件或原因 中断请求:是外设通过硬件信号的形式、向处理器引脚發送有效请求信号。 中断响应:中断响应是在满足一定条件时处理器进入中断响应总线周期。 关中断:禁止处理器响应可屏蔽中断 开Φ断:允许处理器响应可屏蔽中断。 中断返回:处理器正在执行的程序的指令主要存放在中断返回指令将断点地址从堆栈中弹出,程序返回断点继续正在执行的程序的指令主要存放在原 来的程序 中断识别: 处理器识别出当前究竟是哪个中断源提出了请求, 并明确与之相應的中断服务程 序所在主存位置 中断优先权: 为每个中断源分配一级中断优先权, 即系统设计者事先为每个中断源确定处理 器响应他们嘚先后顺序 中断嵌套:在一个中断处理过程中又有一个中断请求被响应处理,称为中断嵌套 中断处理:接到中断请求信号后,随之产苼的整个工作过程称中断处理。 中断服务:指处理器正在执行的程序的指令主要存放在相应的中断服务程序进行数据传送等处理工作。 〔习题 7.13〕 按照图 7-10 所示的中断查询接口与相应的流程图编写用于中断服务的程序段。具体要求 是当程序查到中断设备 0 有中断请求(对應数据线 D0) ,它将调用名为 PROC0 的子程序; 如此依次去查中断设备 1~中断设备 3,并分别调用名为 PROC1~PROC3 的子程序 〔解答〕 sti

控制器控制下被读出傳送给外设。 DMA 写:外设的数据在 DMA 控制器控制下被写入存储器 单字节传送方式:每次 DMA 传送时仅传送一个字节。传送一个字节之后DMA 控制器釋放 系统总线,将控制权还给处理器 数据块传送: DMA 传送启动后就连续地传送数据,直到规定的字节数传送完 请求传送:DMA 传送由请求信號控制。如果请求信号一直有效就连续传送数据;但当请 求信号无效时,DMA 传送被暂时中止 〔习题 7.15〕 IA-32 处理器何时处于开中断状态、何时處于关中断状态? 〔解答〕 在 IA-32 处理器中若 IF=1,则处理器处于开中断状态 若 IF=0, 则处理器处于关中断状态 IF=0 关中断的情况有: 系统复位后, 任何一个中断 (包 括外部中断和内部中断)被响应后正在执行的程序的指令主要存放在关中断指令 CLI 后。 〔习题 7.16〕

简述 IA-32 处理器的中斷工作过程 〔解答〕 IA-32 处理器获得向量号识别出中断源后,中断或异常接着的工作过程如下: (1)将标志寄存器 EFLAGS 压入堆栈保护各个标志位;将被中断指令的逻辑地址(代码 段寄存器和指令指针寄存器内容)压入堆栈,保护断点 (2)如果有错误代码,将其压入堆栈(有些異常产生错误代码更具体地表明产生异常的 原因) 。实地址方式的异常不返回错误代码 (3)根据向量号获得中断服务程序(中断或异瑺的处理程序)的段选择器和指令指针,分 别传送给代码段寄存器 CS 和指令指针寄存器 EIP (4)对于中断,要设置中断允许标志 IF 为 0即禁止进┅步的可屏蔽中断。 (5)控制转移至中断服务程序入口地址(首地址) 开始正在执行的程序的指令主要存放在中断或异常处理程序。 中斷服务程序最后是中断返回指令 IRET中断返回指令 IRET 将断点地址和标志寄存器出栈 恢复, 如果压入了错误代码还需要相应增量堆栈指针 于是控制又返回到断点指令继续正在执行的程序的指令主要存放在。 〔习题 7.17〕 IA-32 处理器的中断向量表和中断描述符表的作用是什么 〔解答〕 IA-32 处悝器的中断向量表和中断描述符表的作用都是获取中断服务程序的入口地址(称为 中断向量) ,进而控制转移到中断服务程序中 〔习题 7.18〕 IRR,IMR 和 ISR 三个寄存器的作用是什么 〔解答〕 中断请求寄存器 IRR:保存 8 条外界中断请求信号 IR0~IR7 的请求状态。Di 位为 1 表示 IRi 引脚有中断请求;为 0 表示該引脚无请求 中断屏蔽寄存器 IMR: 保存对中断请求信号 IR 的屏蔽状态。 位为 1 表示 IRi 中断被屏蔽 Di (禁 止) ;为 0 表示允许该中断 中断服务寄存器

苐 8 章 常用接口技术 〔习题 8.1〕简答题 〔解答〕 ① 方式 1 可以通过编程产生一个确定宽度的单稳脉冲,故称工作方式 1 为可编程单稳脉冲 工作方式 ② 因为计数器是先减 1,再判断是否为 0所以写入 0 实际代表最大计数值。

③ 通过控制字的 D7 位来区别:D7=1该控制字为方式控制字;否则为位控制字。 ④ 8255 的三种工作方式均可实现输出数据锁存即数据输出后被保存在 8255 内部,可以 读取出来只有当 8255 再输出新一组数据时才改变。 ⑤ Modem 称为调制解调器, 将数字信号转换为适合在***线路上传送的模拟信号 (调制) 以及将***线路的模拟信号转换为数字信号(解调) ⑥ 因绝大多数设备只使用 RS-232C 标准的其中 9 个信号,所以 PC 机上就配置 9 针连接器 ⑦ 两台微机进行短距离通信,可以不使用调制解调器直接利鼡 232C 接口连接,被称为 零调制解调器(Null Modem)连接 ⑧ UART 表示通用异步接收发送器, 主要功能是将并行数据转换为串行数据发送 以及实现 串行数據转换为并行传送给处理器。 ⑨ 采用多路开关通过微型机控制,把多个现场信号分时地接通到 A/D 转换器上转换达 到共用 A/D 转换器以节省硬件的目的。 ⑩ 处理器输出数据都只在输出指令 OUT 正在执行的程序的指令主要存放在的极短时间内出现在数据总线上 慢速的外设 不能及时获取,所以主机与 DAC 之间必须连接数据锁存器 〔习题 8.2〕判断题 〔解答〕 ① 对 ② 对 ③ 对 ④ 对 ⑤ 对 ⑥ 错 ⑦ 错 ⑧ 对 ⑨ 对 ⑩ 对 TxD,RxDGND ⑧ 通信线路控制(CLR) ,B(1FH) 2FBH ⑨ , ⑩ 53H(=51≈51.2=2÷10×256) 〔习题 8.4〕 8253 芯片每个计数通道与外设接口有哪些信号线每个信号的用途是什么? 〔解答〕 CLK 时钟输入信号:在计数过程中此引脚上每输入一个时钟信号(下降沿) ,计数器的计 数值减 1 GATE 门控输入信号:控制计数器工作,可分成电平控制和上升沿控制两种类型 OUT 计数器输出信号:当一次计数过程结束(计数值减为 0) ,OUT 引脚上将产生一个输出 信号 〔习题 8.5〕 8253 芯片需要几个 I/O 地址,各用于何种目的 〔解答〕 4 个,读写计数器 01 和 2,及控制字 〔习题 8.6〕

试按如下要求分别编写 8253 的初始化程序,已知 8253 的计数器 0~2 和控制字 I/O 地址依 次为 204H~207H ① 使计数器 1 工作在方式 0,仅用 8 位二进制计数计数初值为 128。 ② 使计数器 0 工作在方式 1按 BCD 码计数,计数值为 3000 ③ 使计数器 2 工作茬方式 2,计数值为 02F0H 〔解答〕 ① mov al,50h mov

输出时序,说明数据输出的过程 〔解答〕 ① 中断方式下,处理器响应中断正在执行的程序的指令主要存放在输出 OUT 指令:输出数据给 8255,发出信号查 询方式下,通过端口 C 的状态确信可以输出数据处理器正在执行的程序的指令主要存放在输絀指令; ② 信号一方面清除 I***,另一方面在上升沿使有效通知外设接收数据。实质上信号是外 设的选通信号; ③ 信号结束后数据从端口數据线上输出。当外设接收数据后发出响应; ④ 信号使无效,上升沿又使 I*** 有效(允许中断的情况) 发出新的中断请求。 〔习题 8.9〕 设定 8255 芯片的端口 A 为方式 1 输入端口 B 为方式 1 输出,则读取口 C 的数据的各位是 什么含义 〔解答〕 PC0:端口 B 的中断请求信号 PC1:端口 B 输出缓冲器满信号 PC2:端口 B 中断允许控制位 PC3:端口 A 的中断请求信号 PC4:端口 A 中断允许控制位 PC5:端口 A 输入缓冲器满信号

PC6/PC7:I/O 信号 〔习题 8.10〕 用 8255 端口 A 方式 0 与打印机接口示唎中,如果改用端口 B其他不变,说明应该如何修 改接口电路和程序 〔解答〕 修改电路:将端口 B 的 PB0~PB7 接打印机的数据位 DATA0~DATA7 即可。 修改程序:将输出数据端口改为 FFFAH 即可 〔习题 8.11〕 用 8255 端口 A 方式 1 L0~L3 亮,表示系统该 控制点运行正常;开关闭合则对应发光二极管不亮说明该控制点絀现故障。编写 8255 的

〔习题 8.14〕 串行异步通信发送 8 位二进制数 :采用起止式通信协议使用奇校验和 2 个停止 位。画出发送该字符时的波形图若用 1200 bps,则每秒最多能发送多少个数据 〔解答〕 每个字符的位数是:1 个起始位+8 个数据位+1 个奇校验位+2 个停止位=12 位,采用 1200bps、即每秒 1200 位嘚传送速率则每秒最多能发送 1200÷12=100 个数据。 〔习题 8.15〕 微机与调制解调器通过 232C 总线连接时常使用哪 9 个信号线?各自的功能是什么利用 232C 進行两个微机直接相连通信时,可采用什么连接方式画图说明。 〔解答〕 常用的 9 个信号线及其各自的功能: TxD:串行数据发送端 RxD:串行數据接收端。 RTS:发送请求信号用于通知数据通信设备准备接收数据。 CTS:清除发送 CTS 信号有效响应 RTS 信号,即允许发送RTS 和 CTS 是一对用于数据發 送的联络信号。 DTR:数据终端准备就绪信号 DSR:数据装置准备好信号;DTR 和 DSR 也可用做数据终端设备与数据通信设备间的联络信 号 GND:信号地,咜为所有的信号提供一个公共的参考电平 CD:载波检测信号,当本地调制解调器接收到来自对方的载波信号时就从该引脚向数据 终端设備提供有效信号。 RI: 振铃指示 当调制解调器接收到对方的拨号信号期间, 该引脚信号作为***铃响的指示、 保持有效 利用 232C 进行两个微機直接相连通信时,可采用教材图 8-25 所示连接方式 〔习题 8.16〕 8250 的 IIR 是只读的,且高 5 位总是 0试分析 XT 机系统 ROM-BIOS 中下段程序的作用。如 不发生条件转迻则 RS232-BASE 字单元将存放什么内容? mov bx,0

中该段程序的作用是检测是否存在串行异步通信接口电路 如果不发生条件转移,说明存在异步通信接口電路RS232-BASE 字单元存放异步通信接口 电路的基地址:3F8H 和 2F8H。 〔习题 8.17〕 首先采用自循环查询方式在本机上实现例题 8-3然后购买或制作一个用于零调淛解调器连 接的 RS-232C 电缆, 修改例题 8-3 采用正常的查询方式实现两台微机的通信 如果在 Windows 的模拟 DOS 环境无法运行程序,则应该采用纯 DOS 启动微机在實方式下运行。读者还可 以改进例题 8-3 的功能例如每当按下回车键才将刚输入的字符串发送给对方,本机也显示 发送的信息 〔解答〕 〔***题 8.18〕 说明在模拟输入输出系统中,传感器、放大器、滤波器、多路开关、采样保持器的作用 DAC 和 ADC 芯片是什么功能的器件? 〔解答〕 传感器:将各种现场的物理量测量出来并转换成电信号 放大器:放大器把传感器输出的信号放大到 ADC 所需的量程范围。 低通滤波器:滤波器用於降低噪声、滤去高频干扰以增加信噪比。 多路开关:对多个模拟信号分时地接通到 A/D 转换器上转换达到共用 A/D 转换器以节省 硬件的目的。 采样保持器:对高速变化的信号使用采样保持器可保证 A/D 转换期间信号不变,保证转 换精度 D/A 转换器:将微机处理后的数字量转换成为模拟量(电压或电流) 。 A/D 转换器:将模拟量(电压或电流)转换成为数字量输入微机处理 〔习题 8.19〕 假定某 8 位 ADC 输入电压范围是-5V~+5V,求絀如下输入电压 Vin 的数字量编码(偏移 码) : ① 1.5V ② 2V ③ 3.75V ④ -2.5V ⑤ -4.75V

〔解答〕 ① A7H ② B4H ③ E0H ④ 40H ⑤ 06H 〔习题 8.20〕 ADC 的转换结束信号起什么作用,可以如何使用该信号以便读取转换结果? 〔解答〕 当 A/D 转换结束ADC 输出一个转换结束信号,通知主机读取结果 有多种使用 A/D 转换结束信号的方法,对应的程序设计方法也不同 查询方式: 把结束信号作为状态信号经三态缓冲器送到主机系统数据总线的某一位上。 主机 不断查询这个状态位發现结束信号有效,便读取数据 中断方式:把结束信号作为中断请求信号接到主机的中断请求线上。ADC 转换结束主动向 处理器申请中断。处理器响应中断后在中断服务程序中读取数据。 DMA 传送方式:如果 ADC 速度足够快可把结束信号作为 DMA 请求信号,采用 DMA 传送 方式 延时传送方法:不使用结束信号,微机延时到转换结束读取数据 〔习题 8.21〕 某控制接口电路如本题图形。需要控制时8255A 的 PC7 输出一个正脉冲信号 START 启动 A/D 轉换; ADC 转换结束在提供一个低脉冲结束信号 EOC 的同时送出数字量。 处理器采集该 数据进行处理,产生控制信号现已存在一个处理子程序 ADPRCS,其入口参数是在 AL 寄存器存入待处理的数字量 出口参数为 AL 寄存器给出处理后的数字量。 假定 8255 端口 A B,C 及控制端口的地址依次为 FFF8H~FFFBH要求 8255 嘚端口 A 为方式 1 输入、端口 B 为方式 0 输出。编写采用查询方式读取数据实现上述功能的程序段。 〔解答〕 ; 8255A 初始化 mov al,1011000×b mov dx,0fffbh out

mov dx,0fff8h ; 输入数据 in al,dx call adprcs ; 处理数据 mov dx,0fff9h out dx,al ; 输出数據 〔习题 8.22〕 图 8-19c 矩阵键盘还可以使用反转方法识别按键 首先, 将行线作为控制线接一个输出端口 将列线作为检测线接一个输入端口。 CPU 通過输出端口将行线 (控制线) 全部设置为低电平 然后从输入端口读取列线(检测线) 。如果此时有键被按下则必定会使某列线为“0” 。然 后将行线和列线的作用互换,即将列线作为控制线接输出端口行线作为检测线接输入端 口。并且将刚才读得的列值从列线所接端口输出,再读取行线的输入值那么,闭合键所 在的行线值必定为“0” 这样,当一个键被按下时必定可以读得一对唯一的行值和列徝。 能够采用反转法识别按键需要一个条件:连接行线和列线的接口电路必须支持动态改变输 入、输出方式图 8-19c 使用 8255A,其 3 个端口可以编程妀变请编写扫描程序。 〔解答〕 第 9 章 处理器性能提高技术 〔习题 9.1〕简答题 〔解答〕 (1)传统上提高计算机性能的方法是采用复杂的、功能强大的指令即复杂指令集计算机 结构 CISC。精简指令集计算机结构 RISC 从根本上打破了这个观念使用简单指令,更便于 硬件实现高性能 (2)分支预测技术是用于解决指令流水线技术中存在的控制相关,即转移指令导致性能降 低的问题 (3)浮点数据采用规格化形式可以表达哽大、更精确的数据,也避免编码的多样性 (4)浮点数据编码无法表达任意精度的数据,所以需要舍入但整数编码表达的数据都是 精確的数据。 (5)多媒体指令的一个突出特点是一条指令同时处理多组数据即单指令多数据 SIMD。 〔习题 9.2〕判断题 〔解答〕 ① 对 ② 对 ③ 错 ④ 错 ⑤ 错 〔习题 9.3〕填空题 〔解答〕 ① Complex Insruction Set Computer复杂指令集计算机,Reduced精简的,CISC ② 指令预取(PF) 、指令译码 1(D1) 、指令译码 2(D2) 、指令正在执行的程序嘚指令主要存放在(EX)和回写(WB) ③ ±2-126±(2-2-23)×2127,下溢上溢 ④ 32,823 ⑤ CEH,7FH 〔习题 9.4〕 通过处理器性能公式说明影响程序正在执行嘚程序的指令主要存放在时间的三个方面。 〔解答〕 处理器正在执行的程序的指令主要存放在时间=IC×CPI×T 其中: IC 为程序的指令条数 CPI 为正在執行的程序的指令主要存放在每条指令所需的平均时钟周期数

T 为每个时钟周期的时间也就是时钟频率的倒数 〔习题 9.5〕 什么是简单指令和複杂指令,结合 RISC 处理器说明把指令分为简单和复杂的原因。 〔解答〕 简单指令是指计算机基本的、常用的指令往往其功能也比较简单。而复杂指令是指功能强 大的指令但往往不常用。 计算机大部分时间是在正在执行的程序的指令主要存放在简单指令复杂指令的使用頻度都比较低。对一个 CISC 结构的 指令系统而言只有约 20%的指令被经常使用,其使用量约占整个程序的 80%;而该指令 系统中大约 80%的指令却佷少使用其使用量仅占整个程序的 20%;而且使用频度较高的 指令通常是那些简单指令。 〔习题 9.6〕 RISC 技术有哪些方面的主要特色 〔解答〕 指令条数较少。 寻址方式简单 面向寄存器操作。 指令格式规整 便于使用先进的流水线技术。 …… 〔习题 9.7〕 什么是指令流水线80486 采用哪幾级流水线,各级的主要操作分别是什么 〔解答〕 指令流水线是多条指令重叠正在执行的程序的指令主要存放在的一个处理器实现技术 (在一条指令还没有正在执行的程序的指令主要存放在结束就开始 后续指令) 。 Intel 80486 采用 5 级指令流水线: ① PF 步骤――指令预取(Prefetch) 处理器总昰从高速缓存读取一个 Cache 行,为 16 个 字节平均包括 5 条指令。 ② D1 步骤――指令译码 1(Decode Stage 1) 指令译码分成了 2 个步骤,D1 步骤对所有操 作码和寻址方式信息进行译码 ③ D2 步骤――指令译码 2 Decode Stage 2) D2 步骤将每个操作码扩展为 ALU 的控制信号, ( 并进行较复杂的存储器地址计算。 ④ EX 步骤――指令正茬执行的程序的指令主要存放在(Execute) EX 步骤完成 ALU 操作和 Cache 存取。 ⑤ WB 步骤――回写(Write Back) WB 步骤更新在 EX 步骤得到的寄存器数据和状态标志。 〔习題 9.8〕 影响流水线效率的主要指令相关有哪三个方面 〔解答〕 资源冲突、数据相关,控制相关 〔习题 9.9〕 已知 BF600000H 是一个单精度规格化浮点格式數据它表达的实数是什么? 〔解答〕 BF600000H=10

有效数字部分是 表示有效数=1.11 B=1.75。 所以这个实数为:-1.75×2-1=-1.75×0.5=-0.875。 〔习题 9.10〕 实数真值 28.75 如果用单精度规格化浮点数据格式表达其编码是什么。编程将单精度浮点 数据的编码显示出来 〔解答〕 28.75=B=1.110011B ×24 于是,符号位=0 指数部汾是 4,8 位阶码为 (=4+127=131) 有效数字部分是 。 这样28.75 表示成单精度浮点数为: 0 B =10 00 B =41E60000H 数据上溢:当数据比能够表达的最小数还要小、还要接近 0 时,就是数据下溢 数据下溢:当数据比能够表达的最大数还要大时,就是数据上溢 (2) 规格化有限数:使用规格化格式表达的数據。它表达的数值是:1.XXX…XX它的最高位恒 为 1,随后都是小数部分;有效数字只需要表达小数部分隐含一个整数 1。 非规格化有限数:指数編码为全 0;有效数字仅表示小数部分、但不能是全 0表示的数值 是:0.XXX…XX,用于表达比规格化格式不能表达的更小的实数 (3) NaN:指数编码昰全 1、有效数字编码不是全 0 的浮点格式编码,被称为非数 NaN(Not a Number) 它不是实数。 无穷大:指数编码为全 1有效数字编码为全 0 的浮点格式编码,用于表达大于规格化浮点 数所能表达的最大数的真值 〔习题 9.12〕 什么是紧缩整型数据和紧缩浮点数据?扩展有 SSE3 指令的 Pentium 4 支持哪些紧缩数据類 型 〔解答〕 紧缩整型数据是指多个 8、16、32 或 64 位的整型数据组合形成一个整体。

紧缩浮点数据是指多个单精度或双精度浮点数据组合形成┅个整体 SSE3 指令的 Pentium 4 支持 128 位紧缩数据类型,具体有: 紧缩字节、字、双字、4 字整型数据; 紧缩单精度浮点数据; 紧缩双精度浮点数据 〔习題 9.13〕 SIMD 是什么?举例说明 MMX 指令如何利用这个结构特点 〔解答〕 SIMD 表示单指令多数据(Single Instructon Multiple Data) 。 例如PADDB 一条指令可以实现 8 组整型字节数据的求和,嘚到独立的 8 个结果 〔习题 9.14〕 什么是环绕运算和饱和运算。给出如下结果: (1)环绕加:7F38H+1707H (2)环绕减:1707H-7F38H (3)无符号饱和加:7F38H+1707H (4)无苻号饱和减:1707H-7F38H (5)有符号饱和加:7F38H+1707H (6)有符号饱和减:1707H-7F38H 〔解答〕 环绕运算:通常的算术运算即当无符号数据的运算结果超过其数據类型界限时,它进行正 常进位借位但是,每个进位或借位并不能反映出来 饱和运算:指运算结果超过其数据界限时,其结果被最大戓最小值所替代 (1)环绕加:7F38H+1707H=963FH (2)环绕减:1707H-7F38H=87CFH (3)无符号饱和加:7F38H+1707H=963FH (4)无符号饱和减:1707H-7F38H=0000H(饱和) (5)有符号饱和加:7F38H+1707H=7FFFH(饱和) (6)有符号饱和减:1707H-7F38H=87CFH 〔习题 9.15〕 简单说明如下名词(概念)的含义: (1)Load-Store 结构 (2)超级指令流水线 (3)指令流水线的时空图 (4)指令相关 (5)就近舍入 〔解答〕 (1)Load-Store 结构:处理器内部设置较多的通用寄存器,使多数操作(算术逻辑运算) 都在寄存器与寄存器之間只有“取数 Load”和“存数 Store”指令访问存储器。或者说 访问存储器只能通过 Load 和 Store 指令实现。 (2)超级指令流水线:将指令流水线的步骤(階段)化分得更多并加倍内部时钟频率, 使紧接着的 2 个步骤可以重叠一部分正在执行的程序的指令主要存放在 使得每个时钟可以完成哆条指令的正在执行的程序的指令主要存放在, 进而提 高指令流水线的性能 (3)指令流水线的时空图:描绘流水线操作的时间空间图、簡称时空图,其横坐标表示时 间纵坐标是指令处理的各个阶段、表示空间。

(4)指令相关:指令流水线中指令之间存在相互依赖关系,使得下一条指令无法在设计 的单位时间内正在执行的程序的指令主要存放在的情况 (5)就近舍入:浮点数据的舍入方法之一,类似“㈣舍五入”原则舍入结果最接近准确 值。如果上下两个值一样接近就取偶数结果(最低位为 0) 。 第 10 章 并行处理技术 〔习题 10.1〕简答题 (1)英特尔所谓的微结构对应计算机层次结构的哪个层次 (2)新一代 IA-32 处理器将指令译码为微操作有什么特别的作用? (3)乱序正在执行的程序的指令主要存放在是什么含义 (4)Flynn 分类法以什么内容为分类依据? (5)为什么说动态超标量技术为软件提供了免费“性能午餐” 〔解答〕 (1)微结构对应计算机层次结构的控制层。 (2)IA-32 处理器将指令译码为微操作可以将复杂指令转换为简单指令便于硬件实现。 (3)乱序正在执行的程序的指令主要存放在是指令的正在执行的程序的指令主要存放在不一定是传统的串行顺序方式可能会出现后面指令先正在执行的程序的指令主要存放在的 情况。 (4)以并行操作的指令流个数和数据流个数为分类依据 (5)因为动态超标量技术采用硬件實现性能提高,即使软件没有改进也能提高性能 〔习题 10.2〕判断题 (1)在 Pentium 中,只要两条指令不存在数据相关就能配对并行正在执行的程序的指令主要存放在。 (2)指令流水线运用了时间重叠思想提高并行性 (3)数据相关可以用寄存器重命名技术消除。 (4)Intel 64 结构支持 16 个 64 位整数通用寄存器 (5)Intel Core 微结构支持超线程技术。 〔解答〕 ① 错 ② 对 ③ 错 ④ 对 ⑤ 错 〔习题 10.3〕填空题 (1)有两种性质的并行性同一个时刻发苼的并行性称__________,同一段时间内发生的 并行性称__________ (2)Pentium 处理器中,某时刻正在执行的程序的指令主要存放在一条转移指令它在 BTB 的历史位为 10,则预测 __________分支;如果确实发生分支则该历史位成为__________;而如果预测错误,则该 历史位成为__________ 如果某个转移指令的实际正在执行的程序的指囹主要存放在情况是分支 “发生―不发生―发生― 不发生―发生―不发生……” ,则利用 Pentium 的分支预测机构它的准确度约为百分之 __________。 (3)基于 IA-64 结构的安腾处理器使用了__________技术一个 128 位的指令束包括 __________条指令,还有指示指令并行性的模板域 (4)Intel 64 结构新增 8 个通用寄存器,名称为__________;原来的 8 个通用寄存器被扩展 为 64 位名称为__________。 (5)多核处理器属于多处理器系统对应 Flynn

⑤ MIMD 〔习题 10.4〕 对比 Intel 80486 指令流水线和 Pentium 超标量指令流水线,指絀它们的异同 〔解答〕 Pentium 的超标量整数指令流水线的各个阶段类似 Intel 80486,仍分成了 5 个步骤但是其 后 3 个步骤可以在它的 2 个流水线(U 流水线和 V 流沝线)同时进行。 〔习题 10.5〕 Pentium 超标量指令流水线为什么限制复杂指令、存在数据相关的指令和转移指令等不能实 现配对正在执行的程序的指囹主要存放在 〔解答〕 因为 Pentium 的两条指令流水线 U 和 V 并不是完全相同的,例如 V 流水线只能正在执行的程序的指令主要存放在简单指 令所以鈈可能实现复杂指令的配对正在执行的程序的指令主要存放在。 存在数据相关的指令 需要正在执行的程序的指令主要存放在完前一条指囹才能得到后一条指令需要的操作数, 所以也无 法同时进行正在执行的程序的指令主要存放在 存在转移指令, 需要正在执行的程序的指囹主要存放在完前一条指令才能决定是否正在执行的程序的指令主要存放在后一条指令 所以也不能配对正在执行的程序的指令主要存放茬。 〔习题 10.6〕 什么是 Pentium 的动态分支预测和 Pentium II 的静态分支预测对于如下两个程序片断,分 别指出 Pentium 处理器第一次正在执行的程序的指令主要存放茬转移指令时动态分支预测的结果和 Pentium II 的静态分支 预测的结果 (1)单分支结构 mov ecx,12 cmp eax,7 jne EAX_7 mov ecx,17 EAX_7: (2)循环结构 loopx: add list[eax*4],5 dec eax jnz loopx 〔解答〕 动态分支预测:Pentium 维持一个分支目标缓沖器 BTB,用它记录最近使用的转移指令的有 关情况并动态预测当前转移指令是否发生分支;在预测正确时就可以无延迟的正在执行的程序嘚指令主要存放在,如果 预测错误则产生 3~4 个时钟的延迟。 静态分支预测:解决对于分支目标缓冲器 BTB 中(动态分支预测)没有记录的转迻指令的分 支预测问题预测无条件转移指令发生分支。预测向前分支的条件转移指令不发生分支预 测向后分支的条件转移指令发生分支。 (1)Pentium 动态分支预测:不分支Pentium II 静态分支预测:不分支 (2)Pentium 动态分支预测:不分支。Pentium II 静态分支预测:分支 〔习题 10.7〕 说明 NetBurst 微结构的踪迹 Cache 为什么优于 P6 微结构的 L1 指令 CacheCore 微结构的双 核处理器共享 L2 Cache 为什么优于 Pentium D 独立使用 L2 Cache? 〔解答〕 踪迹 Cache 存储已译码指令即微操作存储已译码指令使得 IA-32 指囹的译码从主要正在执行的程序的指令主要存放在循 环中分离出来。指令只被译码一次并被放置于踪迹

重复使用。P6 微结构的 L1 指令 Cache 仍然是存储原始指令代码的指令 Cache取指后还需 要译码。 Core 微结构中两个处理器共享 L2 Cache,可以充分利用 Cache 空间为两个处理器共用每 个处理器各有独立嘚 L2 Cache,则 Cache 只能为对应的处理器服务 〔习题 10.8〕 简单说明如下名词(概念)的含义: (1)超标量技术 (2)指令级并行 (3)乱序正在执行的程序嘚指令主要存放在 (4)寄存器重命名 (5)推测正在执行的程序的指令主要存放在 (6)VLIW (7)EPIC (8)超线程技术 (9)SIMD (10)多核处理器 〔解答〕 (1)超标量技术:指提高标量指令的正在执行的程序的指令主要存放在性能而设计的一种处理器技术。处理器采用多条 指令流水线可以实現一个时钟周期完成多条指令的正在执行的程序的指令主要存放在。 (2)指令级并行:指令是处理器正在执行的程序的指令主要存放在的基本单位指令级并行是指发掘指令之间的并行执 行能力,也就是提高处理器内部操作的并行程度 (3)乱序正在执行的程序的指令主要存放在:多条指令进入处理器正在执行的程序的指令主要存放在单元,指令正在执行的程序的指令主要存放在的顺序不必一定按照程序顺序、 可能是乱序的即乱序正在执行的程序的指令主要存放在。 (4)寄存器重命名:对于使用相同寄存器名引起的假数据相关只要更改寄存器名,就可 以消除指令相关的技术 (5)推测正在执行的程序的指令主要存放在:处理器采用分支预测技术推测指令分支路径,并按照推测结果发送和正在执行的程序的指令主要存放在 指令这就是推测正在执行的程序的指令主要存放在。 (6)VLIW:超长指令字一种利用軟件编译器方法提高指令并行正在执行的程序的指令主要存放在能力的技术。 (7)EPIC:显式并行计算源于 VLIW 技术,64 位 Itanium 系列处理器主要采用的提高性能 的技术 (8)超线程技术:它使一个物理处理器看似有两个逻辑处理器,每个逻辑处理器维持一套 完整的结构状态共享几乎物悝处理器上所有正在执行的程序的指令主要存放在资源。 (9)SIMD:单指令多数据指一条指令可以同时对多组数据进行操作(正在执行的程序的指令主要存放在) 。 (10)多核处理器:在一个物理封装内制作了两个或多个处理器正在执行的程序的指令主要存放在核心形成的处理器 〔习题 10.9〕 简单总结新一代 IA-32 处理器的结构特点: (1)Pentium 的超标量指令流水线 (2)Pentium II 的动态正在执行的程序的指令主要存放在结构 (3)Pentium 4 的超线程技术 (4)多核处理器结构 〔解答〕 (1) Pentium 的超标量指令流水线: 利用资源重复的思想, Pentium 处理器采用超标量技术 设计了 2 个可以并行操作的囸在执行的程序的指令主要存放在单元, 形成了 2 条指令流水线 这样, 在一定条件下 Pentium 允许在一个时钟周期中同时运行 2 条整数指令, 或者運行一条浮点指令 (但浮点交换指令可

以与另一条浮点指令配对同时正在执行的程序的指令主要存放在) (2)Pentium II 的动态正在执行的程序的指令主要存放在结构:包含 3 个组成部分:顺序发送前端、乱序核心和顺序退出 单元,它们之间通过重排序缓冲区 ROB(Re-Order Buffer)建立联系具有采用 3 蕗超标量、 12 级超级流水线。 (3)Pentium 4 的超线程技术:超线程技术为 IA-32 结构引入了同时多线程概念它使一个 物理处理器看似有两个逻辑处理器。 操作系统和用户程序像传统多处理器系统一样在逻辑处 理器上调度线程或进程两个逻辑处理器的指令可以在共享的正在执行的程序的指囹主要存放在资源上同时保持和正在执行的程序的指令主要存放在。 (4)多核处理器结构:在一个物理封装内制作了两个或多个处理器正茬执行的程序的指令主要存放在核心使多个处理 器耦合得更加紧密,同时共享系统总线、主存等资源可以有效地正在执行的程序的指囹主要存放在多线程的应用程序。 〔习题 10.10〕 追踪处理器技术最新发展选择某个方面,做一篇新技术发展的论文

注:文中大部分文章参考引用都昰自身的引用为了不产生混淆,各个章节标题使用英文原称同时参考引用也用英文原称。

每个链接都由一个链接脚本控制这个脚本甴链接命令语言编写。

链接脚本的主要目的是描述输入文件中的段应当如何映射到输出文件中并控制输出文件的内存布局。多数链接脚夲都正在执行的程序的指令主要存放在类似功能但是,如果需要链接脚本也可以使用下面所描述的命令指挥链接器进行很多其他操作。

链接器通常使用一个链接脚本如果没有为其提供一个,链接器将会使用默认的编译在链接器正在执行的程序的指令主要存放在文件内蔀的脚本可以使用命令’–verbose’显示默认的链接脚本。一些命令行选项例如’-r’,’-N’会影响默认的链接脚本

你可以通过在命令行使鼡’-T’命令使用自己的脚本。如果使用此命令你的链接脚本将会替代默认链接脚本。

也可以通过将脚本作为链接器输入文件隐式的使用鏈接脚本参考Implicit Linker Scripts。

为了描述链接脚本语言我们需要定义一些基本概念和词汇。

链接器将许多输入文件组合成一个输出文件输出文件和烸个输入文件都有一个特定的已知格式成为目标文件格式。每个文件都被称为目标文件输出文件通常叫做可正在执行的程序的指令主要存放在文件,但我们仍将其称为目标文件每个目标文件在其他东西之间,都有一个段列表有时把输入文件的段称作输入段,类似的輸出文件的段称作输出段。

每个目标文件中的段都有名字和大小多数段还有一个相关的数据块,称为 段内容一个段可能被标记为可加載,表示当输出文件运行时段内容需要先加载到内存中。一个没有内容的段可能是可分配段即在内存中留出一段空间(有时还需要清零)。一个即不是加载又不是可分配的段通常含有一些调试信息。

每个加载或可分配输出段有两个地址第一个地址为VMA,或者叫做虚地址这是当输出文件运行时段所拥有的地址。第二个地址是LMA或者叫加载内存地址。这是段将会被加载的地址一个它们会产生区别的例孓是,当一个数据段加载到ROM 此后在程序启动时被复制到RAM中(这个技术通常被用来初始化全局变量)。此种情况下ROM使用LMA地址,RAM使用VMA地址

如果想查看目标文件中的段,可以用objdump程序的’-h’选项

每个目标文件还有一个符号列表,称为符号列表一个符号可能是被定义的或者未定义的。每个符号都有一个名字且所有已定义的符号在其他信息中间都有一个地址。如果将一个c或者c++程序编译成目标文件会将所有萣义过的函数和全局变量以及静态变量作为已定义符号。所有输入文件引用的未定义的函数或者全局变量会成为未定义符号

你可以参看目标文件中的符号,使用nm程序或使用objdump程序的’-t’选项

链接脚本是文本的文件。

一个链接器脚本是一系列的命令每个命令都是一个关键芓,可能后面还跟有一个参数或者一个符号的赋值。使用分号分割命令空格通常被忽略。

类似于文件名或者格式名的字串可以直接输叺如果文件名含有一个字符例如逗号,(逗号被用来分割文件名)你可以将文件名放在双引号内部这里禁止文件名内使用双引号字符。

你可以像一样在链接脚本内包含注释由’/*’和’*/’划分。和C一样注释在句法上被当作空格。

多数脚本链接都很简单

一个最简单的鈳能的脚本只有一个命令:’SECTIONS’。你使用’SECTIONS’命令描述输出文件的内存布局

‘SECTIONS’命令是一个非常强大的命令。这里我们会描述它的一个簡单应用假设你的程序由代码,初始数据段以及未初始数据构成。这些将对应被放在’.text’,’.data’,以及’.bss’段中我们进一步假设这些是唯一将会出现在输入文件中的段。

在这个例子里我们设定代码应该被加载到地址0x10000,数据应该由地址0x8000000起始下面的链接脚本将会如此正在執行的程序的指令主要存放在:

输入的文字’SECTIONS’作为命令字’SECTIONS’,后面跟随着用花括号包围的一系列符号赋值以及输出段的描述

在上面嘚例子中’SECTIONS’命令内部的第一行设置了特殊符号’.’的值,’.’是一个位置计数器如果你不用其他方式指出输出段的地址(其他方法后媔会讨论),地址就会被位置计数器的当前值所设置位置计数器此后会依据输出段的大小而增加。在’SECTIONS’命令一开始位置计数器的值為’0’。

第二行定义了一个输出段’text’。语法上所需要的冒号在现在暂时可以被忽略在输出段后面的花括号内,你列出了应当被放入這个输出段的输入段名称’*’是一个通配符,可以与所有文件名匹配表达式’*(.text)’表示所有输入文件的’.text’输入段。

因为在’.text’被定义嘚时候位置计数器的值是’0x10000’链接器将会把输出文件’.text’的段地址设置为’0x10000’。

剩下的行定义了输出文件的’.data’和’.bss’段链接器将会紦’.data’输出段定为在地址’0x8000000’。在链接器放置’.data’段后位置计数器为’0x8000000’加上’.data’段的大小。因此’.bss’输出段在内存中将会紧紧挨在’.data’段后面

链接器会保证每个输出段依照要求对齐,如果有必要的话会增加位置计数器。在上面的例子中段’.text’和’.data’段可以正确的苻合任何对齐的限定条件,而链接器可能会在’.data’和’.bss’段之间创建一个小缝(为了使’.bss’段对齐)

如上,这是一个简单完整的链接脚夲

本章我们将介绍一些简单的脚本命令。

第一个在程序中正在执行的程序的指令主要存放在的指令被称为入口点(entry point)可以用E***Y脚本命令設置入口点,参数是一个符号名:

这里有几种方法设置入口点链接器会依照下面的方法依次尝试设置入口点,直到其中一种方法成功:

  • 命令行的’-e’选项指定的值
  • 一个目标约定的特殊符号(如果有定义的话);例如大多数目标符号为start但PE和BeOS系统会检查一个可能入口符号列表,以第一个碰到的为准 - ‘.text’的第一个字节的地址如果存在的话

注:也就是说,优先级为:命令>脚本文件>自定义start

一些脚本命令用来处理攵件 
在命令处包含链接脚本文件’filename’。文件将会在当前目录搜索以及任何’-L’命令行命令指定的路径。INCLUDE可以嵌套调用10层 
可以直接把INCLUDE放到顶层,MEMORY或者SECTIONS命令中或者在输出段描述中。

事实上如果你愿意,可以把所有输入文件列在链接脚本内然后仅使用’-T’命令调用链接器。

在sysroot前缀被设置的情况下且filename以’/’字符开始,且正在运行的脚本也处于sysroot前缀范围内filename将会在sysroot前缀范围内查找。否则链接器会尝试在當前目录打开如果没有找到,链接器会搜索库搜索路径sysroot前缀也可以通过把filename的第一个字符设置为’=’强制使用(’=’替换为sysroot)。参照的’-L’命令

当你使用INPUT命令在隐式链接脚本中,文件在链接脚本文件被包含的时刻才会被加入这可能会影响库的搜索。

此构造仅可以出现茬INPUT或GROUP命令中位于其他命令中间。此命令中的文件将会以类似于直接出现在INPUT或者GROUP命令中的文件一样处理除了ELF共享库,ELF共享库仅在真正需偠使用时才被添加这个构造本质上使能了列表中文件的’–as-needed’选项,并且恢复此前的–as-needed设置此后的–no-as-needed。

OUTPUT命令为输出文件命名使用脚夲中的OUTPUT(filename)与命令行的’-o filename’类似(参见)。如果同时设置了命令行的命令有效。 
你可以使用OUTPUT命令定义一个默认的输出文件名来替代通常默认嘚名称a.out

SEARCH_DIR命令添加一个ld搜索库的路径。使用SEARCH_DIR(path)与命令行的’-L path’类似(参见)如果都使用了,链接器将会搜索所有路径命令行给出的路径會优先搜索。

STARTUP命令类似于INPUT命令除了filename将作为首个被链接的输入文件处理,就像被在命令行第一个给出一样在一些把第一个文件当作入口點的系统上这个命令非常有效。

bfdname’(参考)如果都使用了,以命令行为准

可以使用三参数OUTPUT_FORMAT命令来使用不同的基于命令行’-EB’和’-EL’的格式。此命令允许链接脚本设置输出格式需要的大小端

如果即没有’-EB’也没有’-EL’被使用,那么输出格式将会使用第一个参数如果使鼡了’-EB’,输出格式将是第二个参数大端。如果使用了’-EL’输出格式将是第三个参数,小端

例如MIPS ELF目标默认的链接脚本使用如下的命囹:

这表示默认输出格式为’elf32-bigmips’,但如果在命令行输入了’-EL’命令输出文件将以’elf32-littlemips’格式输出。

TARGET命令设置读取输入文件时的BFD格式这将影响后面的INPUT和GROUP命令。此命令类似使用命令行指令’-b bfdname’(参见)如果使用了TARGET命令,但OUTPUT_FORMAT命令没使用则最后的TARGET命令还被用来设置输出文件的格式。(参见)

可以为MEMORY命令创建的内存区域提供别名每个名字最多指代一个区域。

REGION_ALIAS函数为内存区域创建一个别名这允许了输出段灵活嘚映射到内存区域。下面是一个例子:

假设有一个含有很多内存存储设备的系统的应用每个内存设备都有特殊的目的,易失内存RAM可以存放可正在执行的程序的指令主要存放在代码或者数据一些设备可能是只读的,非易失性内存ROM允许存储可正在执行的程序的指令主要存放茬代码和只读数据最后的是一个只读的,非易失的内存ROM2允许只读数据段读取,不允许指定代码段存储现在有四个输出段:

  • .data 可读写且需要初始化数据
  • .bss 可读写的置零初始化数据

目标是提供一个链接命令文件含有系统无关的定义输出段的部分,以及系统相关的把输出段映射箌系统有效内存区域的部分我们的嵌入式系统含有三个不同的内存设置A,B,C:

标记RAM/ROM或者RAM/ROM2表示此段被分别加载到区域ROM或者ROM2。注意三个设置的.data段的起始地址都位于.rodata段的末尾

下面是基本链接脚本处理输出段。其含有系统相关的linkcmds.memory文件文件描述了内存布局:

代码和只读数据存入ROM。可读寫数据放入RAM一个已初始化了的数据的镜像被加载到ROM,并在系统启动的时候读入RAM

代码放入ROM,只读数据放入ROM2可读写数据放入RAM。一个已初始化了的数据的镜像被加载到ROM2并在系统启动的时候读入RAM。

这里可以依据需要可以写一个普通的系统初始化流程将.data段从ROM或者ROM2拷贝到RAM:

注:目湔分析,应该是AT命令把读写数据.data段即加载到ROM又在RAM分配了空间

这里有几个其它的链接脚本命令。

确保exp表达式为非零的如果是零,则报错退絀 
注意此断言会在最终链接阶段之前进行检查。这表示在段内使用PROVIDE的定义如果用户没有为其设置值,此表达式将无法通过检测唯一嘚例外是PROVIDE的符号刚刚引用了’.’。因此一个如下断言:

如果没有在别的地方定义__stack_size将会失败。符号在段外定义的PROVIDE会在此前被求值因此他們可以被ASSERT。因此:

强制符号在输出文件中作为未定义符号这样做了,可能会引发从标准库中连接一些额外的模块。你可以为每一个’EXTERN’列絀几个符号,而且你可以多次使用’EXTERN’ 这个命令跟’-u’命令行选项具有相同的效果。

此命令类似于命令行命令’-d’:即便是使用了’-r’的偅定位输出文件也让ld为普通符号分配空间。

此命令在’-T’指定的脚本中典型应用是增强默认的SECTIONS例如,重复占位程序段它将把所有此湔的链接脚本的声明插入output_section的后面(或者前面),并且使’-T’不要覆盖默认链接脚本实际插入点类似于孤儿段。参见Location Counter插入发生在链接器紦输入段映射到输出段后。在插入前因为’-T’的脚本在默认脚本之前被解析,在’-T’脚本中的声明会先于默认内部脚本的声明而正在执荇的程序的指令主要存放在特别的,会先于默认脚本把输入段的声明被制成’-T’指定的输出段下例为’-T’脚本使用INSERT可能的情况:

在特萣的程序类型中,比如使用覆盖技术的嵌入式系统当一个段被加载到内存中,另一个段不会被加载任何两个段之间直接的引用都会带來错误。例如如果一个段中的代码调用另一个段中的函数,将会产生错误

NOCROSSREFS列出了一系列输出段的名字。如果ld检测到任何段间交叉引用将会报告错误并返回非零退出码。注意NOCROSSREFS使用输出段名称而不是输入段名称。

指定一个特定的输出机器结构参数为BFD库定义的名字之一(参考)。可以使用objdump程序的’-f’指令查看一个目标文件的结构

在链接脚本中,可以为符号赋值这将定义符号并将其放入全局的符号表內。

可以使用任何C的赋值操作符号为符号赋值:

第一种情况将会把表达式的值赋给符号其他情况里,符号必须已经定义过此后符号的徝会被相应调整。

特殊符号’.’代表位置计数器你可以在SECTIONS命令中使用它,参考Location Counter

表达式后面的分号不能省略。

后面会有表达式的定义參考Expressions。

你在写表达式赋值的时候,可以把它们作为单独的部分,也可以作为’SECTIONS’命令中的一个语句,或者作为’SECTIONS’命令中输出段描述的一个部分

符号的有效区域由表达式所在的段决定,更多信息参考Expression Section

下面是表示三种不同的使用符号赋值的地方:

在这个例子里,’floating_point’将被设置为0符号’_etext’被设置为紧随’.text’最后一个输入段后面的地址。符号’_bdata’将被定义为在’.text’输出段后面的一个4字节向上对齐的地址

为ELF目标的端口定义一个符号,符号将被隐藏并且不会被导出语法是HIDDEN(symbol = expression)。

这是上面简单赋值的例子使用HIDDEN重写:

这里此三个符号出了这个模块就不可見了。

有些情况下仅当一个符号被引用了却没有定义在任何链接目标中,才需要为链接脚本定义一个符号例如,传统链接器定义符号’etext’但是,ANSI C需要用户可以自由使用’etext’作为一个函数名称且不会引发错误只有当符号被引用却没被定义的时候,PROVIDE关键字可以定义一个苻号比如’etext’。语法为PROVIDE(symbol = expression)

下面是一个使用PROVIDE定义’etext’的例子:

在这个例子中,如果程序定义了’_etext’链接器将给出重复定义错误。然而另┅方面如果程序定义了’etext’,链接器将会默认使用程序中的定义如果程序已用了’etext’但没有定义它,链接器将使用链接脚本中的定义

类似PROVIDE。对于ELF目标的端口符号将被隐藏且不会被输出。

从源代码获得一个脚本定义的变量值不是直观的特别是一个脚本符号与一个高級语言定义的变量声明不符的时候,将使用一个没有值的变量替代它

在更深入前,需要注意的一点是编译器常常把源码的名称转变为鈈同的名字再存入符号表中。例如Fortran编译器通常在前面或者后面加一个下划线而C++ 偏爱额外的’name mangling(命名粉碎)’。因此在源码中定义的变量名称與链接脚本中定义的变量可能会有区别例如在一个中,一个链接脚本变量可能被认为是:

但在脚本中可能被定义为:

后面的例子中假設没有发生名字转换。

当一个高级语言比如C语言,声明了一个符号会发生两件事。第一是编译器在程序内存中保留足够的空间来保持這个符号第二是编译器在符号表中创建一个入口,用来保持符号的地址例如符号表含有保存符号值的内存块的地址。因此例如下面的C聲明在文件中为:

在符号表创建了一个名为’foo’的入口。此入口保存了一个’int’大小的内存块的地址块内数字1000被初始化存储。

当一个程序引用一个符号编译器生成的代码会首先存取符号表来查找符号的内存块的地址,此后代码从内存块中读取值因此:

在符号表中查找’foo’,得到符号相关的地址此后将1写入改地址。反之:

查找符号符号表内的’foo’获取它的地址,此后复制地址的值到与变量’a’相關的地址去

链接脚本的符号声明,相对来说在符号表中创建一个入口,但此时并不指派任何内存给它们因此它们是一个地址但没有徝。例如链接脚本定义:

在符号表创建一个符号称为’foo’并保持了内存地址1000,但没有任何特殊的东西被存储在地址1000这表示你不能存取鏈接脚本定义符号的值–它们没有任何值–所有你可以做的仅为存取链接脚本定义符号的地址。

因此当你在源代码中使用一个链接脚本萣义的符号时你应该总是使用符号的地址,永远不要尝试使用它的值例如假设你想把.rom段的内容复制到.FLASH段中,且链接脚本含有以下声明:

C源码正在执行的程序的指令主要存放在这个复制应当类似于:

注意操作符’&’的使用上面是正确的代码。一种替换是把符号被当作一個数组变量的名称,因此代码变成了:

注意此时不需要操作符’&’了

SECTIONS命令告诉链接器如何将输入段映射到输出段,以及如何把输出段放叺内存中

‘E***Y’命令和符号赋值在’SECTIONS’命令中是允许的,这是为了方便在这些命令中使用位置计数器。这也可以让连接脚本更容易理解,因为伱可以在更有意义的地方使用这些命令来控制输出文件的布局

输出段描述和重叠将在后面分析。

如果你在链接脚本中不使用SECTIONS命令链接器将会把所有输入段依照碰到的顺序分别放在一个独立名称的输出段中。例如如果所有输入段出现在第一个文件中,输出文件的段的顺序将会与第一个输入文件保持一致第一个段被放在地址0。

完整的输出段描述看起来像下面这样(一个sections-command):

多数输出段不需要使用多数的鈳选段属性

SECTION边上的空格是必须的,所以段名称是明确的。冒号跟花括号也是必须的最后的逗号如果使用了fillexp,且下一个段命令看起来像是表达式的延续的时候可能会需要断行和其他的空格是可选的。

输出段的名字是sectionsection必须符合你的输出格式的规定。在仅支持一个有限段数目的格式中例如a.out,名字必须为该格式支持的段名称之一(例如a.out格式仅允许’.text’’.data’,’.bss’)如果输出格式支持任意数量的段,但名稱仅能为编号(例如Oasys)名字应该以双引号包裹的数字字串形式提供。一个段名字可能由任何字符组成但一个含有许多特殊字符例如逗號等的名字需要被双引号括起来。

地址(address)是一个输出段VMA(虚地址)的表达式此地址为可选参数,但如果给出了地址则输出地址就会被精确的设置到给定值。

如果输出的地址没有给定则依照下面的尝试选择一个地址。此地址将会被调整到符合输出端要求的对齐地址輸出段的对齐要求是所有输入节中含有的对齐要求中最严格的一个。

  • 如果为段设置了内存区域则段被放如该区域,并且段地址为区域中嘚下一个空闲位置
  • 如果使用MEMORY命令创建了一个内存区域列表,此时第一个属性匹配段的区域被选择来加载段段地址为区域中的下一个空閑位置。参见MEMORY
  • 如果没有指定的内存区域,或者没有匹配段的则输出地址将会基于当前位置计数器的值。

有着精细的差别第一个将会紦’.text’的地址设置为位置计数器。第二个将会依照所有’.text’输入段中最严格的对齐要求设置地址为当前位置计数器对齐的值。(第一个囿address第二个没有,启动了探索机制)

地址可以是任何表达式;参考Expressions例如,如果你想在0x10字节边界上对齐段因此段地址最低的四个位(原攵是bit,不是byte有的翻译有错误)为0,你可类似如下面这么做:

此代码可以工作因为ALIGN将会返回位置计数器依照参数向上对齐的值。

为段指萣地址将会改变位置计数器的值如果该段不是空段的话。(空段被忽略)

输入段描述是最基本的链接脚本操作你使用输出段告诉链接器如何把程序放到内存中。你使用输入段描述告诉链接器如何把输入文件映射到你的内存布局

一个输入段描述由跟随在段名称后面括号包含的一个可选的文件名称列表构成。

文件名和段名称可以为通配符我们将在后面解释(参考Input Section Wildcards)。

最普通的输入段描述为在一个特定输絀段内包含所有输入段例如,把所有输入段放入’.text’段可以这么写:

此处的’*’是一个通配符,可以匹配任何文件名如果想从通配苻匹配的文件列表中排除一系列文件,可以使用EXCLUDE_FILE例如:

有两种方法包含更多的段:

两种方法的区别是输入段的’.text’和’.rata’段出现在输出Φ的顺序。第一个例子里他们将被混合在一起,按照链接器找到它们的顺序存放另一个例子中,所有’.text’输入段将会先出现后面是’.rdata’输入段。

你可以指定一个文件名来包含特定文件的段如果一个或者多个你的文件需要被放在内存中的特定位置,你可能需要这么做例如:

如果想使用段标志来选择输入文件的段,可以使用INPUT_SECTION_FLAGS

下面是一个例子,使用ELF的段头部标记:

在此例中输出段’.text’将被由那些匹配名字(.text)且段头部标志设置了SHF_MERGE和SHF_STRINGS的段构成。输出段’.text2’由那些匹配名字(.text)且段头部标志未设置SHF_WRITE的段构成

你也可以指出特别的关联库名称的文件,命令是 库匹配模板:文件名模板 冒号两边不能有空格。 

‘archive’和’file’都可以含有shell的通配符在基于DOS的系统里,链接器会假定一个单字哏着一个冒号是一个特殊的驱动符因此’c:myfile.o’是一个文件的特殊使用,而不是关联库’c’的’myfile.o’文件’archive:file’可以使用在EXCLUDE_FILE列表中,但不能出現在其他链接脚本内部例如,你不能使用’archive:file’从INPUT命令中取出一个库相关的文件

如果你使用一个文件名而不指出段列表,则所有的输入攵件的段将被放入输出段通常不会这么做,但有些场合比较有用例如:

当你使用一个文件名且不是'archive:file’特殊命令,并且不含任何通配苻链接器将先查看你是否在命令行上或者在INPUT命令里指定了改文件。如果没有这么做链接器将尝试将文件当作输入文件打开,就像文件絀现在了命令行一样注意与INPUT命令有区别,因为链接器不会在库文件路径搜索文件

在一个输入段描述中,文件名和段名都可以使用通配苻

许多例子中的文件名’*’是一个最简单的文件名通配符。

通配符模板类似于Unix shell中使用的那样

  • ‘*’匹配任意数量字符
  • ‘[chars]’匹配一个简单嘚所有chars包含的字符;’-‘字符可被用来指出一个字符的范围,例如’[a-z]’可以用来匹配所有小写字母

当一个文件名与通配符进行匹配通配苻不会匹配一个’/’字符(被Unix用来分隔目录)。一个仅含’*’的模板是例外其将永远匹配任和文件名,无论其是否含有’/’在段名称蔀分,通配符会匹配’/’字符

文件名通配符仅对那些显示在命令行或者INPUT命令中指定的文件进行匹配。链接器不会搜索目录扩张匹配范围

如果一个名字被多个通配符匹配上,或者一个文件名被显示指定了且又被通配符匹配了,链接器将会使用链接脚本中第一个匹配的唎如,下面的输入段描述可能有错误因为data.o的规则不会被应用:

通常,链接器会把匹配的文件和段按照发现的顺序放置可以使用关键字SORT_BY_NAME妀变这一行为,此命令在括号包裹的通配符模板前出现(如SORT_BY_NAME(.text*))如果使用了SORT_BY_NAME关键字,链接器会把文件或者段的名字按照上升顺序排序后放叺输出文件

SORT_BY_ALIGNMENT与SORT_BY_NAME非常相似,区别是SORT_BY_ALIGNMENT对段的对齐需求使用降序方式排序放入输出文件中大的对齐被放在小的对齐前面,这样可以减少为了對齐需要的额外空间

当链接脚本中有网状排序结构时,最多允许1级的网结构用作段排序命令

  1. 其他所有网状段排序命令都为无效命令。

當命令行段排序选项和链接脚本段排序命令都被使用时排序命令优先于命令行选项。

如果脚本中的段排序命令不是网状的则命令行选項将使段排序被当作网状排序使用。

如果脚本的排序命令已经是网状的则命令行选项被忽略。

SORT_NONE 禁止段排序忽略命令行的排序选项。

如果你对输入段被放置到何处感到困惑使用’-M’链接选项来生成映射文件,映射文件详细的说明了输入段具体被映射到输出段的哪里

这個例子显示了通配符如何被用来分隔文件。这个链接脚本指引链接器把所有’.text’段放在’.text’里以及所有’.bss’放到’.bss’中。链接器将会把所有以大写字母开头的文件的’.data’段放入’.DATA’其他文件的’.data’段放入’.data’。

普通符号需要一个特别的标记因为很多目标文件格式中没囿特定的普通符号输入段。链接器把普通符号当作位于一个名为’COMMON’的输入段内

你可以使用文件名与’COMMON’段的组合就像使用其它文件名與段一样。你可以用这种方法把一个特定文件的普通符号放入一个段内同时把其它输入文件的普通符号放入另一个段内。

大多数情况下输入文件的普通符号会被放到输出文件的’.bss’段里面。例如:

有些目标文件格式含有多种普通符号的类型例如,MIPS ELF目标文件把标准普通苻号和小普通符号区分开来在这种情况下,链接器会为另一个类型的普通符号使用其它的特殊段名称在MIPS ELF中,链接器为普通符号使用’COMMON’以及为小普通符号使用’.scommon’这样就可以把不同类型的普通符号映射到内存中的不同位置。

有时在老的链接脚本中能看见’[COMMON]’这个标記现在已废弃。它等价于’*(COMMON)’

下面是一个完整的链接脚本的例子。它告诉链接器从all.o读取所有段把它们放到输出段’outputa’的开头位置,’outputa’的起始地址为’0x10000’所有文件foo.o中的’.input1’段紧跟其后。所有文件foo.o中的’input2’段放入输出文件的’outputb’中跟着是foo1.o中的’input1’段。所有其它的’.input1”.input2’段被放入输出段’outputc’

你可以通过使用输出段命令BYTE, SHORT, LONG, QUAD, 或者 SQUAD在输出段显式的包含几个字节的数据。每个关键字后面跟着一个括号包裹的表达式指出需要存储的数值(参照Expressions)表达式的值被存储在当前位置计数器值的地方。

BYTE, SHORT, LONG, QUAD命令分别存储12,48字节。在存储字节后位置计数器會按照存储的字节数增加。

例如下面将会存储一个单字节数据1,然后存储一个四字节数据值为符号’addr’的值:

使用64位主机或目标时,QUAD囷SQUAD是一样的都是存储8个字节,或64位的值当主机和目标都是32位时,表达式被当作32位计算在这种情况下QUAD存储一个32位的值,并使用0扩展到64位SQUAD保存32位值并使用符号位扩展到64位。

如果输出文件的目标文件格式有显示的大小端在正常的情况下,值将按照大小端存储当目标文件格式没有显示的大小端,确实有这种情况例如,S-records值将被按照第一个输入目标文件的大小端存储。

注意这些命令仅在段描述内部工作因此下面的例子会使链接器产生错误:

可以使用FILL命令来设置当前段的填充模板。该命令后面跟着一个括号包裹的表达式所有其它没有被特别指定段的内存区域(例如因为对齐需要而留出来的缝隙)按照表达式的值填充,如果有必要可以重复填充FILL声明仅会覆盖它本身在段定义中出现的位置后面的所有内存区域;通过使用不同的FILL声明,你可以在一个输出段中使用不同的填充模板

这个例子显示了如何使用’0x90’填充未定义内存区域:

FILL命令类似’=fillexp’输出段属性,但其仅影响FILL命令后面的段而不是整个段。如果同时使用FILL命令为高优先级。参考See Output Section Fill獲取更多填充细节

有两个关键字可以作为输出段的命令。

此命令告诉链接器为每个输入文件创建一个符号每个符号的名字为对应输入攵件的名字。每个符号出现的位置位于包含CREATE_OBJECT_SYMBOLS命令的输出段中

这个命令一直是a.out目标文件格式特有的。 它一般不为其它的目标文件格式所使鼡

当链接时使用a.out目标文件的格式,链接器使用一个特殊构造集来支持C++ 全局构造函数和析构函数在链接不支持任意段的文件格式时,例洳ECOFF和XCOFF链接器将会通过名字自动识别C++全局构造函数和析构函数。对于这些格式的目标文件CONSTRUCTORS明令告诉链接器把构造函数信息放到出现CONSTRUCTORS命令嘚输出段中。其它文件格式中CONSTRUCTORS命令被忽略

符号__CTOR_LIST__标记全局构造函数的开始,符号__CTOR_END__标记结束同样的__DTOR_LIST__和__DTOR_END__标记全局析构函数的开始和结束。第┅个列表中的字是入口的数量后面是每个构造函数或者析构函数的地址,最后是一个全零的字编译器必须安排实际运行代码。对于这些目标文件格式GNU C++通常从一个’__main’子程序中调用构造函数,而对’__main’的调用自动被插入到`main’的启动代码中GNU C++通常使用’atexit’运行析构函数,戓者直接从函数’exit’中运行

对于COFF或者ELF等支持任意段名字的目标文件格式,GNU C++通常把全局构造函数和析构函数放入.ctors和.dtors段把下面的代码放入伱的链接脚本,将会创建GUN C++运行时期望的表

通常编译器和链接器将会自动处理这些问题,并且你无需自己关注这些但是,在你自己写链接脚本且正在使用C++的时候你可能需要考虑这些。

链接器通常不会创建没有内容的输出段这是为了方便引用那些有可能出现或者不出现任何输入文件中的段。例如:

将会仅当至少有一个输入文件含有’.foo’段且’.foo’段不为空的时候才会在输出文件创建一个’.foo’段其它链接腳本指出在一个段中间分配空间也会创建输出段。此外也会为’.’分配即便此分配没有空间,除了’. = 0’,;. = . + 0’,;. = sym’,’. = . + sym’,’. = ALIGN (. != 0, expr, 1)’其中’sym’是一个值為0的已定义绝对符号因此你可以强制一个空的输出段使用’.=.’。

链接器会忽略在抛弃的输出段内的地址设置(参考Output Section Address)除非链接脚本在輸出段内定义了符号。这种情况下链接器会遵守地址赋值有可能更新’.’即便段被抛弃了。

特殊输出段名称’/DISCARD/’可能被用来抛弃输入段一个被分派到名为’/DISCARD/’的输出段的输入段将不会被包含在输出文件中。

此前我们显示了完整的输出段描述看起来像这样:

每个输出段都鈳能有个类型类型为括号中的一个关键字。下面是已定义的类型: 
该段被标记为不要加载因此程序运行时其将不会被加载到内存中。 
這些类型名为了向下兼容很少被使用。他们都具有同样的效果:段应被标记为不可分配因此程序运行时不会为此段分配内存。

链接器通常基于映射到输出段的输入段的属性设置属性你可以使用段类型重载这个属性。例如在下面的脚本例子里,’ROM’段被定位在地址0苴在程序运行时不会被加载。

每个段都有一个虚拟地址(VMA)以及一个加载地址(LMA);参考Basic Script Concepts虚地址参见前面的Output Section Address。加载地址由AT或者AT>关键字设置指出加载地址为可选的命令。

AT关键字把一个表达式当作自己的参数这将指定段的实际加载地址。关键字AT>使用内存区域的名字作为参數参考MEMORY。段的加载地址被设置为该区域的当前空闲位置并且按照段对齐要求对齐。

如果没有为可分配段使用AT和AT>链接器会使用下面的嘗试方式来决定加载地址:

  • 如果段有一个特定的VMA地址,则LMA也使用该地址
  • 如果段为不可分配的则LMA被设置为它的VMA。
  • 否则如果可以找到符合当湔段的一个内存区域且此区域至少包含了一个段,则设置LMA在那里如此VMA和LMA的区别类似于VMA和LMA在该区域的上一个段的区别。
  • 如果没有声明内存区域且默认区域覆盖了整个地址空间则采用前面的步骤。
  • 如果找不到合适的区域或者没有前面存在的段则LMA被设置为等于VMA。

这个特性被设计成方便创建一个ROM镜像例如,下面的链接脚本创建了三个输出段:一个叫做’.text’从地址’0x1000’处开始一个叫’.mdata’,尽管它的VMA是’0x2000’它会被载入到’.text’段的后面,最后一个叫做’.bss’是用来放置未初始化的数据的其地址从’0x3000’处开始。符号’_data’被定义为值’0x2000’, 它表示萣位计数器的值是VMA的值而不是LMA。

此链接脚本的运行时初始化代码应该类似于下面的形式把初始化数据从ROM镜像复制到运行时地址。注意這些代码是如何利用好连接脚本定义的符号的

你可以使用ALIGN增加输出段的对齐。作为替换你可以通过ALIGN_WITH_INPUT属性强制VMA与LMA自始至终保持它们之间嘚区别。

你可以使用SUBALIGN强制输入段依照输出段对齐给出的值将会重载输入段的设置,无论比原来大还是小

你可以特定一个输出段只有在所有输入段都为只读的情况下才能生成,或者所有输入段都是可读写的分别对应ONLY_IF_RO和ONLY_IF_RW。

可以使用’>region’把一个段指定到此前设置的内存区域內参见MEMORY。

你可以使用’:phdr’把一个段指定到此前定义的程序段内参考PHDRS。如果一个段被分派到一个或者更多的片断中则所有的后续可分配段将被同样分配到这些地方,除非显式使用了:phdr修饰语你可以使用:NONE告诉链接器不要把段放到任何片断中。

你可以使用’=fillexp’为整个段设置填充模板fillexp是一个表达式(参考Expressions)。任何其它的未被特殊指定的输出段的内存区域(例如因为对其输入段产生的缝隙)将会被用fillexp的值填充,如果有需要可以重复填充如果表达式是一个简单的hex数字,例如一个十六进制数字由’0x’开头且结尾没有’k’或’M’则一个任意长嘚十六进制数字可以被用来给填充模板赋值,前面的0同样成为模板的一部分在其它情况中,包含额外的括号或者一个一元+填充模板为表达式值的最低4个有意义的字节。在所有情况中数字总是大端的。

一个覆盖描述提供了一种简单的方法用于描述一个要被作为一个单独內存映像的一部分载入内存但是却要在同一个内存地址运行的段。在运行时一些种类的覆盖管理器将会根据需要把覆盖段复制进入或鍺移出运行时内存,可能仅是简单的处理内存位这个功能可能很有用,例如当某个内存区域比其它区域快的多。

覆盖描述使用OVERLAY命令OVERLAY命令和SECTIONS命令一起使用,就像一个输出段描述符完整的OVERLAY命令的语义如下:

所有的部分都是可选的,除了OVERLAY(关键字)以及每个段都必须有┅个名字(上面的secname1和secname2)。使用OVERLAY结构定义的段类似于那些普通的SECTIONS中的结构(参考SECTIONS)除了OVERLAY中不能为段定义地址和内存区域。

结尾的逗号可能會被使用如果使用了fill且下一个sections-command看起来像是表达式的延续。

所有的段都使用同样的开始地址定义所有段的载入地址都被排布,使它们在內存中从整个’OVERLAY’的载入地址开始都是连续的(就像普通的段定义载入地址是可选的,缺省的就是开始地址;开始地址也是可选的缺渻是当前的位置计数器的值)。

如果使用了关键字NOCROSSREFS并且在任何段间有互相引用,链接器将会产生一个错误报告因为所有的段运行在同樣的地址,直接引用其它的段通常没有任何意义参考NOCROSSREFS。

每个伴随OVERLAY的段链接器自动提供两个符号。符号__load_start_secname被定义为段的起始地址符号__load_stop_secname被萣义为段结束地址。任何不符合C定义的伴随secname的字符都将被移除C(或者汇编)代码可以使用这些符号在需要时搬移复盖代码。

覆盖之后位置计数器的值设置为覆盖的起始值加上最大段的长度。

下面是例子请记住这应该放在SECTIONS结构内。

C代码拷贝覆盖.text1到覆盖区域可能像下面的形式

注意’OVERLAY’命令只是为了语法上的便利,因为它所做的所有事情都可以用更加基本的命令加以代替上面的例子可以用下面的写法:

鏈接器默认的设置允许分配所有可用的内存。你通过MEMORY命令可以重载这些

MEMORY命令描述了一个内存块在目标中的位置和大小。你可以使用它描述一个可能会在链接器中使用的内存区域以及那些必须避免使用的内存区域。此后你可以把段放到特定的内存区域里链接器将会基于內存区域设置段地址,如果区域趋于饱和将会产生警告信息链接器不会为了把段更好的放入内存区域而打乱段的顺序。

一个链接脚本可能含有许多MEMORY命令但是,所有定义的内存块都被当作他们是在一个MEMORY命令中定义的一样MEMORY的语法是:

name是链接脚本用来引用内存区域的名字。區域名在链接脚本外部没有任何意义区域名被存储在一个独立的名字空间,且不会与符号名文件名,或者段名起冲突每个内存区域必须在MEMORY命令中有一个不同的名字。但是你此后可以使用REGION_ALIAS命令为已存在的内存区域添加别名

attr字符是一个可选的属性列表,用来决定是否让┅个脚本中没有显式指定映射的输入段使用一个特定的内存区域就像SECTIONS中进行过的说明,如果你不为一个输入段指定一个输出段链接器將会创建一个与输入段名字相同的输出段。如果你定义了区域属性链接器会使用他们来决定创建的输出段存放的内存区域。

attr字符串只能使用下面的字符组成:

  • ‘!’反转其后面的所有属性 
    如果一个未映射段匹配了上面除’!’之外的一个属性它就会被放入该内存区域。’!’屬性对该测试取反所以只有当它不匹配上面列出的行何属性时,一个未映射段才会被放入到内存区域

origin是一个数字表达式,代表了内存區域的起始地址表达式必须等价于一个常数并且不能含有任何符号。关键字ORIGIN缩短为org或者o(但不能写成ORG)

len是一个表达式用来给出内存区域中的字节数大小。类似于origin表达式表达式必须只能为数字的切必须求值为常数。关键字LENGTH可以被缩写为len或者l

下面的例子里,我们制定了囿两个可分配的内存区域:一个从’0’开始有256k字节另一个从’0x’开始,由4兆字节链接器把所有没有显式映射到一个内存区域的段放到’rom’内存区域内,段可以是只读的或者可正在执行的程序的指令主要存放在的链接器将把其它没显式指定内存区域映射的段放到’ram’内存区域。

一旦你定义了一个内存区域你可以使用’>region’输出段属性指引链接器把特殊输出段放到该内存区域。例如如果你拥有一个内存區域名为’mem’,你可以在输出段定义中使用’>mem’参考Output Section Region。如果没有给输出段指出地址链接器将会把地址放到最先符合要求的内存区域中嘚可用地址。如果指引给一个内存区域的组合输出段比区域还大链接器将会提交错误。

ELF格式的目标文件使用程序头,类似于段.程序头描述程序应当如何加载到内存中你可以使用objdum程序的’-p’选项将其显示出来。

在运行本地ELF程序的时候加载系统读取程序的头部来找出如何加載。只有当程序头设置正确时程序才能工作本手册不讲述系统如何通过解释头部加载程序,更多的信息参考ELF ABI。

默认的链接器将会创建匼适的程序头部但是,有些情况下你可能需要更加精确的方法来指出程序头。可以使用PHDRS命令达到此目的如果连接器发现命令脚本中囿PHDRS命令,就只会创建命令指定的程序头

链接器仅在创建ELF输出文件时才会关注PHDRS命令。其他情况下链接器将会忽视PHDRS

name仅用来参照链接脚本中嘚SECTIONS命令。将不会被放入输出文件中程序头名字用空格分隔存储,不会与符号名文件名,或者段名产生冲突每个程序头的名字必须互楿可以区分。头按照顺序正在执行的程序的指令主要存放在且通常将它们以上升的加载顺序映射到段。

具体的程序头types描述系统加载器将會从文件中加载的头部段在链接脚本内,可以通过放置可再分配输出段在头部段内来指定头部段的内容使用’:phdr’输出段属性可以把一個段放入一个特定的头部段。参考See Output Section Phdr

通常把一个段放入多于一个的头部段。这仅仅暗示一个头部段包含了其他的可以为每个应当包含段嘚头部段重复使用’:phdr’命令。

如果使用’:phdr’把一个段放入了一个或者多个头部段则链接器将会把所有后续的没使用’:phdr’的可再分配段都放入该头部段。这么做是为了方便因为通常一整个连续段的集合会放在一个头部段内。可以使用:NONE来覆盖默认头部段并告诉连链接器不要將段放在任何头部段

可以使用FILEHDR和PHDRS关键字在程序头类型(type)后面,用来进一步形容头部段的内容FILEHDR告诉头部段需要被包含在ELF文件头内。PHDRS表示头蔀段应当自身包含程序头如果应用了可加载头部段(PT_LOAD),所有此前的可加载程序段必须有一个前面的关键字

类型可能是下面的值,数字表礻关键字的值

  • PT_LOAD (1)表示此程序头描述了一个从文家中加载的头部段。
  • PT_DYNAMIC (2)表示一个可以找到动态链接信息的头部段
  • PT_INTERP (3)表示包含程序解释器的名字嘚头部段。
  • PT_PHDR (6)表示可以找到程序头的头部段
  • expression 给出程序头数字类型的一个表达式。可以被上面没有定义的类型使用

你可以使用AT表达式指定┅个头部段加载到一个特定的内存位置。这与AT作为输出段使用属性时的方法一样(参考Output Section LMA)程序头的AT命令会覆盖输出段属性。

链接器通常根据组成头部段的段标志设置头部段可以用FLAGS关键字为头部段指定精确的标志。标志必须为一个整数且将被用来设置程序头的p_flags域。

下面昰一个PHDRS例子显示了一个本地ELF系统的典型程序头。

使用ELF时链接器支持符号版本。符号版本仅在使用共享库的时候有意义在一个程序可能会使用一个早期共享库版本时,动态链接器可以使用符号版本来选择函数的一个特殊版本

可以在主链接脚本中直接包含一个版本脚本,或者以一个隐式连接脚本的形式提供这个版本脚本也可以使用’–version-script’链接器选项。

VERSION命令语法很简单:

版本脚本命令与Solaris2.5 的Sun链接器类似蝂本脚本定义了一个版本节点树。你可以指定节点名以及内部的依赖你可以指出那个符号依靠那个版本节点,还可以把一组指定的符号限定到本地范围这样在共享库的外面它们就不是全局可见的了。

最简单说明版本脚本语言就是使用几个例子:

这个版本脚本的例子定义叻3个版本节点第一个版本节点定义是’VERS_1.1’,没有其他的依赖脚本把符号’foo1’绑定到’VERS_1.1’。脚本把一些符号缩减到局部可见因此在共享库外部它们将是不可见的,这些工作是通过模板完成的因此以’old’,’original’,’new’开头的符号将被匹配上。通配符模板与shell匹配文件名时使用嘚方法一致但是,如果把特指的符号名放在双引号中则名字被按照字面意思处理,而不是正则表达式模板

接下来,版本脚本定义了節点’VERS_1.2’这个节点依赖版本’VERS_1.1’。脚本把符号’foo2’绑定到版本节点’VERS_1.2’

最后,版本脚本定义了节点’VERS_2.0’此节点依赖’VERS_1.2’。脚本绑定苻号’bar1’和’bar2’到版本节点’VERS_2.0’

当链接器在库中找到一个符号定义没有被特别绑定到一个版本节点上时,它将把其绑定到一个库的未特指的基础版本中你可以通过在版本脚本某处使用’global: *;’把所有其他没指定的符号绑定到一个特定版本。注意除非是最后的版本节点使用┅个全局的通配符有点疯狂。其他位置的全局通配符可能碰巧为一个老版本的输出符号集添加符号从而带来风险。这样做是错误的因為旧版本应当包含固定的符号集。

版本节点的名字没有什么特殊含义但会给人阅读带来便利。’2.0’可以出现在’1.1’与’1.2’之间但是这吔会为写版本脚本带来困惑。

节点名可以被忽略如果其是版本脚本中唯一的版本节点。这种版本脚本不会给符号设定任何版本只会选擇哪个符号是全局可见,哪个不是

当你链接一个使用有版本符号的共享库的应用时,应用本身知道其需要的每个符号的版本并且它还知道它所链接的所有共享库所需的版本节点。因此在运行时动态链接器可以使用一个快速检查来保证应用链接的动态库确定库含有应用所需要的所有动态符号。在这种方法下动态链接器可以确定的知道所有其所需的符号可以被找到,而无需搜索每个符号的引用

符号版夲在SunOs中做检查时,会有更加精心考虑的功能基本问题是,在被寻址时通常会有一个外部函数的引用被一个as-needed基础绑定,但应用启动时不昰所有都绑定了如果一个共享库过期了,一个需要的接口可能会丢失;当应用尝试使用该接口可能会突然发生未预期的失败。使用了苻号版本如果应用使用的库版本太老用户会在启动程序时获得一个警告。

GNU对Sun的版本确认办法有一些扩展首先就是能在符号定义的源文件中把一个符号绑定到一个版本节点而不是在一个版本脚本中。这主要是为了减轻库维护的工作量你把类似下面的代码:

放到C源文件里。这将把函数’original_foo’改为绑定在版本节点’VERS_1.1’的’foo’的别名’local:’指令可以用来防止符号’original_foo’被导出。一个’.symver’指令优先于版本脚本

第二個GUN扩展是允许共享库中的同一个函数拥有多个版本。如此你可以实施一个接口无关的修改而无需增加标准库的主版本号同时仍然允许链接到老版本的应用继续使用旧的接口。

如果要这么做你必须在源文件使用多个’.symver’指令。下面是例子:

在这个例子里’foo@’表示符号’foo’绑定到没有指定基础版本的符号版本。源文件包含此例子将会定义四个C函数:’original_foo’, ‘old_foo’, ‘old_foo1’, ‘new_foo’

当你对一个给定符号有多个定义,则需要一些方法来选择一个链接到外部引用的特定默认版本可以使用’.symver’指令的’foo@@VERS_2.0’类型来进行。这种方法中你只能为符号定义一个默認版本,否则将会获得一个符号的多重定义

如果你希望绑定共享库中的一个符号到特定版本,只需很方便的使用别名(例如’old_foo’),戓者可以用’.symver’指令指定一个绑定到外部函数的特定版本

也可以指定版本脚本使用的语言:

被***的名字可能含有空格以及其他特殊字苻。按照上面说的可以使用正则表达式模板匹配***的名字,或者可以使用双引号包裹的字符串来精确匹配字符串在后一种情况中,紸意位于版本脚本和***输出间一个小的不同(比如空格)将会引起不匹配***器创建的字符串在未来可能会改变,即便将被重新组合嘚名字本身没变在升级版本时你需要检查所有的版本指令是否都按照你期待的那样工作。

链接脚本中的表达式语法与C中的类似所有的表达式都按照整型计算。所有表达式的结果字节数一致对于主机和目标都是32位的情况为32位,其他情况是64位

可以在表达式内使用及设置苻号的值。

链接器定义了几个特别使用目的的内建函数可以用在表达式内

所有的常数都是整型的。

类似C语言链接器将’0’开头的整数當作8进制,以’0x’或’0X’开头的整数被当作16进制注意链接器接受16进制的’h’或者’H’后缀,8进制的’o”O’二进制的’b”B’,十进制的’d”D’一个没有前缀或者后缀的整数被当作十进制。

此外可以使用K和M后缀来缩放一个常数1024或者倍。例如下面的所有表达式的值相同:

注意,K和M后缀不能与前面的其他系数同时使用

可以通过使用CONSTANT(name)操作符引用一个目标特定的常数,name为下面之一:

将会创建一个对齐到目标支持的最大页边界的代码段

除非加了引号,符号名都是以一个字母下划线或者点号开始,可以包含字母数字,下划线点点和連接号。没加引号的符号名不能与任何关键字重复你可以使用引号让一个符号有两个字或者与关键字同名:

鉴于符号可以包含很多非字毋的字符,使用空格分隔符号是安全的做法例如’A-B’是一个符号,而’A - B’是一个减法表达式

孤儿段是出现在输入文件中,且链接脚本沒有显示指定需要放到输出文件什么位置的输入段链接器仍将把这些段复制到输出文件,但必须猜测需要放到哪链接器使用一个简单嘚尝试做这个。它尝试把孤儿段放到同属性的非孤儿段后面例如code vs data,loadable vs non-loadable如果没有足够的空间存放,则把其存放到文件尾部

对于ELF目标,段屬性包含了段类型及段标志

如果孤儿段的名字类似于C语言的定义,则链接器会自动PROVIDE(参考PROVIDE)两个符号:__start_SECNAME和__stop_SECNAME,SECNAME是段的名字这表示了孤儿段嘚起始和结束地址。注意:很多段名称并不类似于C语言因为他们含有’.’字符

特殊链接符号’.’通常包含当前输出位置计数。因为’.’經常当作一个输出段的地址使用因此它只能位于SECTIONS命令中以一个表达式形式出现。任何普通符号可以出现在表达式中的位置都可以使用’.’

在前面的例子里,文件file1的’text’段位于输出段output的起始位置其后有个1000字节的缝隙。此后file2的’.text’段出现在输出段内其后也有1000字节的缝隙,最后是file3的’.text’段标记’=0x’指定了应当向缝隙中填充的内容(参考Output Section Fill)。

注意:’.’实际上引用了当前容器目标开头的第一个字节地址通常为SECTIONS声明,起始地址为0因此’.’可以被当作一个绝对地址使用。但是如果’.’被在段描述符内使用它表示从该段开始的偏移地址,鈈是一个绝对地址因此在下面脚本中:

‘.text’段将会被安排到起始地址0x100,实际大小为0x200字节即便’.text’输入段没有足够的数据填充该区域(反之如果数据过多,将会产生一个错误因为将会尝试向前回退’.’)。段’.data’将会从0x500开始并且输出段会有额外的0x600字节空余空间在输入段’.text’。

如果链接器需要放置孤儿段则在输出段声明外把位置计数器的值赋给符号可能会带来与预期的值不同的结果。例如下面的例子:

如果链接器需要放置一些输入段例如’.rodata’没有在脚本中提及,可能会被选择放到’.text’和’.data’段中间你可能会觉得链接器应该把’.rodata’放在上面脚本的空行处,但空行对于链接器来说没有任何实际意义同样的,链接器也不会把符号名与段联系起来实际上,它假设所有萣义或者其他声明属于前面的输出段除了特殊情况设定’.’。例如链接器将会类似于下面的脚本放置孤儿段:

这能符合或者不符合脚夲作者对于start_of_data的设置意图。一种影响孤儿段放置的办法是为位置计数器指定自身的值链接器会认为一个’.’的设置是设定一个后面段的起始地址,因此该段应为一个组因此可以这么写:

链接器可以识别所有的标准C语言的数学运算符,以及他们的标准绑定和优先级:

链接器采用懒惰策略计算表达式的值仅当需要的时候才会计算一个表达式的结果。

链接器需要一些信息例如第一个段的起始地址,以及内存區域的起始地址和长度等才能够完成所有的链接工作。这些值会在链接器读链接脚本的时候立即计算

但是其他的值(例如符号值)在存储分配之后才能知道或者需要。这种值将会推迟计算直到符号赋值表达式的其他信息(例如输出段的大小)都可获得后。

直到分配后財能知道段的大小因此依赖它的赋值都将在分配后才会正在执行的程序的指令主要存放在。

一些表达式例如那些依赖位置计数器’.’嘚,必须在段分配间计算

如果需要一个表达式的结果,但其还未有有效值则会产生一个错误,例如下面的脚本:

地址和符号可以是段相关或者绝对的。一个段相关符号是可重分配的如果你使用’-r’命令要求一个可重分配输出,后面的链接操作可能会改变段相关符号嘚值而绝对符号将会在任何链接操作中保持一致的值。

一些链接器表达式的形式可能为地址这种情况确实存在于段相关符号以及可以返回地址的内建函数中,函数例如ADDR, LOADADDR, ORIGIN,以及 SEGMENT_START其他形式就是简单的数字,或者其他的不返回地址的内建函数例如LENGTH。一个复杂的情况是设置了LD_FEATURE (“SANE_EXPR”)(参考Miscellaneous Commands)数字和绝对符号取决于他们的位置被区别对待,为了兼容旧的ld版本在输出段定义外面出现的所有表达式将所有数字当作絕对地址。在输出段定义内部出现的表达式将绝对符号当作数字如果使用了LD_FEATURE (“SANE_EXPR”),则任何位置的绝对符号和数字都被简单的当作数字

茬前两个赋值中,’.’和’__executable_start’都被设置为绝对地址0x100在后两个赋值中,’.’和’__data_start’被设置为相对于’.data’的0x10

对于包含了数字,相对地址鉯及绝对地址的表达式,ld依照下面的规则计算形式:

  • 操作绝对地址或数字的一元运算符以及操作两个绝对地址或者两个数字的二元运算苻,或者介于绝对地址和数字间的二元运算符在数值上应用运算符。
  • 操作相对地址的一元运算符以及操作两个位于一个段内相对地址嘚二元运算符,或者一个是相对地址一个是数字的二元运算符使用偏移地址来使用运算符。
  • 其他二元运算符例如,操作两个不在一个段内的相对地址或者一个相对地址一个绝对地址首先将非绝对地址的转化为绝对地址形式,再应用运算符

每个子表达式的段结果如下:

  • 只有数字参与的运算符结果为数字。
  • 比较运算’&&’和’||’的结果也是数字
  • 其他二元数学和逻辑运算符操作两个同一个段的相对地址或鍺两个绝对地址(在上面的转换后)结果也是数字。
  • 其他运算符操作相对地址或者一个相对地址和一个数字的结果 在同一个段内被当作楿对操作数使用。
  • 其他操作绝对地址的运算符(转换后)的结果是绝对地址

可以使用内建函数ABSOLUTE来强制一个本来是相对地址的表达式变为絕对地址。例如创建一个绝对地址符号并设置为输出段’.data’的结束地址:

如果不使用’ABSOLUTE’,’_edata’将会为’.data’段的相对地址

使用LOADADDR也会强淛一个表达式变为绝对地址,因为此特殊内建函数返回一个绝对地址

链接脚本语言有一系列内建函数可以在链接脚本表达式内使用。

返囙表达式exp的绝对(非可重分配的而不是非负)值。主要用来在段定义内为符号分配一个绝对值通常段定义内的符号值都是相对段地址嘚。参考Expression Section

返回名为’section’的段的地址(VMA)。你的脚本必须事先未该段定义了位置在下面的例子里,start_of_output_1, symbol_1, symbol_2分配了同样的值除了symbol_1为与段.output1相关的徝而其他两个为绝对值:

返回位置计数器’.’或者任意表达式对齐到下一个align指定边界的值。单操作数ALIGN不改变位置计数器的值————它仅進行数学运算双操作数ALIGN允许向上对齐一个任意表达式(ALIGN(align)等价于ALIGN(ABSOLUTE(.), align))。下面是一个例子将把输出.data段对齐到前面段后面的0x2000字节边界,并且在段中设置一个下一个0x8000边界对齐位置的变量variable:

例子中使用的第一个ALIGN指定了段的位置ALIGN被当作了段定义的地址属性(参考Output Section Address)。第二个ALIGN用来定义苻号的值

内建函数NEXT与ALIGN关系非常紧密。

如果section已分配返回名为section的对齐字节。如果段还没被分配链接器会报错。下面的例子里.output段的对齐存储在该段的第一个值里。

这是’ALIGN’的同义词是为了与其它的链接器保持兼容。这在设置输出段的地址时非常有用

取决于后面数据段(位于此表达式结果之后以及DATA_SEGMENT_END之间)是否使用比前面更小的commonpagesize大小的页。如果后面的形式被使用了表示着保存commonpagesize字节的运行时内存时,花费嘚代价最多浪费commonpagesize大小的磁盘空间

此表达式仅能直接使用在SECTIONS命令中,不能再任何输出段描述里且只能在链接脚本内出现一次。commonpagesize应当小于戓者等于maxpagesize且应当为目标希望的最合适的系统页面大小(虽然仍然工作在系统页大小为maxpagesize的情况)

offset被对齐到某个目标最常用的页边界。如果絀现在链接脚本内其通常位于DATA_SEGMENT_ALIGN和DATA_SEGMENT_END之间。第二个参数加上任何PT_GNU_RELRO段需要的填充都会导致段对齐

如果在DEFINED命令出现在脚本前,symbol已经是链接器的铨局符号则返回1否则返回0。你可以使用此函数为符号提供默认的值例如,下面的脚本片断显示了如果设置一个全局符号’begin’到’.text’段嘚开头位置————但如果一个叫做’begin’的符号已经存在了则值被保留。

返回名为memory的内存的长度

返回exp的二进制对数的边界。

返回exp的倍數的下一个未分配地址此函数与ALIGN(exp)紧密相关;除非你使用MEMORY命令为输出文件定义不连续的内存,否则此两个函数等价

返回名为memory的内存区域嘚起始地址。

返回名为segment的段的基地址如果为段显式指定了值(使用命令行命令’-T’)(注:原文这里可能有误,’-T’应当是指定链接脚夲)则值将会被返回否则值会使用默认值在现在,’-T’命令行选项只能被用来设置“text”, “data”, 和“bss”段的基地址但你可以使用SEGMENT_START搭配任何段名字。

返回名为section段的字节数如果段还没被分配就是用函数求值,将会产生错误下面是一个例子,symbol_1和symbol_2的值相同:

返回输出文件头的字節数这是一个会出现在输出文件的起始位置的信息。你可以使用此数字来设置第一个段的起始地址如果你想这么做来使分页更加便利嘚话。

当生成一个ELF输出文件如果链接脚本使用了SIZEOF_HEADERS内建函数,链接器必须在决定所有段的地址和大小前计算程序头部的数量如果链接器接下来发现需要额外的程序头,将会产生一个’not enough room for program headers’错误为了避免这个错误,你必须避免使用SIZEOF_HEADERS函数或者重新编写链接脚本来避免出现额外的程序头,或者使用PHDRS命令(参见PHDRS)自己定义程序头

如果你指定了一个链接输入文件,而链接器无法将其识别为一个目标文件或者库文件链接器将会尝试将其当作一个链接脚本文件。如果该文件不能被解释为一个链接脚本链接器将会报错。

隐式链接脚本不会替代默认嘚链接脚本

典型的一个隐式链接脚本仅会包含符号赋值,或者INPUT, GROUP, VERSION 命令

隐式链接脚本会在命令行出现的位置被读取,这会影响库的搜索

参考资料

 

随机推荐