深入理解计算机系统学习笔记(一)

程序的编译过程

为了说明程序的编译过程,我们用经典的hello world程序作为例子

#include <stdio.h>

int main(int argc, char const *argv[])
{
    printf("hello world!!!\n");
    return 0;
}

在linux系统中,我们用GCC编译器将源程序文件helloworld.c编译成可执行目标文件helloworld。

zengwh@zengwh:~/test_code$ gcc helloworld.c -o hello
zengwh@zengwh:~/test_code$ ./hello
hello world!!!

这个过程经过四个阶段,分别是预处理阶段,编译阶段,汇编阶段和链接阶段。执行这个四个阶段的程序分别是预处理器,编译器,汇编器和链接器,一起构成了编译系统。

  • 预处理阶段:预处理器(cpp)根据‘#’包含的头文件,将头文件的内容加进源程序中。得到新的程序文件文本,以“.i”为文件扩展名。比如说helloworld程序包含stdio.h头文件,这个阶段将这个头文件的内容插进源程序中
  • 编译阶段:编译器(ccl)将文本文件hello.i翻译成汇编程序hello.S。也就是将高级语言翻译成汇编代码,低级的机器语言指令。
  • 汇编阶段:汇编器(as)将汇编程序hello.S翻译成机器指令,将这些指令打包成可重定位目标程序的格式,并把结果保存在hello.o文件中,hello.o是个二进制文件。
  • 链接阶段:链接器(ld)将会把一个工程中所有的.o文件链接合并成一个可执行目标文件,可以被加载在内存中,由系统运行。

系统硬件组成

高速缓存(Caches)

高速缓存用来存放处理器近期可能需要的信息,用来加快程序在CPU的运行,下图是一个典型系统中的高速缓存存储器。

位于处理器芯片上的L1高速缓存访问速度跟访问寄存器的速度几乎一样快,L2高速缓存通过一条特殊的总线连接到CPU,访问速度比L1慢5倍左右,但比访问主存要快5-10倍。更新的系统还会有L3高速缓存,他们都是用一种SRAM的硬件技术实现的。这样,系统就可以获得很大的一块存储器,而且访问速度也很快。

程序具有访问局部区域里的数据和代码的趋势。通过将可能经常访问的数据保存在高速缓存中的方法,大部分的存储器操作都将在快速的高速缓存中完成,程序性能大大提升。

操作系统管理硬件

在处理器中,指令集结构是对实际处理器硬件的抽象,在操作系统中,文件是对I/O的抽象,虚拟存储器是对程序存储器的抽象,进程是对一个正在运行的程序的抽象,虚拟机则是对整个计算机(包括操作系统,处理器和程序)的抽象

进程

进程是操作系统中对一个正在运行的程序的一个抽象。一个系统可以同时运行多个进程程序,而每个进程都好像独占使用硬件。并发运行则是说一个进程的指令和另一个进程的指令是交错运行的。

线程

一个进程可以由多个线程组成,每个线程运行在进程的上下文中,并共享同样的代码和全局数据。

虚拟存储器

虚拟存储器是一个抽象概念,为每个进程提供一个假象,即每个进程好像在独占使用主存。每个进程看到的是一致的存储器,即是虚拟地址空间。图中的地址是从下往上增大。

  • 程序代码和数据:对所有进程来说,代码都是从同一固定地址开始,接着就是全局变量对应的数据位置。代码和数据区一开始运行就已经规定大小。
  • 堆:堆可以运行的时候动态地扩展和收缩,比如调用malloc或free函数的时候。
  • 共享库:大约在地址中间,用来存放像C标准库或数学库这样共享的代码和数据区域。
  • 栈:位于用户虚拟地址空间顶部的是栈,编译器同它来实现函数调用。和堆一样,在程序运行期间可以动态地扩展和收缩。每调用函数,栈增长,函数返回,栈收缩。
  • -

时间: 2024-10-09 17:28:57

深入理解计算机系统学习笔记(一)的相关文章

深入理解计算机系统读书笔记一 ---&gt; 计算机基础漫游

一.程序编译的不同阶段. 通常我们是以高级程序开发易于阅读的代码,我们通过语法规则推断代码的具体含义.但是计算机执行代码的时候就需要把代码解析成既定的可执行问题,计算机是如何处理的呢?这里以C语言hello.c文件为例来说明中间过程. #include <stdio.h> int main() { printf("hello world!\n"); } 先上张图. C语言源程序----预处理解析头文件和函数  --- 编译器解析成汇编语言 ---   翻译机器语言指令,打包

深入理解计算机系统读书笔记之第一章:漫游

我是从豆瓣上看到好多人都在推荐这本书,于是就去借来读一读,昨天晚上用了好长时间来读这本书的第一章节,感觉这本书比较符合我(有些基础还不太明白,这本书详细的进行了讲解,很好). 下面写一下我的理解(顺便回顾一下知识) 第一节主要讲的是: A Tour of Computer Systems 以hello.c为例进行讲解,介绍这个程序如何从一个源程序变成可执行程序,再到执行,显示屏上出现“hello,world” ···········································

3.2《深入理解计算机系统》笔记(二)内存和高速缓存的原理【插图】

<深入计算机系统>笔记(一)主要是讲解程序的构成.执行和控制.接下来就是运行了.我跳过了"处理器体系结构"和"优化程序性能",这两章的笔记继续往后延迟! <深入计算机系统>的一个很大的用处是:给了我们很多定义式的解释,或者称之为科学的解释,这将成为我的理论依据:不再是网上一些自称老手的闲聊了.不愧是计算机最牛逼的大学卡内基-梅隆大学的教材. 该blog跳过第四章CPU的结构,第五章优化程序性能,也没有详细讨论高速缓存的机制. 六.存储器层次结

4.2《深入理解计算机系统》笔记(五)并发、多进程和多线程【Final】

该书中第11章是写web服务器的搭建,无奈对web还比较陌生.还没有搞明白. 这些所谓的并发,其实都是操作系统做的事情,比如,多进程是操作系统fork函数实现的.I/O多路复用需要内核挂起进程.多线程需要内核创建和挂起线程.我么只是使用以下操作系统的这项并发技术.但是我们必须处理一些存在问题. ●进程.用这种方法,每个逻辑控制流都是一个进程,由内核来调度和维护.因为进程有独立的虚拟地址空间,想要和其他流通信,控制流必须使用进程间通信(IPC). ●I/O多路复用.这种形式的并发,应用程序在一个进

深入理解计算机系统学习(位扩展)

最近在复习计算机基础知识,断断续续的记录在这里吧. 深入理解计算机系统是本好书,对底层的实现原理从程序员的角度进行的细致的讲解,不愧为经典,深得大家的喜爱. 其中CPU对于有符号,无符号转化以及位的扩展引起的溢出问题需要理解,并在写c的时候避免,有时候编译不报错, 但是却存在隐患. 1.无符号扩展直接高位补0 例如,无符号扩展 unsigned short e = 100; int f = e; printf("e= %.2xH\n", e); show_bytes((byte_poi

&lt;深入理解JavaScript&gt;学习笔记(4)_立即调用的函数表达式

前言 大家学JavaScript的时候,经常遇到自执行匿名函数的代码,今天我们主要就来想想说一下自执行.(小菜理解:的确看到好多,之前都不知道这是自执行匿名函数) 在详细了解这个之前,我们来谈了解一下“自执行”这个叫法,本文对这个功能的叫法也不一定完全对,主要是看个人如何理解,因为有的人说立即调用,有的人说自动执行,所以你完全可以按照你自己的理解来取一个名字,不过我听很多人都叫它为“自执行”,但作者后面说了很多,来说服大家称呼为“立即调用的函数表达式”.(小菜理解:不管叫什么,大概意思都是一样的

&lt;深入理解JavaScript&gt;学习笔记(1)_编写高质量JavaScript代码的基本要点

注:本文是拜读了 深入理解JavaScript 之后深有感悟,故做次笔记方便之后查看. JQuery是一个很强大的JavaScript 类库,在我刚刚接触JavaScript的就开始用了. JQuery使用起来非常方便,以至于我这样的JS小白在任何网站上都会毫不犹豫的引入JQuery.....(我想这样做的不止我一个人吧,哈哈) 由于最近新项目中开始使用各种JavaScript 插件(JQueryUI, JQuery.dataTable,uploadify等....),需要进一步封装,以方便使用

Autolayout 约束类方法的理解(学习笔记二)

随apple大屏手机的问世,屏幕适配问题被堆到风口浪尖,对于代码画UI的同学无疑是个噩梦.在上班闲暇之余,学习了autolayout:autolayout从iOS6开始使用,因为各种坑,只有一些advanced coder们所用,但现在autolayout今非昔比了.学习的必要性也越发强烈. autolayout也可以用代码实现,apple可爱的工程师开发了一个可视化语言VFL(Visual Format Language),这里不解释VFL的语法,但是要解释一个约束的类方法,个人觉得这对理解a

&lt;深入理解JavaScript&gt;学习笔记(5)_强大的原型和原型链

前言 JavaScript 不包含传统的类继承模型,而是使用 prototypal 原型模型. (prototypal :原型.学好英语还是很重要的) 虽然这经常被当作是 JavaScript 的缺点被提及,其实基于原型的继承模型比传统的类继承还要强大.实现传统的类继承模型是很简单,但是实现 JavaScript 中的原型继承则要困难的多. 由于 JavaScript 是唯一一个被广泛使用的基于原型继承的语言,所以理解两种继承模式的差异是需要一定时间的,今天我们就来了解一下原型和原型链. 原型