CPU总是周而复始地做同一件事:从内存取指令,然后解释执行它,然后再取下一条指令,再解释执行。CPU包含以下功能单元:
寄存器(Register),是CPU内部的高速存储器,像内存一样可以存取数据,但比访问内存快得多。我们马上会讲到x86的寄存器如eax
、ebp
、eip
等等,有些寄存器保存的数据只能用于某种特定的用途,比如eip
寄存器用作程序计数器,这称为特殊寄存器(Special-purpose Register),而另外一些寄存器保存的数据可以用在各种运算和读写内存的指令中,比如eax
寄存器,这称为通用寄存器(General-purpose Register)。
程序计数器(PC,Program Counter),保存着CPU取指令的地址,每次CPU读出程序计数器中保存的地址,然后按这个地址去内存中取指令,这时程序计数器保存的地址会自动加上该指令的长度,指向内存中的下一条指令。
程序计数器通常是CPU的一个特殊寄存器,x86的程序计数器是特殊寄存器eip
,由于地址是32位的,所以这个寄存器也是32位的,事实上通用寄存器也是32位的,所以也可以说处理器的位数是指它的寄存器的位数。处理器的位数也叫做字长,字(Word)这个概念用得比较混乱,在有些上下文中指16位,在有些上下文中指32位(这种情况下16位被称为半字Half Word),在有些上下文中指处理器的字长,如果处理器是32位那么一个字就是32位,如果处理器是64位那么一个字就是64位。
指令解码器(Instruction Decoder)。CPU取上来的指令由若干个字节组成,这些字节中有些位表示内存地址,有些位表示寄存器编号,有些位表示这种指令做什么操作,是加、减、乘、除还是读、写,指令解码器负责解释这条指令的含义,然后调动相应的执行单元去执行它。
算术逻辑单元(ALU,Arithmetic and Logic Unit)。如果解码器将一条指令解释为运算指令,就调动算术逻辑单元去做运算,比如加减乘除、位运算、判断一个条件是否成立等。运算结果可能保存在寄存器中,也可能保存到内存中。
地址和数据总线(Bus)。CPU和内存之间用地址总线、数据总线和控制线连接起来,32位处理器有32条地址线和32条数据线[25],每条线上有1和0两种状态,32条线的状态就可以表示一个32位的数。如果在执行指令过程中需要访问内存,比如从内存读一个数到寄存器,则执行过程可以想像成这样:
CPU内部将寄存器对接到数据总线上,使寄存器的每一位对接到一条数据线,等待接收数据。
CPU将内存地址通过地址线发给内存,然后通过另外一条控制线发一个读请求。
内存收到地址和读请求之后,将相应的存储单元对接到数据总线的另一端,这样,存储单元每一位的1或0状态通过一条数据线到达CPU寄存器中相应的位,就完成了数据传送。
往内存里写数据的过程与此类似,只是数据线上的传输方向相反。