本书主要介绍与计算机系统相关的核心概念,解释这些概念如何相互关联并终影响程序执行的结果和性能。本书共分8章,主要内容包括数据的表示和运算、程序的转换及机器级表示、程序的链接、程序的执行、存储器层次结构、虚拟存储器、异常控制流和I/O操作的实现等。本书将计算机系统每个抽象层涉及的重要概念通过程序的开发和运行串联起来,内容详尽,反映现实,概念清楚,通俗易懂,实例丰富,并提供大量典型习题以供读者练习。本书可以作为计算机专业本科或大专院校学生计算机系统方面的基础性教材,也可以作为有关专业研究生或计算机技术人员的参考书。
PREFACE前 言后PC时代的到来,使得原先基于PC而建立起来的专业教学内容已经远远不能反映现代社会对计算机专业人才的培养要求,原先计算机专业人才培养强调“程序”设计也变为更强调“系统”设计。这需要我们重新规划教学课程体系,调整教学理念和教学内容,加强学生系统能力培养,使学生能够深刻理解计算机系统整体概念,更好地掌握软/硬件协同设计和程序设计技术,从而更多地培养出满足业界需求的各类计算机专业人才。不管培养计算机系统哪个层面的计算机技术人才,计算机专业教育都要重视学生“系统观”的培养。
本书的主要目的就是为加强计算机专业学生的“系统观”而提供一本关于“计算机系统基础”课程教学的教材。
1.本书的写作思路和内容组织本书从程序员视角出发,重点介绍应用程序员如何利用计算机系统相关知识来编写更有效的程序。本书以高级语言程序的开发和运行过程为主线,将该过程中每个环节所涉及的硬件和软件的基本概念关联起来,试图使读者建立一个完整的计算机系统层次结构框架,了解计算机系统的全貌和相关知识体系,初步理解计算机系统中的每一个抽象层及其相互转换关系,建立高级语言程序、ISA、OS、编译器、链接器等之间的相互关联;对指令在硬件上的执行过程和指令的底层硬件执行机制有一定的认识和理解,从而增强读者在程序的调试、性能优化、移植和健壮性保证等方面的能力,并为后续的“计算机组成与设计”“操作系统”“编译技术”“计算机体系结构”等课程打下坚实基础。
本书的具体内容包括:程序中处理的数据在机器中的表示和运算、程序中各类控制语句对应的机器级代码的结构、可执行目标代码的链接生成、可执行目标代码中的指令序列在机器上的执行过程、存储访问过程、打断程序正常执行的机制以及程序中的I/O操作功能如何通过请求操作系统内核提供的系统调用服务来完成等。
不管构建一个计算机系统的各类硬件和软件多么千差万别,计算机系统的构建原理以及在计算机系统上的程序转换和执行机理是相通的,因而,本书仅介绍一种特定计算机系统平台下的相关内容。本书所用的平台为IA-32/x86-64+Linux+GCC+C语言。
本书共有8章,分两个部分。第一部分主要是系统概要并介绍可执行目标文件的生成,包含第1~4章;第二部分主要介绍可执行目标文件的运行,包含第5~8章。第1章是计算机系统概述;第2章和第3章分别介绍高级语言程序中的数据和语句所对应的底层机器级表示,展示的是高级语言程序到机器级语言程序的对应转换关系;第4章主要介绍如何将不同的程序模块链接起来构成可执行目标文件,展示的是程序的链接环节;第5章和第6章着重介绍程序的运行环节,包括与程序运行密切相关的硬件部分——CPU及存储器的组织;第7章介绍打断程序正常运行的事件机制——异常控制流;第8章主要介绍程序中I/O操作的实现机制。此外,附录A中还补充了数字逻辑电路的基础内容,为那些没有数字逻辑电路基础知识的读者阅读本书提供方便。
2.读者所需的背景知识本书假定读者对C语言程序设计有一定的基础,已经掌握了C语言的语法和各类控制语句、数据类型及其运算、各类表达式、函数调用和C语言的标准库函数等相关知识。
此外,本书对于程序中指令的执行过程进行了介绍,这涉及布尔代数、逻辑运算电路、存储部件等内容,因而,本书正文内容假定读者具有数字逻辑电路基础知识。不过,如果读者不具备这些背景知识的话,可以参看本书附录A。
本书所用的平台为IA-32/x86-64+Linux+GCC+C语言。书中大多数C语言程序对应的机器级表示都是基于IA-32+Linux平台用GCC编译器生成的,本书会在介绍程序的机器级表示之前,先简要介绍IA-32的指令集体系结构,包括其机器语言和汇编语言的介绍,因而,读者无须任何机器语言和汇编语言的背景知识。
XII3.使用本书作为教材的课程及教学建议目前国内大学计算机专业课程设置,大多是按计算机系统层次结构进行横向切分,自下而上分解成数字逻辑电路、计算机组成原理、汇编程序设计、操作系统、编译原理、程序设计等课程,而且,每门课程都仅局限在本抽象层,相互之间几乎没有关联,因而学生对整个计算机系统的认识过程就像“瞎子摸象”一样,很难形成一个对完整计算机系统的全面认识。虽然国内有些高校也有计算机系统概论、计算机系统入门或导论之类的课程,但通常内容较广且结构较松散,基本上是计算机课程概论,因而很难使学生真正形成计算机系统层次结构整体框架。
笔者对美国几所顶级大学近年来相关课程体系进行了跟踪调查,发现他们都非常注重计算机系统能力的培养,都在讲完高层的编程语言及程序设计课程后开设一门关于计算机系统的基础课程,如MIT的6.004、UC-Berkeley的CS 61C、CMU的CS 213、斯坦福大学的CS 107等。这些课程在内容上特别注重计算机系统各抽象层的纵向关联,将高级语言程序、汇编语言程序、机器代码及其执行串联起来,为学生进一步学习后续相关课程打下坚实的基础。
本书在借鉴国外相关课程教学内容和相关教材的基础上编写,适合于在完成程序设计基础课程后进行学习。本书内容贯穿计算机系
袁春风 南京大学计算机科学与技术系教授。主要研究领域为大数据计算与并行处理技术、Web信息检索与文本挖掘技术等。在相关领域承担科研项目近40项,发表论文近70篇,两次获江苏省科技进步二等奖,并获江苏省软件一等奖。主持的“计算机组成原理”和“计算机组成与系统结构”课程被遴选为精品课程、精品资源共享课、江苏省精品课程;主编的《计算机组成与系统结构》以及《计算机组成与系统结构习题解答与教学指导》获“十二五”普通高等教育规划教材和江苏省精品教材;作为主要成员获2013年江苏省教学成果特等奖和2014年国家教学成果二等奖。“计算机系统基础(一):程序的表示、转换与链接”获国家精品在线开放课程,“计算机组成与系统结构”课程网站获江苏省多媒体课件特等奖。
CONTENTS
目 录
丛书序言
序 言
前 言
第一部分 系统概述和可执行目标文件的生成
第1章 计算机系统概述2
1.1 计算机基本工作原理2
1.1.1 冯·诺依曼结构基本思想2
1.1.2 冯·诺依曼机基本结构3
1.1.3 程序和指令的执行过程4
1.2 程序的开发与运行7
1.2.1 程序设计语言和翻译程序7
1.2.2 从源程序到可执行文件9
1.2.3 可执行文件的启动和执行10
1.3 计算机系统的层次结构12
1.3.1 计算机系统抽象层的转换12
1.3.2 计算机系统核心层之间的关联14
1.3.3 计算机系统的不同用户16
1.4 计算机系统性能评价18
1.4.1 计算机性能的定义19
1.4.2 计算机性能的测试19
1.4.3 用指令执行速度进行性能评估21
1.4.4 用基准程序进行性能评估22
1.4.5 Amdahl定律23
1.5 本书的主要内容和组织结构24
1.6 小结27
习题27
第2章 数据的机器级表示与处理30
2.1 数制和编码30
2.1.1 信息的二进制编码30
2.1.2 进位计数制32
2.1.3 定点与浮点表示36
2.1.4 定点数的编码表示36
2.2 整数的表示41
2.2.1 无符号整数和带符号整数的表示41
2.2.2 C语言中的整数及其相互转换42
2.3 浮点数的表示44
2.3.1 浮点数的表示范围44
2.3.2 浮点数的规格化45
2.3.3 IEEE 754浮点数标准45
2.3.4 C语言中的浮点数类型49
2.4 十进制数的表示51
2.4.1 用ASCII码字符表示51
2.4.2 用BCD码表示51
2.5 非数值数据的编码表示52
2.5.1 逻辑值52
2.5.2 西文字符52
2.5.3 汉字字符53
2.6 数据的宽度和存储55
2.6.1 数据的宽度和单位55
2.6.2 数据的存储和排列顺序57
2.7 数据的基本运算61
2.7.1 按位运算和逻辑运算61
2.7.2 左移运算和右移运算61
2.7.3 位扩展运算和位截断运算63
2.7.4 整数加减运算64
2.7.5 整数乘除运算68
2.7.6 常量的乘除运算71
2.7.7 浮点数运算72
2.8 小结78
习题79
第3章 程序的转换及机器级表示87
3.1 程序转换概述87
3.1.1 机器指令及汇编指令88
3.1.2 指令集体系结构89
3.1.3 生成机器代码的过程89
3.2 IA-32指令系统概述94
3.2.1 数据类型及其格式95
3.2.2 寄存器组织和寻址方式96
3.2.3 机器指令格式101
3.3 IA-32常用指令类型及其操作103
3.3.1 传送指令103
3.3.2 定点算术运算指令106
3.3.3 按位运算指令109
3.3.4 控制转移指令110
3.3.5 x87浮点处理指令115
3.3.6 MMX/SSE指令集116
3.4 C语言程序的机器级表示118
3.4.1 过程调用的机器级表示118
3.4.2 选择语句的机器级表示132
3.4.3 循环结构的机器级表示136
3.5 复杂数据类型的分配和访问139
3.5.1 数组的分配和访问139
3.5.2 结构体数据的分配和访问144
3.5.3 联合体数据的分配和访问146
3.5.4 数据的对齐148
3.6 越界访问和缓冲区溢出151
3.6.1 缓冲区溢出151
3.6.2 缓冲区溢出攻击153
3.6.3 缓冲区溢出攻击的防范155
3.7 兼容IA-32的64位系统158
3.7.1 x86-64的发展简史158
3.7.2 x86-64的基本特点159
3.7.3 x86-64的基本指令和对齐159
3.7.4 x86-64的过程调用161
3.7.5 x86-64的浮点操作与SIMD指令165
3.8 小结166
习题167
第4章 程序的链接182
4.1 编译、汇编和静态链接182
4.1.1 编译和汇编182
4.1.2 可执行目标文件的生成184
4.2 目标文件格式186
4.2.1 ELF目标文件格式186
4.2.2 可重定位目标文件格式187
4.2.3 可执行目标文件格式190
4.2.4 可执行文件的存储器映像192
4.3 符号表和符号解析193
4.3.1 符号和符号表193
4.3.2 符号解析196
4.3.3 与静态库的链接199
4.4 重定位201
4.4.1 重定位信息202
4.4.2 重定位过程202
4.5 动态链接206
4.5.1 动态链接的特性207
4.5.2 程序加载时的动态链接207
4.5.3 程序运行时的动态链接209
4.5.4 位置无关代码210
4.6 小结214
习题215
第二部分 可执行目标文件的运行
第5章 程序的执行222
5.1 程序执行概述222
5.1.1 程序及指令的执行过程222
5.1.2 CPU的基本功能和组成224
5.1.3 打断程序正常执行的事件226
5.2 数据通路基本结构和工作原理227
5.2.1 数据通路基本结构227
5.2.2 数据通路的时序控制229
5.2.3 总线式数据通路230
5.2.4 单周期数据通路235
5.3 流水线方式下指令的执行238
5.3.1