CPU的运行和内存的介绍

废话不多说,开搞!

一:总线

CPU的运行和内存的介绍_第1张图片

1.每个CPU芯片都有许多管脚,这些管脚和总线相连,CPU通过总线跟外部器件进行交互

2.什么是总线?

总线就是一根根导线的集合

3.总线的种类?

<1> 地址总线

<2> 数据总线

<3> 控制总线

4.微型计算机的基本结构


CPU的运行和内存的介绍_第2张图片

下面看一张图

CPU从内存的3号单元读取数据

CPU的运行和内存的介绍_第3张图片

地址总线

地址总线的宽度决定了CPU的寻址能力

8086CPU的地址总线宽度是20,所以寻址能力是1M

怎么计算的呢?

这里比较绕,我仔细说下 

假如我有两根地址总线,全部通电,它的值是11(二进制)也就是3,可以理解吗?

0(00)

1(01)

2(10)

3(11)

结合上图,那么它的寻址能力就是0 1 2 3,也就是4个字节

地址总线寻址能力的计量单位是Byte,公式是 寻址能力= 2 ^ n,n是地址总线的宽度

那20根是多少呢?

答案是:2 ^ 20 B == 2 ^10 KB == 1 MB

如果对上面的表达式看不懂的话,那么你就需要了解B KB MB 的换算了

小常识:10根地址总线寻址能力是1KB

20根地址总线寻址能力是1MB

30根地址总线寻址能力是1GB

32根地址总线寻址能力是4GB(2^2 GB)这也是为什么32位系统内存最大只支持4G,更大的利用不了

数据总线

数据总线的宽度决定了CPU的单次数据传输量,也就是数据传输速度(俗称数据吞吐量)

8086的数据总线的宽度是16,所以单次最大传递2个字节的数据

这又是怎么计算的呢?看图

CPU的运行和内存的介绍_第4张图片

1Byte = 8bit       

 一个字节等于8位(8个二进制位),也就是说,8根数据总线可以组成8个二进制位的数据,也就是一个字节的数据,而16根数据总线能组成2个字节的数据

控制总线

控制总线的宽度决定了CPU对其他器件的控制能力,能有多少种控制

接下来做个小计算:

1 . 一个CPU 的寻址能力为8KB,那么它的地址总线的宽度为____

2.  8080,8088,80286,80386 的地址总线宽度分别为16根,20根,24根,32根.那么他们的寻址能力分别为多少____KB, ____MB,____MB,____GB?

3. 8080,8088,8086,80286,80386 的数据总线宽度分别为8根,8根,16根,16根,32根.那么它们一次可以传输的数据为:____B,____B,____B,____B,____B,

4. 从内存中读取1024字节的数据,8086至少要读____次,80386至少要读取____次.

答案我会放在最下面

二:内存

CPU的运行和内存的介绍_第5张图片
CPU的运行和内存的介绍_第6张图片
CPU的运行和内存的介绍_第7张图片

这几张图了解下就可以了,我们主要在ARM(主存储器中玩),其他的地方我们操作不了。

0x00000~0x9FFFF:主存储器。可读可写

0xA0000~0xBFFFF:向显存中写入数据,这些数据会被显卡输出到显示器。可读可写

0xC0000~0xFFFFF:存储各种硬件、系统信息。只读

内存地址空间的大小受CPU的地址总线宽度的限制,8086的地址总线宽度为20,可以定位(2^20)个不同的内存单元(内存地址范围0x00000~0xFFFFF),所以8086的内存大小为1MB

同样的问题,怎么计算的?

首先0x代表16进制,每一位都是16进制

那么0xFFFFF == 16^5 == 2^4^5 == 2^20 == 1MB(F等于10进制的16)

如过看不懂上面的公式没关系,接着往下看

三:进制

目前主流有4种进制

<1> 二进制:由二个符号组成(0 1) 逢二进一

<2> 八进制:由八个符号组成(0 1 2 3 4 5 6 7)逢八进一

<3> 十进制:由十个符号组成(0 1 2 3 4 5 6 7 8 9)逢十进一

<4> 十六进制:由十六个符号组成(0 1 2 3 4 5 6 7 8 9 a b c d e f)逢十六进一

拓展:N进制:由N个符号组成 逢N进一

注意:我说的是符号!符号!也就是说,你可以用任意数字,字母来组成任意进制,这有什么好处呢?两个字,安全。能在进制上做手脚进行加密安全操作的是非常高端的,所以它有个更重要的作用,装逼!

比如:

我用0 1 3 4 2 5 6 7 8 9 组成一个10进制

那么1+1=?

是不是等于3

这时候别人知道这个“3”的是真的“3”吗?

这就是进制加密的好处,安全!

进制的运算

八进制的运算:

2 + 3 = __ , 2 * 3 = __ ,4 + 5 = __ ,4 * 5 = __.

277 + 333 = __ , 276 * 54 = __ , 237 - 54 = __ , 234 / 4 = __ .

大家可以算下。对照下面的运算表,这可是神器哦,跟我们小时候背的99乘法表一样

CPU的运行和内存的介绍_第8张图片

进制之间的比对

CPU的运行和内存的介绍_第9张图片

看懂了进制之间的变换吗?

二进制:从0 写到 1111

0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111 

这种二进制使用起来太麻烦,改成更简单一点的符号:

0 1 2 3 4 5 6 7 8 9 A B C D E F 这就是十六进制了

数据的宽度

数学上的数字,是没有大小限制的,可以无限的大。但在计算机中,由于受硬件的制约,数据都是有长度限制的(我们称为数据宽度),超过最多宽度的数据会被丢弃。

我写个例子,有兴趣的可以在Xcode上跑跑看

int max(){

          int max = 0x1FFFFFFFF

          return max;

}

printf("%x\n",max());

看看最后输出的max()函数值是多少,是不是我们赋值的值?

计算机中常见的数据宽度

位(Bit): 1个位就是1个二进制位.0或者1

字节(Byte): 1个字节由8个Bit组成(8位).内存中的最小单元Byte.

字(Word): 1个字由2个字节组成(16位),这2个字节分别称为高字节和低字节.

双字(Doubleword): 1个双字由两个字组成(32位)

计算机中的存储数据它会分为有符号和无符号数。

CPU的运行和内存的介绍_第10张图片
CPU的运行和内存的介绍_第11张图片


四:寄存器

CPU内部部件之间由总线连接

CPU的运行和内存的介绍_第12张图片

对我们程序员来说,CPU中最主要部件是寄存器,可以通过改变寄存器的内容来实现对CPU的控制。它的作用就是进行数据的临时存储。

CPU的运算速度是非常快的,为了性能CPU在内部开辟一小块临时的存储区域,并在进行运算时陷阱数据从内存复制到这一小块临时存储区域中,运算时就在这一小块临时存储区域内进行,我们统称这一小块临时存储区域为寄存器

不同的CPU,寄存器的个数、结构是不同的

另外,还有一个概念--高速缓存

iPhoneX上搭载的ARM处理器A11它的一级高速缓存的容量时64KB,2级高速缓存的容量时8MB

CPU每执行一条指令前都需要从内存中将指令读取到CPU内并执行。而寄存器的运算速度相比内存读写要快得多,为了性能,CPU还集成了一个高速缓存-存储区域。当程序运行时,先将要执行的指令代码以及数据复制到高速缓存中去(这一步是由操作系统完成的)。而CPU直接从高速缓存中依次读取指令来执行。

内存地址与高速缓存之间有个一一对应的映射关系,当我们读取指令的时候,pc寄存器指向谁,我们就读谁,当我们pc的地址给了CPU,它其实我们是去高速缓存中寻找,因为它们是映射关系

还有一个问题:当高速缓存中8MB的地址全部用完了怎么办,pc所指向的地址在高速缓存中找不到了怎么办?

不要急,因为这时候会重新从内存中cpoy一份到高速缓存中去,它中间其实有个高速缓存的这个过程

那么为什么不将整个内存条都做成高速缓存区域呢?只开辟出8MB?

越是高效,越是精良的硬件,它的做工要求就更高,成本就更高!

1.通用寄存器

ARM64拥有31个64位(每个寄存器是64位的,CPU是64位的)的通用寄存器x0到x30,这些寄存器通常用来存放一般性的数据,成为通用寄存器(有时候也有特定用途)

CPU的运行和内存的介绍_第13张图片

咦?不是说是x0到x30吗?为什么只有到x28?

注意:fp就是x29,lr就是x30

并且:sp我们俗称它是x31,但是它不属于通用寄存器


CPU的运行和内存的介绍_第14张图片

w0到w28是32位的,但是64位的CPU可以向下兼容32位,所以只使用64位寄存器的低32位,如w0就是x0的低32位

这些寄存器是怎么看的呢,打开Xcode,运行程序,大哥断点,然后将这个选为all(原来是auto)

CPU的运行和内存的介绍_第15张图片


通常CPU会先讲内存中的数据存储到通用寄存器中,然后再对通用寄存器中的数据进行运算

举个例子:

假设内存中有快红色空间的值是3,现在想把它的值加1,并将结果存储到蓝色内存空间

CPU的运行和内存的介绍_第16张图片

<1> CPU首先会会将红色内存空间的值放到x0寄存器中:

mov x0,红色内存空间   (伪代码)

mov 数据传送指令(相当于赋值)

上面伪代码的意思就是将红色空间的值移动到x0中

<2> 让后让x0寄存器与1相加:add x0,1 (伪代码)

add 相加指令

意思是 将x0的值加1 再存到x0中

<3> 最后将值赋值给内存空间:mov 蓝色内存空间,x0 (伪代码)

这句代码的意思就不说了,自己想

注意:我们所有运算都不能直接拿内存中的数据进行直接计算,必须要把值放到寄存器中进行运算!运算结束后再写进内存中。

2.pc寄存器(program counter)

重点,很有意思

<1> 为指令指针寄存器,它指示CPU当前要读取指令的地址

<2> 在内存或者磁盘上,指令和数据没有任何区别,都是二进制信息

<3> CPU在工作的时候把有的的信息看作指令,有的信息看做数据,为同样的信息赋予了不同的意义

例:

比如 1110 0000 0000 0011 0000 1000 1010 1010 

可以当作数据 0xE003008AA

也可以当作指令 mov x0,x8

<4> CPU根据什么将内存的信息看作指令呢?

CPU将pc指向的内存单元的内容看作指令

如果内存中的某段内容曾被CPU执行过,那么它所在的内存单元必然被pc指向过

接下来演示一下这个有意思的pc

CPU的运行和内存的介绍_第17张图片

我们现在断点在0x102b58bac这个地址上对吧!

ni是单行执行下一步的操作

之前有说过通过改变寄存器的内容来实现对CPU的控制

那么现在就来改一下

当前这个寄存器的内容地址是0x102b58bac

现在我将它改掉

CPU的运行和内存的介绍_第18张图片

这句代码 register write pc 0x102b58b94  

它的意思是将当前pc寄存器的地址改为0x102b58b94

当我们进行ni操作的时候

咦?

它并没有执行到下一步地址为0x102b58bb0的操作,而是进到了我们改动的内存地址下,是不是‘哦莫西罗伊’

3.数据地址寄存器

数据地址寄存器通常用来做数据计算的临时存储、累加、计数、地址保存等功能。定义这些寄存器的作用主要用于在CPU指令中保存操作数,在CPU中当做一些常规变量来使用。

ARM64(CPU)

64位:X0-X30,XZR(零寄存器)

32位:W0-W30,WZR(零寄存器)

注意:在Inter架构CPU中还有中特殊的寄存器-段寄存器:CS、DS、SS、ES,主要是用来保存这些段的基地址。但是ARM中是没有的。

4.浮点和向量寄存器

因为浮点数的存储以及运算的特殊性,CPU中专门提供浮点数寄存器来处理浮点数

<1>浮点数寄存器:

64位:D0-D31

32位:S0-S31

目前的CPU它支持向量运算(向量运算在图形处理相关的领域用的非常多)。喂了支持向量计算,系统也提供了众多的向量寄存器。

<2>向量寄存器:

128位:V0-V31

5.SP和FP寄存器

<1> sp寄存器在任意时刻会保存我们栈顶的地址

<2> fp寄存器也叫做x29寄存器,它属于通用寄存器,但在某些时刻我们利用它保存栈底的地址

<3> 另外:ARM64开始,取消了32位的LDM,STM,PUSH,POP指令,取而代之的是ldr\ldp str\stp

ldr\ldp str\stp 这些都是内存读写指令

注意:读/写操作都是数据往高地址中进行读/写

str(store register)指令

将数据从寄存器中读出来,存到内存中

ldr(load register)指令

将数据从内存中读出来,存到寄存器中

ldp和stp是str和ldr的两个变种指令

<4> ARM64里面,对栈的操作是16字节对齐的

延伸:什么是栈?

栈:一种遵循后入先出法(LIFO)的特殊访问方式的存储空间

什么叫后入先出法?

Last In Out First.   最后一个进去的,第一个出来

有个举烂的例子:

将羽毛球放到羽毛球筒中,最后一个放进去的羽毛球肯定是第一个拿出来

CPU的运行和内存的介绍_第19张图片


5.bl指令

<1> CPU从何处执行指令是pc中的内容决定的,我们可以通过改变pc的内容来控制CPU执行目标指令

<2> ARM64提供了一个mov指令(传送指令),可以用来修改大部分寄存器的值

如:

mov x0,#10、mov x1,#20

这里解释下#号的含义

#后面跟数字,它有个概念,叫“立即数”

什么事立即数?

就是它代表的是个数字,而不是符号!

听懂没,之前说进制的时候,说0 1 2…… 这些是符号

当前面加上#号后,它就代表数字了

所以mov x0,#10这条指令的意思就是:把10这个数放到x0中

<3> but,mov指令不能用于设置pc的值,ARM64没有提供这样的功能

如:mov pc,#0x102b58bb0 这条汇编指令是错误的,不能这么写

<4> ARM64提供了另外的指令来修改PC的值,这些指令统称为转移指令,最简单的就是bl指令


计算题答案

1. 之前有说10根地址总线的寻址能力是1KB,那么8KB == 8 * 1 KB == 2^3 *1KB == 2^3 * 2^10 B = 2^13 B

所以地址总线的宽度是13

2.同样的计算方式

<1>   a:  2^16B == (2^10B)^6 KB == 2^6 KB == 64KB

<1>   b: 2^20B == 2^10 KB == 1MB

<1>   c: 2^24B == b^4 MB ==16MB

<1>   d:2^32B == 2^2 GB = 4GB(上面有提到30根地址总线的寻址能力是1GB)

你可能感兴趣的:(CPU的运行和内存的介绍)