深入C语言—前奏—控制访问内存的数据宽度
在前面的一篇文章中,我们知道了,我们的内存分为寄存器和内存,寄存器的数据宽度设计时就固定了,所以我们按照它的数据长度对它读写就可以了,但是内存中每个字节的内存空间都有一个编号,我们的数据大于八位就需要不止一块内存了,所以我们对内存读写时,需要制定我们要操作的内存的数据宽度,这在后面的汇编指令中也有体现,就是说我们访问或写一块内存时,必须指定我们操作的数据宽度。接下来我们要讲的就是怎么操作内存的数据宽度。
现在我们的电脑都是32位,64位。但是PC机同一款CPU,它在升级的同时都是向下兼容的,就是说之前8位或者16位的CPU指令都是适用的,也是因为技术都是在原来的基础上演变来的,原理都是一样的。为了方面讲解,我们选一个16位的CPU讲解,因为我们内存的最小宽度是byte,8位的CPU不能很好的解释,这里我就选用我在微机原理课上的8086的系统来讲一讲。
先晒一张图,我们看一看操作系统内部逻辑上的储存结构。
8086是一个16位的CPU,它的寄存器也都是16位的,数据总线也是16位,而地址总线是20位,那么它的寻址能力就是2e20byte,就是1MB,从图上知道,这1MB内存单元是两块独立的内存,偶数地址的统称为偶数库,连接了数据总线的低八位,奇数地址的统称为奇数库,连接了数据总线的高八位。其中内存上的SEL上面一个横线学过数电我们都知道这是个使能端,低电平有效,就是说当BHE是低电平的时候我们的储存体才可以用,才可以写或者读。我们从图上可以看到,偶数库的使能接到了地址总线的A0,奇数库的是接在了BHE上。这么做是有意义的,解释一下,当操作一个偶数的内存块(字节)时,它的地址肯定是偶数,所以A0必定为1,所以直接用A0来控制。而BHE是操作系统控制的,当你需要访问奇数库的时候操作系统自动给BHE低电平。
接下来我们看几种情况。
1同时访问两个储存体
2只访问偶储存体
3只访问奇储存体
第一种情况比较复杂,在计算机中我们的内存是又内存对齐的概念的,大概可以理解为你所操作的数据的数据宽度在内存中的位置可以整除数据宽度,我举一个例子,比如说我们访问一个字的内存空间,字是2BYTE,所以数据的地址(低字节地址为改字的地址)必须是偶数。所以说一个字的低字节在偶数库,高字节在奇数库,且连续就说是规则存放的,反之数据的低字节在奇数库,高字节在偶数库,且也是连续的,就是非规则的存放。我们来看看两者的区别。
先说规则对齐的一个字数据,当我们读取时,CPU接收到我们要操作一个字长度的数据并且是规则存放到,这时BHE就变成低电平,规则存放,所以A0是0,这时我们就使能了两个储存体,一个总线周期,我们就通过数据总线读到了一个字的内容。
再说一下非规则的一个字的数据,我们读取时,CPU接收到指令判断一下是非规则的,所以CPU首先把BHE给电平,这时A0是1,因为都是低字节作字的地址。这时我们在一个总线周期只能取走奇数库的内容,取走的是低8位,储存在数据总线的高8位,同时忽略了低8位的数据。第二个周期,CPU把地址加1,访问到了偶数库的内存,此时把数据的高八位存放到了数据总线的低八位,忽略了数据总线高8位的内容,此时高低8位是相反的,还需要颠倒。(非规则数据两次数据怎么变成正常的数据书中没提到,我们可以理解为是移位然后做了一下逻辑运算得到了正常数据)。
理解了上述的两种情况那么2和3就好理解了,每次只使能一个储存体,忽略数据总线中没有使能的储存体数据。
我们理解了16位的CPU怎么控制数据宽度的思想,可以迁移到32位和64位,就是内存是分成了独立的几块,每块有使能端,我们需要多长的数据宽度,规则存放的就一次使能几个内存,我们通过数据总线直接取走,不规则的我们取两次。
比较晦涩难懂,不懂的可以多读几遍。