CSAPP之阅读笔记-计算机系统漫游(1)
最近在看CSAPP(深入理解计算机系统第二版),其实最新版是第三版。但是,我看了一下价格100多大洋,于是去老夫子旧书网上买了本第二版的,花了30多块钱。哈哈。
网上看了一些关于此书的书评,都说是本好书,唯一缺点就是比较难懂。没关系,就姑且先啃一啃,实在不行,实在不行,再退而求其次,看那本《编码:隐匿在计算机软硬件背后的语言》吧。
以下是书中笔记部分与自己理解部分,由于是自学,误解或者错误肯定是不可避免的,希望能给予指出。
第一章 计算机系统漫游
计算机系统是由硬件跟软件共同组成的,它们是一起工作来运行应用程序的。如果你深入地去了解这些硬件跟软件的组件,那么你将会成为凤毛麟角的“权威”程序员。在这本书里,你会学到很多实用的技巧来优化代码,避免漏洞,设计shell,甚至web服务器。
先从hello程序的例子来看看当你在系统上执行这个程序时,系统会发生什么。
code/intro/hello.c
#include <stdio.h>
int main(){
printf("hello, world");
}
1.1 信息就是位+上下文
hello程序其实就是一个文本文件,文件名为hello.c。这个文本是由0和1组成的位序列。8个位被组织成一组,称为字节。了解ASCII码的,就会明白,每一个字符都是根据ASCII表被编码成8位的二进制位。例如,hello.c程序就是以字节序列的方式存储在文件中,每个字节(也就是一个字符)对应于一个整数值。所以,hello.c程序用ASICC文本来表示就是下图的这个样子。
当然,在计算机中,所有的表示ASCII文本的整数都是以二进制方式存储的。像这些只有ASCII字符构成的文件称之为文本文件(可以从键盘上获得的字符组成的文件),而其他所有的文件称为二进制文件。
通过这个hello程序,我们就能明白一个思想:系统中所有的信息——包括磁盘文件(比如视频,图片资料)、存储器中的程序(比如hello.c程序)、存储器中存放的用户数据以及网络上传送的数据,其实都是一串位表示的。而区分不同数据对象的唯一方法就是我们督导这些数据对象时的上下文。
1.2 程序被其他程序翻译成不同的格式
hello程序在执行之前,会被翻译成不同格式的程序。在unix系统上,从源文件到目标文件的转化是由编译器驱动程序完成的:
gcc -o hello hello.c
这条命令会将它翻译成一个可执行目标文件hello,在这个翻译的过程中经过了四个阶段。
1、预处理阶段。在这个阶段预处理器(cpp)会根据以#开头的命令,修改原始的程序。例如hello程序中,是将文件stdio.h的内容插入到程序文本中。这样就得到了另外的一个程序。这个程序通常是以.i作为文件扩展名的。
2、编译阶段。在这个阶段编译器(ccl)会将hello.i翻译成hello.s。它是一个包含汇编语言的程序。汇编语言程序中的每条语句都是以一种标准的文本格式确切地描述了一条低级机器语言指令。
3、汇编阶段。在这个阶段汇编器(as)将hello.s翻译成机器语言指令,并把这些指令打包成一种叫做可重定位目标程序的格式,并将结果保存在牧宝文件hello.o中。这里的hello.o文件是一个二进制文件,它的字节编码是机器语言指令,而不是字符。
4、链接阶段。在这个阶段会将预编译好的目标文件加载到程序文件中。例如hello程序中,printf函数存在与一个名为printf.o的单独预编译好的慕白文件中,而这个printf.o必须通过链接器(ld)来合并并到我们的hello.o程序中。这样,最终就到了hello文件,它是一个可执行目标文件,可以被加载到内存中,有系统执行。
1.3 了解编译系统是如何工作是大有益处的
我们完全可以依靠编译器来生成正确有效的机器代码,为什么还要费尽心思来了解编译系统是如何工作的?
1、可以优化程序的性能。如果了解编译器的内部工作,就能明白一个switch语句总是比一系列的if-then-else要更加的高效。
2、理解链接时出现的错误。根据以往的经验,一些困扰已经的程序错误往往都是与连接器操作有关。
3、避免安全漏洞。缓冲区溢出错误是造成大多数我拿过来和internet服务器上安全漏洞的主要原因,这些内容会在第3章中进行介绍。学习安全编程的第一步就是理解数据和控制信息存储在程序栈上的方式引起的后果。
1.4 处理器读并解释存储在存储器中的指令
回想一下hello.c程序,它此时已经被翻译称为了可执行的目标文件hello,并存放在了磁盘上。我们通过shell程序来运行它。
1.4.1 系统的硬件组成
那么在运行hello程序时发生了什么,先看一个计算机的硬件图。
1、总线。它是整个系统的电子管道,相当于城市的公路,它将字节在各个部件进行传递。通常总线被设计成为传送定长的字节块,也就是字(word)。这里的定长是一个系统的参数,各个机器的情况不一样,如果是32位的,那么机器的字长就是4个字节。如果是64位的,那么机器的字长就是8个字节。这里,假设字长是4个字节,并且总线每次只传送一个字。
2、I/O设备。I/O设备是系统与外部世界的联系通道。这里有4个I/O设备:键盘、鼠标、显示器、磁盘。每个I/O设备都是通过一个控制器或者适配器来与I/O总线相连。
3、主存。主存是一个临时存储设备,在处理器执行程序的时候,用来存放程序和程序处理的数据
4、处理器。处理器(CPU)是解释(或者执行)存储在主存中指令的引擎。它的核心是一个字长的存储设备(或寄存器),称为程序计数器,在任何时刻,PC都指向主存中的某条机器语言指令(即含有该条指令的地址)。这些内容会在第4章中有详细的介绍。这里只做一个区分,就是处理器的指令集结构和微体系结构。指令集结构描述的是每条机器代码指令的效果。而微体系结构描述的是处理器实际上是如何实现的。
1.4.2 运行hello程序
当对计算机的硬件有大致的了解之后。我们在来看执行hello程序之后,发生了什么事。
1、当我们在shell命令行中输入字符串“./hello”之后,shell程序会将这些字符通过键盘读入到寄存器,然后在存放到存储器中。
2、输入回车之后,shell程序知道我们结束了命令,然后它加载可执行文件hello,将文件中的代码和数据(这里的数据包括最终会被输出的字符串“hello, world\n”)从磁盘复制到主存。利用直接存储器存取的技术(DMA),数据可以不通过处理器而直接从磁盘到达主存。
3、当慕白文件hello中代码和数据被加载到主存之后,处理器就开始执行hello程序的main程序中的机器语言指令。执行完毕后,这些指令将“hello, world\n”字符串中的字节从主存复制到寄存器文件,再从寄存器文件中复制到显示设备,最终显示在屏幕上。
1.5 高速缓存至关重要
从上面的例子可以看到,系统会花费了很多的时间把信息从一个地方复制到另外一个地方。从程序员的角度来看,这些复制就是开销,它减缓了程序的工作。因此,系统设计者的一个主要的目标就是使这些复制尽快的完成。而一个高速缓存存储器,会让处理器更快地访问经常需要处理的数据。
本书的一个重要的结论,就是意识到高速缓存存在的应用程序员可以利用高速缓存将他们的程序的性能提高一个数量级。
1.6 存储设备形成层次结构
在处理器和内存之间插入一个更小更快的存储设备已经称为了一个比较普遍的观念。实际上,每一个计算机系统中的存储设备都被组成成了一个存储器层次结构。
CSAPP之阅读笔记-计算机系统漫游(1)的更多相关文章
- CSAPP:第一章计算机系统漫游
CSAPP:计算机系统漫游 关键点:上下文.程序运行.计算机系统抽象. 信息就是位+上下文一个程序的运行过程系统的硬件组成编译系统是如何工作的?一个程序的运行过程(c语言举例)计算机系统中的抽象 信息 ...
- 【CSAPP】一、计算机系统漫游
一.位+上下文 文本文件 / 二进制文件: 文本文件是只由ASCII码构成的文件 二.从源代码到可执行文件的顺序 源代码 ——> 可执行文件(机器代码)共有四步: 全过程代码 gcc hello ...
- [CSAPP笔记][第一章计算机系统漫游]
计算机系统漫游 我们通过追踪hello程序的生命周期来开始对系统的学习—–从它被程序员创建,到系统上运行,输出简单的消息,然后终止.我们沿着这个程序的生命周期,简要介绍一些逐步出现的概念,专业术语和组 ...
- CSAPP =1= 计算机系统漫游
思维导图 预计阅读时间:15min 阅读书籍 <深入理解计算机系统> 参考视频 [精校中英字幕]2015 CMU 15-213 CSAPP 深入理解计算机系统 课程视频 参考文章 < ...
- CSAPP 第一章 计算机系统漫游
第一章 计算机系统漫游 C语言的起源:(系统级编程的首选) C语言与Unix操作系统关系密切 C语言小而简单:其设计由一个人掌控 C语言是为实践目的设计的:其设计用来实现Unix操作系统 C语言程序编 ...
- 阅读笔记 1 火球 UML大战需求分析
伴随着七天国庆的结束,紧张的学习生活也开始了,首先声明,阅读笔记随着我不断地阅读进度会慢慢更新,而不是一次性的写完,所以会重复的编辑.对于我选的这本 <火球 UML大战需求分析>,首先 ...
- [阅读笔记]Software optimization resources
http://www.agner.org/optimize/#manuals 阅读笔记Optimizing software in C++ 7. The efficiency of differe ...
- 《uml大战需求分析》阅读笔记05
<uml大战需求分析>阅读笔记05 这次我主要阅读了这本书的第九十章,通过看这章的知识了解了不少的知识开发某系统的重要前提是:这个系统有谁在用?这些人通过这个系统能做什么事? 一般搞清楚这 ...
- <<UML大战需求分析>>阅读笔记(2)
<<UML大战需求分析>>阅读笔记(2)> 此次读了uml大战需求分析的第三四章,我发现这本书讲的特别的好,由于这学期正在学习设计模式这本书,这本书就讲究对uml图的利用 ...
随机推荐
- Linux can双机通信(2440+MCP2515 && 51+SJA1000)
2012-01-12 22:43:24 上图: 自收发成功完成后,那么双机通信就比较容易了.关键就是CAN波特率.ID标识.滤波设置正确即可双机通信了.
- Is ICARSCAN same or old version of LAUNCH X431 Easydiag ?
LAUNCH X431 Easydiag 2.0 is basically the same OBD-II Bluetooth device – but the software supplied w ...
- nginx运用
1.nginx的 命令 start nginx 这样,nginx 服务就启动了.打开任务管理器,查看 nginx.exe 进程,有二个进程会显示,占用系统资源,那是相当的少.然后再打开浏览器,输入 h ...
- python学习之文本文件上传
最近用python的flask框架完成了一个最基本的文本文件上传,然后读取. 前端用的Angular的ng2-file-upload完成文件上传,后端用flask接收上传的文件,接着做处理. 在交互的 ...
- C语言实例:结构体
结构体: #include <stdio.h> #include <stdlib.h> //#pragma pack(1) typedef struct{ short i; / ...
- PHP CURL 账号密码 添加授权Authorization头Header
<?phpfunction http_request_xml($url,$data = null,$arr_header = null){ $curl = curl_init(); curl_s ...
- git遇到error: RPC failed; curl 18 transfer closed with outstanding read data remaining fatal: The remote end hung up unexpectedly fatal: early EOF fatal: index-pack failed failed怎么办?
答: 将clone地址中的https://替换成git://即可解决 如: 将https://git.openwrt.org/project/luci.git修改为git://git.openwrt. ...
- loadrunner常用函数集锦
一.三个复制函数的区别: strcpy 原型:extern char *strcpy(char *dest,char *src);用法:#i nclude功能:把src所指由NULL结束的字符串复制到 ...
- Python打开新世界的大门-入门篇1
目录 题记 Python技巧.避坑及心得 八种数据类型 循环 函数 Homework 题外话 之前没有写博客的习惯,现在开始写觉得入门也太晚了吧,看看同龄的大哥都写了十几万字.于是 ...
- Django project troubleshootings
1. 当django project文件夹放到cgi-bin目录下面时会出现下面的错误: [Wed Jan 09 01:52:52.611690 2019] [core:notice] [pid 15 ...