我已经看到,在32位微控制器中,每个存储器地址仅保存8位数据;对于16位MC也是如此。对于32位数据,它使用4个地址的组合。为什么不能将地址直接保存为32位数据(将其变为32位或16位而不是8位)?
我已经看到,在32位微控制器中,每个存储器地址仅保存8位数据;对于16位MC也是如此。对于32位数据,它使用4个地址的组合。为什么不能将地址直接保存为32位数据(将其变为32位或16位而不是8位)?
Answers:
这实际上是一种设计选择,没有确凿的理由必须这样做。在过去,当大宗商品处理器以8位值运行时,映射更加一致地为1:1。为了在设计发展到现代的32位和64位处理器时保持一致性,即使数据总线增加了(实现成本之间的权衡也有所变化),仍然需要保留旧的字节寻址映射。某些32位MCU仍可能仅实现到某些存储器的16位数据总线,高端处理器将具有256位或更高版本,并且能够在单个存储器事务中加载多个核心寄存器。宽接口非常适合突发操作或流操作。
较小的可寻址内存大小不仅在处理代码中的字节值时有用,而且在需要读取或修改特定字节的内存中的结构(如以太网数据包)下也很有用。通常,这种操作需要能够执行较小的操作,但效率很高。
在某些情况下,有必要使用大端,小端或混合端数据进行操作。现在通常对此有专用的硬件支持,但是同样,在某些情况下,内存的字节寻址将使这种类型的操作更有效。
相当近期,寄存器中的地址位数一直是地址空间的限制因素,因此,在10到15年前,将2位浪费在地址字节而不是32位字上已经不是什么大问题(现在具有64位指针,通常可实现48或56位宽的字节地址)。入门级计算机科学教学仍然停留在刚发布的大型机时代,并且并不总是很清楚地解决演化方面的问题。在低容量,高成本的体系结构(从最一般的意义上讲)开始被更多的资源约束和更加以商品为中心的处理器设计所补充的时候,许多术语就开始使用(和定义)。
我还没有针对MCU专门回答,架构边界并不像您想象的那么清晰。即使是现代的底层MCU设计也很可能与多核服务器处理器集成在一起,或者仅存在于可扩展产品集中。无论哪种方式,一致的访问内存的方法都对需要编写或移植代码的最终用户有利。
我在逆向计算SE上问了一个有关寄存器大小的问题,以跟进该问题的历史方面。
int
和long
),x86也是,ARM也是如此。我认为大多数8位CPU都会使用它,因为对它的需求甚至比具有更广泛的法规的系统还要多。哦,超级猫是说早期处理器缺乏高效的ADC吗?
有一些DSP(例如TI C54x)无法寻址小于16位的值,而某些音频DSP使用24位。但是,几乎所有通用代码都使用8位值,因此所有通用CPU都支持它。
而且,仅因为用于存储器地址的较小单位是8位字节,并不意味着它将是总线上实际使用的最大单位。大多数CPU使用其本机字大小(16/32位)甚至更大的字长来寻址内存,并且在使用字节访问时,会自动从较大的字中提取字节。
例如,PCI总线始终使用32位事务,但是用于访问的字节使能信号必须更小。
基本答案是“因为这就是一个字节有多长”。拥有大量已建立该假设的代码,破坏该假设会导致各种问题。
在早期,还没有成熟的代码体。处理器经常会使用各种奇怪的架构,如其他答案所示。但是,到16位处理器问世时,已经有足够的代码来假设8位数据的可用性,否则将很难被采用。
每个地址只有一个32位字不会对存储速度造成任何不利影响。在32位系统上,低2地址位通常不进入内存。处理器通常将读取整个32位字并选择(或屏蔽掉)该字中需要的8位字节。只要您的地址空间可以存储足够的数据(对于32位系统,该数据限制为2 ^ 32字节),就无需担心。实际上,在许多16位/ 32位处理器上,使用字节值进行处理比使用本机字长值需要更长的时间-读取32位字并丢弃该字的一部分显然将需要额外的操作,与仅读取32位字相比。
相反,如果您有一个需要高效使用内存的系统,则需要能够访问各个字节。如果不能,则将耗尽内存。考虑到这一点,显然必须能够引用单个字节,因此将您的内存分块为字节是有意义的。
这就是所谓的具有字节可寻址存储器。通常这是一件好事,除非您用完了地址空间(例如,带有32位指针的4GB,而不是带有32位指针的16GB,其中每个地址都是一个单独的32位字)。
可寻址存储单元的大小本质上是您可以寻址多少内存与您将浪费多少内存之间的折衷方案。
可寻址内存。考虑一个32位CPU:如果您寻址字节,则可以寻址多达4GB的内存。如果您寻址单个位,则该数量将减少到512MB,而如果您寻址32位字,则将有16GB。(您的问题似乎暗示了后者)。
浪费的记忆。如果您有一个可以用X位表示的变量,并且只能为其分配N位的单位,则假定X> N,您平均将浪费(N-1)/ 2位。 ,您将以100%的效率使用内存(至少从寻址角度而言)。使用字节,每个变量将浪费3.5位(效率为56%),而使用32位字,则将浪费15.5位(效率为52%)。但是,情况变得更糟:如果您的大多数变量都很小(想想字符,布尔值,状态标志),那么如果可寻址单元太大,最终将浪费大部分内存。
例如,假设变量的平均大小为8位。
512*1024*1024*100%
= 5.4亿个变量。4096*1024*1024*56%
= 24亿个变量。与位寻址计算机相比,这几乎是后者的5倍!当然,您需要购买8倍以上的内存。可能已经在其他答案中说了各种方式。通常,在今天(但不一定在历史上),字节为8位。大多数情况下,我们使用“字节可寻址内存”来处理,这意味着我们可以用单个地址访问的最小对象是一个字节。但这并不意味着那是我们唯一可以解决的问题。根据平台的不同,单个地址可用于访问字节,半字/字(16位),字/双字(32位)等等64位。该指令基本上确定通常以那些单元8、16、32、64为单位的所需访问的大小(8、16、32、64等)。但这并不难,“取决于”。
同样,根据处理器和/或系统的设计,没有理由假定访问的大小是存储器的大小或最小访问的大小。随着需求越来越大,随着时间的推移,使用最小的尺寸来实际实现内存系统的意义越来越小,正在读取此信息的计算机可能会使用32位宽的数据总线或64位宽的数据总线进行所有访问,想要读取一个字节,它执行64位读取并扔掉其余的位,为什么它不花费任何额外的费用,将总线一直扩展到处理器核心附近,并且处理器选择正确的字节通道。花费更多的逻辑和/或时钟来使总线变窄或在字节通道中移动字节(有时会这样做)。因此微控制器中的内部ram可能是32位宽,例如,如果这对系统有意义的话。可能是16。是的,您确实要消耗更多的写入周期,因此必须沿该行的某个位置进行读取-修改-写入。想要在您的PC上写一个字节,某个地方发生64位读取,然后修改该64位中的某个字节,具体取决于您在那之后所做的操作,那64位可能只返回那8位,而返回dram与以前不同的是,缓存和代码使此规则不是通用规则。虽然写操作很容易忘记,但是内存控制器可以从处理器收集地址和数据,并允许处理器在最终执行写保存时钟时继续运行,也许还有更多时钟被读-修改-写操作(如果在缓存中),
甚至在今天,几乎所有这些都存在例外,在某些系统中可能存在可位寻址的指令或访问类型,在某些系统中地址以字节以外的单位表示。一个字节并不总是8位,也许某些系统仍在运行,这是正确的(我们以前使用八进制,而9位字节的18或36位字对于认为八进制, 8位对于十六进制思想家来说很有意义。
现在,您正在阅读的计算机上,即使该dram控制器的数据总线可能是32位或64位宽,实际的dram模块本身也可能由多个8位宽的部分组成,您可以很容易地看到它们。如果它的一侧有8或9个芯片,则可能是64位或72位(64位加上8位ECC)的总线,其宽度为8位。如果模块的一侧有4或5个芯片,但引脚数仍然很多,那么它要么是32位宽(现在不太可能),要么其中4个芯片是16位宽,如果有第5位,则可能为16位宽,仅使用8位,或者是8位宽的部分。也有32位宽的部分,但最常见的是8位宽。一种非常普遍的做法可以追溯到过去。
我们需要知道什么是微控制器。由于您提到的是32位,因此该部分中的内存很有可能是32位宽的(尽管我们无法告知详细信息),并且对它的所有访问都为32位宽。指令可能会确定程序要提供8位,16位和32位访问类型的内容,较小的写操作将需要在某处进行“读取-修改-写入”操作,而读取操作只是忽略了字节通道。闪存也是如此,尽管闪存写入是另一个主题。但是内部闪存很可能为32位宽,并且所有读取均以32位为单位。尽管这是另一回事,但外部闪存很可能是一个位宽(spi或i2c),尽管spi部件有时可以支持1、2或4位,但是一个味o引脚是最常见的。在内部,它们以字节为单位进行组织,可能是8位宽,也可能是16位或32位,或者谁知道,您移出并以字节为单位寻址它们。使用spi,您可以在单个事务中在一个字节和整个内存之间移出任意位置,具体取决于闪存部分的设计。
您也可以获得1位处理器!
数据宽度将跟随寄存器(累加器)的宽度。这通常是“处理器宽度”,而地址总线可能会有所不同(通常较宽),但根据用途,技术上可能会更窄。
8当然是二的幂。感谢8位的广泛使用以及技术的COST /能力,我们有历史要感谢。长期以来,一直裁定使用8位,部分原因是总线的宽度以及难以使寄存器(和RAM)的宽度超过8位(如果您的寄存器全部都是8位,则16位数据毫无意义)。8位相当漂亮,并且在十六进制中很有用。8位可以容纳您的字母,数字,图形和控制字符(ASCII)或0到255或+ -127可以通过分页轻松访问超过256字节的数据(8位地址总线),选择页面,然后选择字节,例如256页或256页可让您进入64K(65536)。通常情况下,页面零将是一个暂存器,因为它不需要设置页面,因此访问起来会更快。我的第一台计算机具有1k x 8bit的静态RAM!(动态RAM更便宜,但需要更多硬件来刷新它)。带有一些标志(c,nc,z,nz),可以左右加,减,旋转,您可以在8位计算机上执行一些相当复杂的数学运算。您不需要浮点算术单元!不是超级快,但是可行!许多早期的处理器可以单步执行,并与简单的静态RAM配合使用,调试起来非常容易。添加一些八进制缓冲区和早期的红色LED,您可以观察地址和数据总线的变化:)