CPU能看到的和认识的就二进制的代码。这和我们编写出来的东西差别太大了。它是如何知道什么是代码?什么是数据?如何来处理的呢?
我先来了解那些高级语言是如何变成二进制代码的。以C语言为例,在我们编写完一个程序后,这些程序是存在一个文本文件中的,我们将这个文件通过预处理器、编译器、链接器一步一步处理后就得到了一个可执行的文件,这个文件就是一个二进制的可执行文件了,而且这个文件是CPU可以看得懂的文件了。有了这个文件我们只要将文件加载到内存中,本通知CPU就可以。可执行文件的加载是操作系统通过一个叫做可执行文件加载程序来完成(这个东西以后再细讲)。在加载完后操作系统就会为其创建一个进程,并完成可执行文件到进程的映射,有了进程就可以通知CPU了。(进程的概念并不是一开始就有的,而是后来发长出来的,但是在现代谈程序的运行是一定有谈到进程的,对CPU来说进程是可运行的,而映射到内存的可执行文件只是一个数据的存储区域了。
在有了上面的基本了解后,我们就可以开始来了解CPU是如何运转程序了。要了解CPU的功能,最好是通过汇编语言,汇编语言中的指令反映了CPU的功能和运行过程。在下面的介绍中我们主要是用的汇编语言来讲解。(对于CPU来说,我们平时认为比较低级的语言C,对他来说太高级了,它理解不了)
CPU中的寄存器。
这里以大家用的很多的Inter的CPU来介绍。在Inter的8086CPU中有4个通用寄存器,他们被分别命名为AX、BX、CX、DX。这些被命名的寄存器可以直接通过上面的名字在汇编语言中使用。通用寄存器就如他们的名字一样,可以存储各种各样的类型数据(整数、字符、指针等等)。他们是一个零时的数据存储地方,用来存储CPU运转过程中的各种类型的中间结果。由于他们什么类型的数据都可以存,而且都是二进制的东西,所以CPU不能区分他们存的东西的类型,所以在实际的使用中AX、DX用来存储整数,而BX用来临时存储堆栈的栈顶指针。
除了以上的4个通用寄存器外,CPU还有4个堆寄存器。他们分别是CS(代码段寄存器)、DS(数据段寄存器)、SS(堆栈段寄存器)、ES(附加段寄存器)。在此我们主要要了解得是前三个段寄存器。
在深入讲段寄存器前,我要先说一下段的概念。在8086CPU上,它的地址总线的长度是20,而寄存器是16位的,这就出现了一个地址数据无法存储在一个寄存器中,这样就用两个寄存器来存储。这样就产生了段这个概念。即一个寄存器存储多出来的四位数据,这个数据就叫段,另一个寄存器存储另外的16位的数据,这个叫段内地址。两个数据相加就得到了一个20位的地址数。
CS(代码段寄存器)用来存储代码在内存中的首地址。与他合作另一个寄存器IP(地址指针寄存器)用来存储将要处理的代码在段内的偏移地址。这两个地址相加后就得到了代码在内存中的实际地址,CPU将内存中的内容读到通用寄存器中就可以开始按指令工作了。
DS(数据段寄存器)用来存储程序中用个的各个变量的值在内存中一个段的首地址,通过数据的寻址,来得到数据在内存中的实际地址,而得到实际的值,或改变这个值。
SS(堆栈段寄存器)用来存储一个堆栈段的首地址,它与SP寄存器合作来找到堆栈内数据的实际地址。堆栈主要用来存储函数传入的值,和于调用函数有关的CPU环境信息。有了堆栈就可以实现递归的算法。可以有了函数的概念了。
(未完待续——)