从上面我们可以看到,一条指令将根据不同的寻址格式对应于不同的机器码。设计CPU时,指定与每个机器代码相对应的指令长度。 8086采用可变长度指令,指令长度为1-6个字节,最后可以添加8位或16位偏移量或立即数。以下命令格式比以上两种格式更复杂。



这里没有必要,并且不能详细介绍CPU指令。只要知道指令的长度已在CPU指令中定义,就不会对读取存储单元感到困惑。有兴趣的人可以查看参考中的链接。
3. 1.3个存储数据
3. 1.3. 1存储器数据的操作
从上面我们可以知道,操作数可以是立即数,可以存储在寄存器中,也可以存储在内存中。对于第一个示例,指令已说明该操作是一个字节,因此CPU可以从下一个内存地址读取该操作,对于第二个示例,该操作数只是地址偏移,因此,当CPU获取此数据时之后,需要将其转换为实际的存储器地址,然后执行存储器访问以将数据读入寄存器。这是我们前面提到的问题,我们需要多少个存储单元来读取此数据?
[cpp]
MyClasscla; 008C3EC9leaecx,[cla] 008C3ECCcallMyClass :: MyClass(08C1050h)008C3ED1movdwordptr [ebp-4],0 cla.num5 = 500; 008C3ED8movdwordptr [ebp-6Ch],1F4h intb1 = MyClass :: num1,64h intb2 = MyClass :: num2; 008C3EE6movdwordptr [b2],0C8h intb3 = MyClass :: num3; 008C3EF0moveax,dwordptrds:[008C9008h] 008C3EF5movdwordptr [b3],eaxword intb4eclaptr movdwordptr [b3],eax word numB4 =,clapt。 ],eax intb5 = cla.num5; 008C3F04moveax,dwordptr [ebp-6Ch] 008C3F07movdwordptr [b5],eax
让我们看一段C ++代码和相应的汇编代码。操作非常简单。创建Myclass对象后,为成员变量分配值。分配是尝试使用Mov运算符。对于这些变量,我们具有赋值操作和值操作,那么如何确定要读取或写入的数据的大小?

[cpp]
cla.num5 = 500; 08C3ED8movdwordptr [ebp-6Ch],1F4h
首先让我们看一下赋值操作,然后将立即值存储在dword ptr [ebp-6Ch]的存储器中。 [ebp-6Ch]是num5的内存地址,前面的dword ptr表示这是一个双精度运算。还记得上面命令格式的第一个字节的W字段吗?在8086中,只能执行字节或字操作,但是现在CPU可以执行双字操作。
[cpp]
intb5 = cla.num5; 08C3F04moveax,dwordptr [ebp-6Ch]
类似地,当我们要从内存中读取数据时,我们还必须指定读取数据的操作类型,这也是一个双字操作。这样,可以从存储器中正确读取所需的长度。如此简单的赋值操作,即可了解您从未想过将其存储在内存中的方式以及如何阅读它。所有这些工作都是由后台的编译器和CPU为我们完成的。
3. 1.3. 2内存对齐
在上一部分中,我们了解了CPU如何正确读取不同大小的数据。在最后一部分,让我们看一下内存对齐的问题。对于大多数程序员来说,内存对齐应该是透明的。内存对齐是编译器的管辖范围。编译器将程序中的每个数据单元安排在适当的位置。
3. 1.3. 2.1对齐原因
我们从前面知道,计算机内存当前以字节为单位寻址,每个地址的内存大小为1字节。读取数据的大小与数据线有关。例如,如果数据线是8位,则一次读取一个字节,如果数据线是32位,则一次需要读取32个字节,以便一次获得更多数据,提高效率。否则,需要4个内存操作才能读取一个int变量。通常,存在以下两个内存访问条件:
CPU一次访问一次存储器所读取的数据和字长相同。某些CPU只能访问字长倍数的内存地址。
通常来说,对于第一种情况,当前存储器的一个单元为8位,并且执行位扩展以使其与字长和数据线数相同,从而使CPU可以获取最多的数据进程可以一次发送。而且我们在前面说过,当前的字节寻址可能是因为一个单元是8位的,所以存储操作读取的数据与字长相同。
因为它与存储器扩展有关(请参见1.2.1的图),所以每个DRAM位扩展芯片都使用相同的RAS。如果需要跨线访问,则需要两次通过RAS。因此,以32位CPU为例,该CPU只能寻址诸如0、4、8和16之类的地址。许多32位CPU禁止地址行中的低2位A0和A1,因此它们的地址必须是4的倍数,否则将发送错误。

如上图所示,当计算机数据线为32位时,一次读取4个地址范围的数据。当将int变量存储在地址0-3中时,CPU可以通过一次内存操作获得int变量的值。但是如果将int变量存储在地址1-4中怎么办?根据上面条件2的说明,此时,CPU需要执行两次内存访问。第一次访问时从0-4读取数据并仅保存1-3的内容,第二次访问时从4-7读取数据并仅保存4的数据,然后合并1-4。如下图所示:

因此,内存对齐不仅可以解决不同CPU的兼容性问题,而且可以减少内存访问次数并提高效率。当然,目前有关此原因的辩论很多,您可以看一下CSDN上的讨论:
3. 1.3. 2.2如何对齐内存
内存对齐方式具有对齐因子,通常为2、4、8、16字节。不同平台上的对齐方式不同,这主要由编译器确定。
有关特定规则,请参阅之前转让的文章,在这里我将不作详细介绍:
摘要
通过本文介绍的内存工作,我们已经从内存的硬件结构和存储方法过渡到了内存的寻址方法,然后讨论了字节寻址带来的问题和解决方案。这涉及CPU的指令格式和编译器的支持。最后,我们还从硬件和软件方面讨论了内存对齐问题。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/shoujiruanjian/article-342651-2.html
必须驱赶