Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 处理器如何读取内存?_C_Memory_Cpu Architecture_Ram_Memory Alignment - Fatal编程技术网

C 处理器如何读取内存?

C 处理器如何读取内存?,c,memory,cpu-architecture,ram,memory-alignment,C,Memory,Cpu Architecture,Ram,Memory Alignment,我试图学习计算机是如何安排和处理内存的,但我不理解对齐的概念 例如,在32位体系结构中,如果短(2个字节)完全位于单个32位字中,即使它们不位于偶数地址,为什么我们说短(2个字节)未对齐 因为如果处理器读取32位乘以32位,并且一个字符位于地址x0,那么后面紧跟着一个短字符(地址x01和x02),然后紧跟着另一个字符(x03)。突然之间就没有问题了,因为处理器读取4个字节,所以不会有剪切数据 因此短是对齐的,不是吗?这个问题表明处理器有32根线连接到总线,用于数据,可能还有其他线用于控制。当它需

我试图学习计算机是如何安排和处理内存的,但我不理解对齐的概念

例如,在32位体系结构中,如果短(2个字节)完全位于单个32位字中,即使它们不位于偶数地址,为什么我们说短(2个字节)未对齐

因为如果处理器读取32位乘以32位,并且一个字符位于地址x0,那么后面紧跟着一个短字符(地址x01和x02),然后紧跟着另一个字符(x03)。突然之间就没有问题了,因为处理器读取4个字节,所以不会有剪切数据


因此
是对齐的,不是吗?

这个问题表明处理器有32根线连接到总线,用于数据,可能还有其他线用于控制。当它需要从内存中读取数据时,它会在总线上放置一个地址,请求从内存中读取数据,等待数据,然后通过这32条线路读取数据

在典型的处理器设计中,这32条线连接到某个临时内部寄存器,该寄存器本身也连接到其他寄存器。很容易将这32位作为一个块移动,每个位都在自己的线路上

如果我们想移动32中的一些位,我们需要移动它们。这可以通过各种硬件实现,比如我们将位放入的移位单元,请求一定量的移位,并从中读取结果。在内部,换档装置将有各种连接和开关来完成其工作

通常,这种移位单元将能够将八位从四个位置(从位0、8、16或24开始)中的任何一个移动到基本位置(0)。这样,诸如“加载字节”之类的指令可以通过从内存中读取32位(因为它只以32位块的形式出现)然后使用移位单元获得所需的字节来实现。该移位单元可能没有将任意一组位(例如,从7、13或22开始)移动到基位置所需的导线和开关。这将需要更多的电线和开关

处理器还需要能够执行加载16位指令。为此,移位单元将能够将16位从位置0或16移动到位置0。当然,工程师们也可以将16位从位置8移动到位置0。但这需要更多的电线和开关,这需要钱、硅和能源。在许多处理器中,做出了这样一个决定:这笔费用不值得,因此没有实现该功能


因此,在加载过程中,硬件无法将数据从字节1和2移动到字节0和1。(处理器中可能有其他移位器,例如用于执行移位指令的通用逻辑单元中的移位器,但这些移位器通常是分开的,并通过指令调度和控制机制访问。它们不在从内存加载时使用的组件行中。)

对齐是一个定义。假设8位字节,且内存可寻址。8位字节(无符号字符)不能未对齐。要对齐的16位半字必须具有lsbit零。32位字,低位两位零,64位双字三位零,依此类推。因此,如果您的16位无符号short位于奇数地址上,则它是未对齐的

“32位系统”并不意味着32位总线,总线宽度不一定与处理器寄存器的大小或指令大小或任何东西匹配。没有理由做出这样的假设。尽管如此,如果您谈论的是MIPS或ARM,那么总线很可能是32位或64位的32位寄存器处理器,64位或128位的64位处理器,可能是64位。但是x86有8位指令,带有8、16、32、64位寄存器和可变长度指令。当您将其可能占用的字节相加时,无法对其大小进行分类。它是一个8位处理器,具有8位指令32或64,因为它的寄存器大小更大,还是128256512等,因为它的总线大小

你提到32岁,我们还是坚持吧。我想遍历一个字节数组,我想进行写操作。我有一个32位宽的数据总线,这是你们今天看到的典型设计之一。假设另一端是缓存,它由32位宽的SRAM构建,以与处理器端总线对齐,我们不会担心dram在另一端是如何实现的。因此,您可能会有一个写数据总线、一个读数据总线,或者有单独的写地址和读地址,或者有一个地址总线来指示读/写事务

就总线而言,所有事务都是32位的,您不一定期望未使用的字节通道浮动,z状态,您期望它们对于总线上的有效时钟为高或低(在有效时钟周期之间,确保总线可能会变为高-z)

读事务通常是,让我们假设是与总线宽度对齐的地址,因此是32位对齐的地址(在总线上或在远端)。在读取时通常没有字节通道启用的概念,处理器在内部隔离感兴趣的字节并丢弃其他字节。有些在地址总线上有一个有意义的长度字段。加上缓存控制信号和其他信号

对齐的32位读取将是地址0x1000或0x1004长度为0(n-1),地址总线使用唯一的事务id进行握手,稍后在读取数据总线上理想情况下,单个时钟周期将包含具有该id的32位数据,处理器看到并完成事务(可能是更多的握手)然后提取所有4个字节,并按照指令中的要求处理它们

在32位边界上对齐的64位访问将有一个长度,一个地址总线握手,两个时钟周期,读取数据总线上的数据。0x1000或0x1002处的16位对齐事务将读取0x1000,处理器将丢弃通道0和1或通道2和3,一些总线设计将对齐