cpu(Central Processing unit,中央处理器):对于一个计算机来讲,最核心的就是 CPU,它包含三个组成部分,运算单元,数据单元、控制单元。
运算单元:只管算,例如做加法、做位移等等。但是,它不知道应该算哪些数据,运算结果应该放在哪里。
数据单元:运算单元计算的数据如果每次都要经过总线,到内存里面现拿,这样就太慢了,所以就有了数据单元。数据单元包括 CPU 内部的缓存和寄存器组,空间很小,但是速度飞快,可以暂时存放数据和运算结果。
控制单元:有了放数据的地方,也有了算的地方,还需要有个指挥到底做什么运算的地方,这就是控制单元。控制单元是一个统一的指挥中心,它可以获得下一条指令,然后执行这条指令。这个指令会指导运算单元取出数据单元中的某几个数据,计算出个结果,然后放在数据单元的某个地方。
总线(Bus):CPU 和其他设备连接,要靠一种叫作总线(Bus)的东西,其实就是主板上密密麻麻的集成电路,这些东西组成了 CPU 和其他设备的高速通道。
程序运行的过程中要操作的数据和产生的计算结果,都会放在数据段里面。那 CPU 怎么执行这些程序,操作这些数据,产生一些结果,并写入回内存呢?
内存(Memery):单靠 CPU 是没办法完成计算任务的,很多复杂的计算任务都需要将中间结果保存下来,然后基于中间结果进行进一步的计算。CPU 本身没办法保存这么多中间结果,这就要依赖内存了。
指令指针寄存器:在cpu的控制单元中有一个指令指针寄存器,它存放的是下一条指令在内存中的地址。控制单元会不断的将代码段中的指令拿进来先放到指令寄存器中。
当前的指令分两部分,一部分是做什么操作,例如是加法还是位移;一部分是操作哪些数据。要执行这条指令,就要把第一部分交给运算单元,第二部分交给数据单元。数据单元根据数据的地址,从数据段里读到数据寄存器里,就可以参与运算了。运算单元做完运算,产生的结果会暂存在数据单元的数据寄存器里。最终,会有指令将数据写回内存中的数据段。
进程切换(Process Switch):CPU 里有两个寄存器,专门保存当前处理进程的代码段的起始地址,以及数据段的起始地址。这里面写的都是进程 A,那当前执行的就是进程 A 的指令,等切换成进程 B,就会执行 B 的指令了,这个过程叫作进程切换(Process Switch)。
地址总线(Address Bus)、数据总线(Data Bus):CPU 和内存来来回回传数据,靠的都是总线。其实总线上主要有两类数据,一个是地址数据,也就是我想拿内存中哪个位置的数据,这类总线叫地址总线(Address Bus);另一类是真正的数据,这类总线叫数据总线(Data Bus)。

栈实现函数调用的过程

函数调用的过程是通过栈实现的。例如函数A调用函数B,函数B调用函数C。A运行至调用函数B的时候先把函数A的相关信息push到栈中,然后运行函数B的逻辑,当运行到调用函数C的地方时,把函数B的相关信息push到栈中,这样当函数C的逻辑运行完之后,再把函数B从栈中pop出来,继续运行函数B剩下的代码逻辑。函数B的代码逻辑全部运行完后,接着把函数A从栈中pop出来,运行函数A剩下的代码逻辑。这样就利用栈实现了函数调用的过程。

常见的汇编指令

move a b :把b值赋给a,使a=b
call和ret :call调用子程序,子程序以ret结尾
jmp :无条件跳
int :中断指令
add a b : 加法,a=a+b
or :或运算
xor :异或运算
shl :算术左移
ahr :算术右移
push xxx :压xxx入栈
pop xxx: xxx出栈
inc: 加1
dec: 减1
sub a b : a=a-b
cmp: 减法比较,修改标志位

x86的寻址大小

x86的地址总线是20位,因此它最大的寻址空间是2^20 = 1M。它将寻址空间按段划分,每个段的偏移量是16位的,因此每个段的大小是2^16 = 64K。

32位系统的寻址大小

32位系统的地址总线是32根,因此它最大的寻址空间是2^32 = 4G。