计算机的硬件组成
总线:贯穿整个系统的是一组电子管道(其实就是传输数据的线路),也就是总线。总线传送的是字,字的大小与系统相关,比如在32位操作系统当中,
一个字是4个字节。
I/O设备:I/O设备是系统与外部联系的通道。I/O设备(键盘、鼠标、显示器等)由控制器(USB控制器)或者适配器(图形适配器,也就是显卡)与I/O总线
相连,两者的区别在于一个是主板上的芯片组,一个是主板插槽上的卡。
主存:它是计算机中的一个临时存储设备,在处理器执行程序的时候,主存就是临时存放数据的地方。物理上来说,它是由动态随即存取存储器芯片组成,
逻辑上来说,它是一组连续的字节数组,每一个字节都有唯一的地址。
处理器:全称*处理单元,是解释存储在主存中指令的引擎。处理器的核心是一个程序计数器,它在整个计算机运行的期间都会指向一个主存中的一个内存地址,
而地址当中则是一个计算机指令。
处理器所做的,就是不停的执行程序计数器所指向的每一条指令。处理器所做的操作是围绕主存、寄存器文件以及算术/逻辑单元进行的,这里面处理器做的最
多的动作就是加载(从主存将数据复制到寄存器)、存储(从寄存器将数据复制到主存)、操作(将两个寄存器的内容复制到算术/逻辑单元进行操作,结果会再次
复制到寄存器)以及跳转(改变程序计数器当中的内容)。
处理器当中提到的是指令集结构,不过实际当中指令集的实现是非常复杂的,这么做的目的是为了加速CPU的运算速度。我们可以这样去区分指令集机构以及
微体系结构,指令集结构是指令集的抽象描述,而微体系结构则是这个抽象描述的某一个具体实现,类似于JAVA虚拟机与JAVA虚拟机实现的关系。
寄存器
先来看寄存器。CPU 本身只负责运算,不负责储存数据。数据一般都储存在内存之中,CPU 要用的时候就去内存读写数据。但是,CPU 的运算速度远高于内存
的读写速度,为了避免被拖慢,CPU 都自带一级缓存和二级缓存。
基本上,CPU 缓存可以看作是读写速度较快的内存。
但是,CPU 缓存还是不够快,另外数据在缓存里面的地址是不固定的,CPU 每次读写都要寻址也会拖慢速度。因此,除了缓存之外,CPU 还自带了
寄存器(register),用来储存最常用的数据。
也就是说,那些最频繁读写的数据(比如循环变量),都会放在寄存器里面,CPU 优先读写寄存器,再由寄存器跟内存交换数据。
寄存器不依靠地址区分数据,而依靠名称。每一个寄存器都有自己的名称,我们告诉 CPU 去具体的哪一个寄存器拿数据,这样的速度是最快的。
有人比喻寄存器是 CPU 的零级缓存。
内存模型:Heap
寄存器只能存放很少量的数据,大多数时候,CPU 要指挥寄存器,直接跟内存交换数据。所以,除了寄存器,还必须了解内存怎么储存数据。
程序运行的时候,操作系统会给它分配一段内存,用来储存程序和运行产生的数据。这段内存有起始地址和结束地址,比如从0x1000
到0x8000
,起始地址是较小
的那个地址,结束地址是较大的那个地址。
程序运行过程中,对于动态的内存占用请求(比如新建对象,或者使用malloc
命令),系统就会从预先分配好的那段内存之中,划出一部分给用户,具体规则是从起始地址开始划分(实际上,起始地址会有一段静态数据,这里忽略)。
举例来说,用户要求得到10个字节内存,那么从起始地址0x1000
开始给他分配,一直分配到地址0x100A
,如果再要求得到22个字节,那么就分配到0x1020
。
这种因为用户主动请求而划分出来的内存区域,叫做 Heap(堆)。它由起始地址开始,从低位(地址)向高位(地址)增长。Heap 的一个重要特点就是不会自动消失,必须手动释放,或者由垃圾回收机制来回收。
内存模型:Stack
除了 Heap 以外,其他的内存占用叫做 Stack(栈)。简单说,Stack 是由于函数运行而临时占用的内存区域。
请看下面的例子。
int main() {
int a = ;
int b = ;
}
上面代码中,系统开始执行main
函数时,会为它在内存里面建立一个帧(frame),所有main
的内部变量(比如a
和b
)都保存在这个帧里面。main
函数执行结束后,该帧就会被回收,释放所有的内部变量,不再占用空间。
http://www.ruanyifeng.com/blog/2018/01/assembly-language-primer.html