程序员的自我修养--完整PDF版

所需积分/C币:13 2014-06-19 15:18:09 89.99MB PDF
收藏 收藏 1
举报

程序员的自我修养—链接、装载与库].俞甲子.扫描版.pdf
温故而知新 1.1从 Hello world说起 1.2万变不离其宗 1.3站得高,望得远 1.4操作系统做什么 1.5内存不够怎么办 1.6众人拾柴火焰高 1.7本章小结 程序员的自我修养—链接、装载与库 第1章温故而知新 1.1从 Hello world说起 亳无疑问,“ Hello world”对于程序员来说肯定是如雷贯耳。就是这样一个简单的程序, 带领了无数的人进入了程序的世界。简单的事物背后往往又蕴涵着复杂的机制,如果我们深 入思考一个简单的“ Hello world”程序,就会发现很多问题看似很简单,但实际上我们并没 有一个非常清晰的思跻;或者在我们脑海里有着模的印象,但真正到某些细节的时候可能 又模糊不清了。比如对于C浯言编写的 Hello world程序 Include <stdio.h> int main( printf("ello World\n")i return 对于下面这些问题,你的脑子里能够马上反应出一个很清晰又很明确的答案吗? 程序为什么要被编译器编译了之后才可以运行? 编译器在把C语言程序转换成可以执行的机器码的过程中做了什么,怎么做的? ●最后编译出来的可执行文件里面是什么?除了机器码还有什么?它们怎么存放的,怎 么组织的? ●# include< stdio. h>是什么意思?把 stdio h包含进来意味着什么?C语言库又是什么?它 怎么实现的? 不同的编译器( Microsoft vc、GCC)和不同的硬件平台(x86、 SPARC、MIPS、ARM), 以及不同的操作系统( Windows、 Linux、UNX、 Solaris),最终编译出来的结果一样 吗?为什么? a Hello world程序是怎么运行起来的?操作系统是怎么装载它的?它从哪儿开始执行, 到哪儿结束?main函数之前发生了什么?main函数结束以后又发生了什么? 如果没有操作系统, Hello World可以运行吗?如果要在一台没有操作系统的机器上运 行 Hello world需要什么?应该怎么实现? ● printf是怎么实乳的?它为什么可以有不定数量的参数?为什么它能够在终端上输出字 符串? Hello world程序在运行时,它在内存中是什么样子的? 对亍上面的问题,如果你确信能够非常清楚地了解里面的各个细节,并且对其中的过程 和机制都了如指掌,那么很遗憾,这本书不是为你准备的:如果你发现对其中一些问题并不 程序员的自我修养——链接、装载与库 1.2万变不离其宗 是很了解,甚至从来没有想到过一个 Hello world还能引出这么多值得思考的问题,而你又 想了解它们,那么恭喜你,这本书就是为你准备的。随着各个章节的逐步展开,我们会从最 基本的编译、静态链接到操作系统如何装载程序、动态链接及运行库和标准库的实现,甚至 些操作系统的机制,力争深入浅出地将这些问题层层剥开,最终使得这些程序运行背后的 机制形成一个非常清晰而流畅的脉络。 在开始进入厐大而又繁琐的系统软件之前,让我们先进行热身活动,那就是一起来回顾 计算机系统的一些基本而又重要的概念。整个计算机系统回顾过程将分为两个部分,分别是 硬件部分和软牛部分。本书的主要目的不是介绍计算机系统结构,第1章的回顾只是巩固和 总结计算机软使件体系里面几个重要的概念,这些概念在我们后面的章节中将时时伴随着我 们,失去了它们的支撑,后面的章节将会显得繁琐而又晦涩。如果你自认为这些基本概念很 简单,那么你可以大概地浏览一遍几个知识点的标题,然后直接跳到第2章:反之,如果你 觉得有些概念还不是很清楚,甚至从来没听说过这些概念,那么诗你仔细阅读相关章节,相 信这个过程对你阅读本书甚至对你深入了解计算机大有裨益。 12万变不离其宗 计算机是个非常广泛的概念,大到占用数层楼的用于科学计算的超级计算机,小到手机 上的嵌入式芯片都可以被称为计算机。虽然它们的外形、结构和性能都千差万别,但至少它 们都有“计算”这个概念。在本书里面,我们将计算机的范围限定在最为流行、使用最广泛 的PC机,更具体地讲是采用兼容x86指令集的32位CPU的个人计算机。原因很简单:因 为笔者手上:目前只有这种类型的计算机可供操作和实验,不过相信90%以上的读者也是, 所以在这一点上我们很快能达成共识。其实选择具体哪种平台并不是最关键的,虽然各种平 台的软硬件差别很多,但是本质上它们的基本概念和工作原理都是一样的,只要我们能够掌 握一种平台上的技术,那么其他的平台都是大同小异的,很轻松地可以举一反三。所以我们 相信,只有你能够深刻地理解ⅹ86平台下的系统软件背后的机理,当有一天你需要在MPS 指令集的嵌入式平台上做开发,或者需要为64位的 Windows或 Linux开发应用程序的时侯, 你很快就能找到它们之间的相通之处。 撇开计算机硬件中纷繁复杂的各种设备、芯片及外围接口等,站在软件开发者的角度看, 我们只须抓住硬件的儿个关键部件。对于系统程序开发者来说,计算机多如牛毛的硬件设备 中,有三个部件最为关键,它们分别是中央处理器CPU、内存和DO控制芯片,这三个部件 几乎就是计算机的核心了;对于普通应用程序开发者来说,他们似乎除了要关心CPU以外 其他的硬件细节基本不用关心,对于一些高级平台的开发者来说(如Java、NET或脚本语 言开发者),连CPU都不需要关心,因为这些平台为它们提供了个通用的抽象的汁算机, 程序员的自我修养——链接、装载与库 第1章温故而知新 他们只要关心这个抽象的计算机就可以了。 早期的计算机没有很复杂的图形功能,CPU的核心频率也不高,跟内存的频率一样, 它们都是直接连接在同一个总线(Bus)上的。由于O设备诸如显示设备、键盘、软盘和 磁盘等速度与CPU和内存相比还是慢很多,当时也没有复杂的图形设备,显示设备大多是 只能输出字符的终端。为了协调IO设备与总线之间的速度,也为了能够让CPU能够和1O 设备进行通信,一般每个设备都会有一个相应的IO控制器。早期的计算机硬件结构如图 所 Monito Keyboard Floppy Hard disk drive disk drive Video Keyboard Floppy Hard CPU Memory controller controller disk disk controler controller BUS 图1-1早期的计算机硬件结构 后来由于CPU核心频率的提升,导致内存跟不上CPU的速度,于是产生了与内存频率 致的系统总线,而CPU采用倍频的方式与系统总线进行通信。接着随着图形化的操作系 统普及,特别是3D游戏和多媒体的发展,使得图形芯片需要跟CPU和内存之间大量交换 数据,慢速的O总线已经无法满足图形设备的巨大需求。为了协调CPU、内存和高速的图 形设备,人们专门设计了一个高速的北桥芯片,以便它们之间能够高速地交换数据。 山于北桥运行的速度非常高,所有相对低速的设备如果全都直接连接在北桥上,北桥 既须处理高速设备,又须处理低速设备,设计就会十分复杂。于是人们又设计了专门处理 低速设备的南桥( Southbridge)芯片,磁盘、USB、键盘、鼠标等设备都连接在南桥上, 由南桥将它们汇总后连接到北桥上。20世纪90年代的PC机在系统总线上采用的是PCI 结构,而在低速设备上采用的ISA总线,采用PCSA及南北桥设计的硬件构架如图1-2 所示。 位于中间是连接所有高速芯片的北桥( Northbridge, PCI Bridge),它就像人的心脏 连接并驱动身体的各个部位:它的左边是CPU,负责所有的控制和运算,就像人的大脑。 比桥还连接着几个高速部件,包括左边的内存和下面的PCI总线。 PCI的速度最高为133MHz,它还是不能满足人们的需求,于是人们又发明了AGP、 程序员的自我修养——链接、装载与库 12万变不离其宗 7 Gache bus Local bus Memory bus Level 2 cache Main bridge memcry PCI bus USB Graphics SA adapto Avail bridge PCI slot M Ke board ISA bus Modem Sound card Printer Avallable ISA slot 图12硬件结构框架 PCI Express等诸多总线结构和相应控制芯片。虽然硬件结构看似越来越复杂,但实际上它 还是没有脱离最初的CPU、内存,以及O的基本结构。我们从程序开发的角度看待硬件时 可以简单地将它看成最初的硬件模型 SMP与多核 人们总是希望计算机越来越快,这是毫无疑问的。在过去的50年里,CPU的频率从几 十κH刭现在的4GHz,整整提高了数十万倍,基本上每18个月频率就会翻倍。但是自2004 年以来,这种规律似乎已经失效,CPL的频率自从那时开始再也没有发生质的提高。原因 是人们在制造CPU的工艺方面已经达到了物理极限,除非CPU制造工艺有本质的突破,否 则CPU的频率将会一直被目前4GHz的“天花板”所限制。 在频率上短期内已经没有提高的会地了,于是人们开始想办法从另外一个角度来提高 CPU的速度,就是增加CPU的数量。一个计算机拥有多个CPU早就不是什么新鲜事了, 很早以前就有了多CPU的计算机,其中最常见的一种形式就是对称多处理器(SMP, Symmetrical Multi-Processing),简单地讲就是每个CPU在系统中所处的地位和所发挥的 功能都是一样的,是相互对称的。理论上讲,增加CPU的数量就可以提髙运算速度,并且 理想情况下,速度的提高与CPU的数量成正比。但实际上并非如此,因为我们的程序并不 是都能分解成若干个完全不相干的子问题。就比如一个女人可以花10个月生出一个孩子 但是10个女人并不能在一个月就生出一个孩子一样。 程序员的自我修养—链接、装载与库 第1章温故而知新 当然很多时候多处理器是非常有用的,最常见的情况就是在大型的数据厍、〖络服务器 上,它们要同时处理大量的请求,而这些请求之间往往是相互独立的,所以多处理器就可以 最大效能地发挥威力。 多处理器应用最多的场合也是这些商用的服务器和需要处理大量计算的环境。而在个人 电脑中,使用多处理器则是比较奢侈的行为,毕竟多处理器的成本是很高的。于是处理器的 厂商开始考虑将多个处理器“合并在一起打包出售”,这些“被打包”的处理器之间共享比 较昂贵的缓存部件,只保留多个核心,并且以一个处理器的外包装进行出售,售价比单核心 的处理器只贵了一点,这就是多核处理器( Multi-core Processor)的基本想法。多核处理器 实际上就是SMP的简化版,当然它们在细节上还有一些差别,但是从程序员的角度来看 它们之间区别很小,逻辑上来看它们是完全相同的。只是多核和SMP在缓存共享等方面有 细微的差别,使得程序在优化上可以有针对性地处理。简单地讲,除非想把CPU的每一滴 油水都榨干,否则可以把多核和SMP看成同一个概念 推荐阅读:“ Free Lunch is Over”(免费午餐已经结束了) http:ihwwgotae.ca,/publications/concurrency-ddj.htm 随着CPU频率碰到了“天花板",多核处理器越来越普及,对程序员开发程序的方式 也将发生极大的变化,这篇文章很好地分析了将要到来的多核时代对程序开发的挑战 和机遇。 1.3站得高,望得远 系统软件这个概念其实比较模糊,传统意义上一般将用于管理计算机本身的软件称为系 统软件,以区别普通的应用程序。系统软件可以分成两块,一块是平台性的,比如操作系统 内核、驱动程序、运行库和数以千计的系统工具:另外一块是用于程序开发的,比如编译器 汇编器、链接器等开发工具和开发库。本书将着重介绍系統软件的一部分,主要是链接器和 库(包括运行库和开发库)的相关内容 计算机系统软件体系结构采用一种层的结构,有人说过句名言: “计算机科学领域的任何问题都可以通过增加一个间接的中间层来解决”1 "Any problem in computer science can be solved by another layer of indirection 这句话几乎概括了计算机系统软件体系结构的设计要点,整个体系结构从上到下都是按 照严格的层次结构设计的。不仅是计算机系统软件整个体系是这样的,体系里面的每个组件 遗憾的是,这句经典的名言出无从考证,据说是有人从图灵奖的获得者 Butler Lampson的讲座上听来的;也有人说是 EDSAC的发明者 David wheeler讲的;还有人指出这是CMU计算机系创始人 Alan Perlis的名言。 程序员的自我修养—链授、装载与库 1.3站得高,望得远 9 比如操作系统本身,很多应用程序、软件系统甚至很多硬件结构都是按照这种层次的结构组 织和设计的。系统软件体系结构中,各种软件的位置如图1-3所示。 Applications: Development Tools: Web Browser C/C++ Compiler Video Player Assembler Word Processor Library Tools Emall Client Debug Tools Image Viewer Development Libraries -Operating S/ stem AFl- Runtime Library .System Call Operating System Kernel -------- Hardware Specification 品mmm Hardware 图13计算机软件体系结构 每个层次之间都须要相互通信,既然须要通信就必须有一个通信的协议,我们一般将其 称为接口( nterface),接口的下面那层是接口的提供者,由它定义接口;接山的上面那层 是接口的使用者,它使用该接口来实现所需要的功能。在层次体系中,接口是被精心设计过 的,尽量保持稳定不变,那么理论上层次之间只要遵循这个接口,任何一个层都可以被修改 或被替换。除了硬件和应用程序,其他都是所谓的中间层,每个中间层都是对它下面的那层 的包装和扩展。正是这些中间层的存在,使得应用程序和硬件之间保持相对的独立,比如硬 件和操作系统都日新月异地发展,但是最初为80386芯片和DOS系统设计的软件在最新的 多核处理器和 Windows vista下还是能够运行的,这方面归功于硬件和操作系统本身保持了 向后兼容性,另一方面不得不归功于这种层次结构的设计方式。最近开始流行的虚拟机技术 更是在硬件和操作系统之间增加了一层虚拟层,使得一个计算机上可以同时运行多个操作系 统,这也是层次结构带来的好处,在尽可能少改变甚至不改变其他层的情况下,新增加个 层次就可以提供前所未有的功能。 我们的软件体系中,位于最上层的是应用程序,比如我们平时用到的网络浏览器、 Email 客户端、多媒体播放器、图片浏览器等。从整个层次结构上来看,开发工具与应用程序是属 于同一个层次的,因为它们都使用一个接口,那就是操作系统应用程序编程接口( Application Programming Interface)。应用程序接口的提供者是运行库,什么样的运行库提供什么样的 API,比如 Linux下的Gibc库提失POSX的AP; Windows的运行库提供 Windows AP, 最常见的32位 Windows提供的AP又被称为Win32 运行库使用操作系统提供的系统调用接口( System call Interface),系统调用接口在实 程序员的自我修养—链接、装载与库 10 第1章温故而知新 现中往往以软件中断( Software Interrupt)的方式提供,比如 Linux使用0x80号中断作为 系统调用接口, Windows使用0x2E号中断作为系统调用接口(从 Windows XP Sp2开始, Windows开始采用一种新的系统调用方式)。 操作系统内核层对于硬件层来说是硬件接口的使用者,而硬件是接口的定义者,硬件的 接口定义决定了操伫系统内核,具体来讲就是驱动程序如何操作硬件,如何与硬件进行通信。 这种接口往往被叫做硬件规格( Hardware Specification),硬件的生产厂商负责提供硬件规 格,操作系统和驱动稈序的开发者通过阅读硬件规格文档所规定的各种硬件编程接口标准来 编写操作系统和驱动程序。 1.4操作系统做什么 操作系统的一个功能是提供抽象的接口,另外一个主要功能是管理硬件资源。 计算机硬牛的能力是有限的,比如一个CPU一秒钟能够执行的指令条数是1亿条或是 GB的内存能够最多同时存储1GB的数据。无论你是否使用它,资源总是那么多。当然我 们不希望自己花钱买回来的硬件成为摆设,充分挖掘硬件的能力,使得计算机运行得更有效 率,在更短的时间内处理更多的任务,才是我们的目标。这对于早期动辄数百万美元的占董 计算机来说更是如此,人们挖空心思让计算机硬件发挥所有潜能。一个计算机中的资源主要 分CPU、存储器(包括内存和磁盘)和ⅣO设备,我们分别从这三个方面来看看如何挖掘它 们的潜力。 14.1不要让CPU打盹 在计算机发展早期,CPU资源十分昂贵,如果一个CPU只能运行一个程序,那么当程 序读写磁盘(当时可能是磁带)时,CPU就空闲下来了,这在当时简直就是暴殄天物。于 是人们很快编写了一个监控程序,当某个程序暂时无须使用CPU时,监控程序就把另外的 正在等待CPL资源的程序启动,使得CPU能够充分地利用起来。这种被称为多道程序 ( Multiprogramming)的方法看似很原始,但是它当时的确大大提高了CPU的利用率。不 过这种原始的多道程序技术存在最大的问题是程序之间的调度策略太粗糙。对于多道程序来 说,程序之间不分轻重缓急,如果有些程序急需使用CPU来完成一些任务(比如用户交互 的任务),那么很有可能很长时间后才有机会分配到CPI。这对于有些响应时间要求高的程 序夹说是很致命的,想象一下你在 Windows上面点击鼠标10分钟以后系统才有反应,那该 是多么沮丧的事。 经过稍微改进,程序运行模式变成了一种协作的模式,即每个程序运行一段时间以后都 程序员的自我修养—链接、装载与库

...展开详情
试读 127P 程序员的自我修养--完整PDF版
立即下载 低至0.43元/次 身份认证VIP会员低至7折
    抢沙发
    一个资源只可评论一次,评论内容不能少于5个字
    • 至尊王者

      成功上传501个资源即可获取
    关注 私信 TA的资源
    上传资源赚积分,得勋章
    最新推荐
    程序员的自我修养--完整PDF版 13积分/C币 立即下载
    1/127
    程序员的自我修养--完整PDF版第1页
    程序员的自我修养--完整PDF版第2页
    程序员的自我修养--完整PDF版第3页
    程序员的自我修养--完整PDF版第4页
    程序员的自我修养--完整PDF版第5页
    程序员的自我修养--完整PDF版第6页
    程序员的自我修养--完整PDF版第7页
    程序员的自我修养--完整PDF版第8页
    程序员的自我修养--完整PDF版第9页
    程序员的自我修养--完整PDF版第10页
    程序员的自我修养--完整PDF版第11页
    程序员的自我修养--完整PDF版第12页
    程序员的自我修养--完整PDF版第13页
    程序员的自我修养--完整PDF版第14页
    程序员的自我修养--完整PDF版第15页
    程序员的自我修养--完整PDF版第16页
    程序员的自我修养--完整PDF版第17页
    程序员的自我修养--完整PDF版第18页
    程序员的自我修养--完整PDF版第19页
    程序员的自我修养--完整PDF版第20页

    试读已结束,剩余107页未读...

    13积分/C币 立即下载 >