6.4 访存指令的控制信号

本文深入解析了单周期处理器中的访存指令——load与store的控制信号生成过程,阐述了如何通过设置不同的控制信号来实现寄存器与存储器间的数据传输。

计算机组成

6 单周期处理器

6.4 访存指令的控制信号

Screen Shot 2018-09-29 at 7.53.33 pm

对于MIPS这样的指令系统来说,其运算指令是不能直接访问存储器的,因此,我们还需要设计单独的访存指令,用来完成寄存器和存储器之间的数据传输。在这一节,我们就来看一看这一类访存指令是如何生成控制信号的。

Screen Shot 2018-09-29 at 7.53.42 pm

对于我们要实现的这个处理器,访存指令都是属于 I 型指令,一条是load,一条是store。我们分别来进行分析。

Screen Shot 2018-09-29 at 7.53.51 pm

对于load指令。首先,当然也是取指;然后根据运算出的地址,访问数据存储器,并将读出的内容写入到 rt 指定的寄存器中;最后,是更新PC寄存器。 那第一步和第三步,与运算指令都是一样的。在这里我们就只讲解第二步相关的操作。

Screen Shot 2018-09-29 at 7.54.00 pm

这是我们的数据通路,如果当前IFU 取回的是一条load指令,那这些控制信号将会如何设置呢? 首先,下一条指令的地址应该还是采用PC+4的方式。然后我们来看寄存器堆这一边,rs 和 rt 都是固定连接到了指令编码的对应位域,因此,busA 和 busB 这两组信号上,分别是由rs和rt所指定的寄存器的内容。

Screen Shot 2018-09-29 at 7.54.08 pm

但我们要注意,对于这条指令,我们想要运算的是rs寄存器中的内容和立即数的符号扩展进行加法。因此,对于ALU的第二个操作数的来源,我们应该通过这个多选器(ALUSrc),选择通道1,并且设置扩展部件为符号扩展的功能(ExtOp=“sign”)。这样,指令位域中的16位立即数就会经过符号扩展,最终连接到了ALU的第二个输入端,而我们发送到ALU的控制信号,则是要设置为加法运算(ALUCtr=“ADD”)。 这样,ALU就会完成了访存地址的运算,并将地址信号送到数据存储器的地址输入端(Adr)。同时我们也要注意,busB上的信号也会被连接到数据存储器(Data Memory)的数据输入端(Data In),虽然我们并不需要它,但是这根信号仍然会把 rt 所指定的寄存器的内容送过来。 所以我们需要设置数据存储器的写使能信号(MemWr)把它设为0,保证了数据存储器的内容不会发生改变。 然后我们来看最后这个多选器,这个多选器的两个输入,一个是ALU的运算结果,就是访存的地址;另一个是从数据存储器当中,读出的数据。 那么对于这条指令,我们显然希望把后者送到寄存器堆当中去。因此,对于这个多选器来说,我们需要设置它的选择信号为1(MemtoReg=1), 这样我们就可以把数据存储器的输出传送到寄存器堆的数据输入端(busW),
而且因为我们要写入 rt 所指定的寄存器,所以,我们需要设置寄存器堆的写使能信号为有效(RegWr=1),并把写入寄存器编号的来源设置为rt(RegDst=0)。

Screen Shot 2018-09-29 at 7.54.17 pm

这样,在下一个时钟上升沿到来的时候,数据存储器输出的内容就会被写入到rt所指定的寄存器当中去了,而且在同样的这个时钟上升沿,PC寄存器的内容也会被更新为PC+4,这就是load指令所完成的操作。

Screen Shot 2018-09-29 at 7.54.28 pm

然后我们来看store指令,store指令也分为三步,同样,我们也只看其中的第二步。

Screen Shot 2018-09-29 at 7.54.37 pm

对于store指令,我们也需要将rs寄存器中的内容和立即数 的符号扩展进行加法运算,并以此作为地址访问数据存储器, 不过不是读出,而是写入。因此,对应到数据通路上,我们就直接标出了对于store指令,有效的这些信号。 那这些控制信号又该如何设置呢? 那你不妨自己想一想,然后我们一起快速地浏览一遍。 对于IFU,我们要选择下一条指令的地址, 仍然是PC+4(nPC_sel="+4"),我们要选择ALU的数据的输入,现在我们选的是立即数的符号扩展(ExtOp=“sign”; ALUSrc=1), 而对于ALU,我们依然要选择加法的运算类型(ALUCtr=“ADD”)。ALU的运算结果,依然是一个地址,会被送到数据存储器上。但是与之前不同的是,这条指令要完成向数据存储器的写操作。所以,在这里我们会把数据存储器的写使能信号置为有效(MemWr=1)。 这样,在下一个时钟的上升沿,数据存储器就会采样其数据输入端(Data In)的信号,但这个输入端的信号又是什么呢?我们可以看一看,实际上它连到了busB,而 busB是由rt这个信号所指定的寄存器中的内容。 因此,在下一个时钟上升沿到来的时候,数据存储器会根据ALU算出来的地址(Adr),选中对应的存储单元,并采样这个来自rt寄存器当中的内容,将它存到对应的存储单元中去。 对于store指令来说,它就完成了它所需要做的主体的操作,但是对于这个数据通路,我们必须要把剩下的控制信号都设置完整。

我们来看后面这个多选器,因为对store指令,我们不需要改写寄存器堆的内容, 所以无论选择哪个通路,都是没有意义的。 在这里,我们就设置这个控制信号,可以是0,也可以是1,就用x来进行标记(MemtoReg=x)。 那这样,这个多选器总会选出一组信号,最终送到寄存器堆的数据输入端。不过没有关系,我们只需要设置寄存器堆的写使能信号为无效(RegWr=0),在时钟上升沿到来的时候,寄存器堆的内容就不会发生改变。也正因为如此,这个要写入的寄存器编号,无论设成rb还是rt(RegDst=x)也都是可以的。

这就是对于store指令的控制信号的设置方法。

Screen Shot 2018-09-29 at 7.54.46 pm

现在,我们已经掌握了访存指令是如何生成控制信号的,再加上之前的运算指令,我们就可以编写程序,让计算机完成相应的任务了。不过,如果我们想编写出功能更为强大的程序,那只有运算指令和访存指令是不够的,我们还需要改变程序流向的分支指令。这一点,我们在下一节继续分析。

转载于:https://www.cnblogs.com/kafffka/p/9735287.html

<think>我们正在讨论计算机体系结构中的访存指令访存指令(MemoryAccessInstructions)是处理器指令集中用于在寄存器和内存之间传输数据的指令。根据引用[3],寻址方式包括寄存器寻址、立即数寻址、位移量寻址、直接寻址等。这里我们关注的是与内存访问相关的指令。常见的访存指令可以分为两大类:加载(Load)指令和存储(Store)指令。加载指令将数据从内存读取到寄存器,存储指令将数据从寄存器写入内存。此外,还有一些特殊的访存指令,如原子操作指令。下面我们将详细说明:###**1.加载指令(LoadInstructions)**加载指令用于从内存中读取数据到寄存器。根据寻址方式和数据大小的不同,有多种变体:-**基本加载指令**:如MIPS中的`lw`(loadword)指令,用于加载一个字(32位)的数据。```mipslw$t0,0($s1)#将内存地址为$s1+0处的32位数据加载到$t0```-**加载半字(16位)**:如`lh`(loadhalfword,有符号扩展)和`lhu`(无符号扩展)。-**加载字节(8位)**:如`lb`(有符号扩展)和`lbu`(无符号扩展)。-**加载双字(64位)**:在64位架构中,如`ld`(loaddoubleword)。-**其他**:如加载立即数(但通常不视为访存指令)或加载地址(如`la`,但实际上是伪指令,由加载地址的指令组合而成)。在x86架构中,类似的指令有`mov`(如`moveax,[ebx]`)。###**2.存储指令(StoreInstructions)**存储指令用于将寄存器中的数据写入内存:-**基本存储指令**:如MIPS中的`sw`(storeword)。```mipssw$t0,4($s1)#将$t0中的数据存储到内存地址$s1+4处```-**存储半字**:如`sh`(storehalfword)。-**存储字节**:如`sb`(storebyte)。-**存储双字**:如`sd`(storedoubleword)。在x86架构中,使用`mov`指令进行存储,如`mov[eax],ebx`。###**3.原子访存指令**现代体系结构还提供原子操作指令,用于多线程同步:-**原子交换**:如x86的`xchg`指令。-**原子加/减**:如`lockadd`。-**比较并交换**:如`cmpxchg`。-**加载链接/条件存储(LL/SC)**:在RISC架构中,如MIPS的`ll`和`sc`指令,用于实现原子操作。```mipsll$t0,0($s1)#加载链接:从$s1+0加载到$t0,并标记内存区域#...修改$t0...sc$t0,0($s1)#条件存储:如果内存区域未被修改,则存储$t0到$s1+0```###**4.其他访存指令**-**预取指令**:用于提示处理器将要访问某内存区域,以便提前缓存,如x86的`prefetch0`。-**内存屏障指令**:用于保证内存访问顺序,如`fence`指令。###**5.不同架构的差异**-**RISC架构**:通常只有明确的加载/存储指令才能访问内存,运算指令的操作数只能是寄存器(即加载-存储架构)[^2]。-**CISC架构**:如x86,允许内存操作数直接参与运算(如`addeax,[ebx]`),但实际上处理器会将其分解为微操作。###**访存指令的关键属性**-**寻址方式**:如基址寻址(如`lw$t0,offset($rs)`)、基址变址寻址(如x86中的`moveax,[ebx+ecx*4]`)。-**对齐要求**:许多体系结构要求访存指令的地址必须对齐(如字加载时地址必须是4的倍数),否则会触发异常。-**内存序**:在多核环境下,访存指令的执行顺序可能需要内存屏障指令来控制[^3]。---###示例代码下面展示MIPS和x86中的基本访存操作:####MIPS示例```mips#加载字:从$s1+8加载到$t1lw$t1,8($s1)#存储字:将$t2存入$s2+16sw$t2,16($s2)```####x86示例```asm;将[esi]处的32位数据加载到eaxmoveax,[esi];将ebx中的数据存储到[edi+8]mov[edi+8],ebx```---###相关问题1.**在访存指令中,大端序和小端序有什么区别?请举例说明。**2.**如果访存地址未对齐会发生什么?在哪些体系结构中对齐是强制的?**3.**原子访存指令在并发编程中的作用是什么?**4.**RISC-V架构中的访存指令与MIPS有何不同?**以上问题可帮助深入理解访存指令的设计和实际应用。</think> ### 访存指令详解 访存指令是计算机体系结构中用于在寄存器与存储器之间传输数据的核心指令类型。根据引用[1]-[4]的体系结构原理,这些指令可分类如下(按功能和使用层级): --- #### **1. 基础加载/存储指令** **功能**:实现寄存器↔内存的数据传输 - **加载指令**:从内存读取数据到寄存器 - `ldr` (ARM):加载32位数据 ```armasm ldr r0, [r1] ; 将r1指向的内存数据加载到r0 ``` - `lw` (MIPS/RISC-V):加载字数据 ```mips lw $t0, 4($s1) ; $t0 = memory[$s1+4] ``` - `mov` (x86):支持内存到寄存器传输 ```x86asm mov eax, [ebx] ; eax = memory[ebx] ``` - *原理*:地址计算采用**基址+偏移量**模式,对齐要求见引用[3] - **存储指令**:从寄存器写入数据到内存 - `str` (ARM):存储32位数据 - `sw` (MIPS/RISC-V):存储字数据 ```mips sw $t2, 8($s3) ; memory[$s3+8] = $t2 ``` - *数据宽度支持*:字节(`sb`/`strb`)、半字(`sh`)、字(`sw`/`str`)、双字(`sd`) --- #### **2. 批量数据传输指令** **功能**:高效处理连续内存块(如数组操作) - `ldm`/`stm` (ARM):多寄存器加载/存储 ```armasm stmia r1!, {r0-r3} ; 将r0-r3存入r1指向的内存,r1地址自增 ``` - `lw/sw` 循环 (RISC/MIPS):结合`addi`实现块传输 ```mips loop: lw $t0, 0($s1) sw $t0, 0($s2) addi $s1, $s1, 4 ; 地址递增 bne $s1, $s3, loop ``` --- #### **3. 原子访存指令** **功能**:保证多核/多线程下的内存操作原子性 - `lr.w`/`sc.w` (RISC-V):加载保留+条件存储 ```riscv retry: lr.w t0, (a0) ; 加载并标记内存地址 addi t0, t0, 1 ; 原子加1 sc.w t1, t0, (a0) ; 若地址未修改则存储 bnez t1, retry ; 失败重试 ``` - `xchg` (x86):原子交换 - *应用场景*:锁实现、计数器同步(引用[3]系统操作) --- #### **4. 内存屏障指令** **功能**:控制内存访问顺序(避免乱序执行问题) - `fence` (RISC-V):全内存屏障 - `dmb` (ARM):数据内存屏障 - *必要性*:保证多核一致性(见冯·诺依曼体系存储程序原理[^4]) --- #### **5. 预取指令** **功能**:减少内存延迟(缓存预加载) - `prefetch` (x86/ARM):提示处理器预取数据 ```x86asm prefetcht0 [eax] ; 将数据预取到L1缓存 ``` - *优化原理*:隐藏内存访问延迟[^1] --- ### 关键技术特性 1. **寻址模式**(引用[3]): - 直接寻址:`lw $t0, 0x1000` - 基址寻址:`lw $t0, 4($s1)` - 变址寻址:`ldr r0, [r1, r2, LSL #2]` (ARM) $$ \text{地址} = \text{Base} + \text{Index} \times \text{Scale} $$ 2. **端序支持**: - 大端序(网络设备):高位字节在低地址 - 小端序(x86/ARM):低位字节在低地址 3. **对齐约束**: - RISC架构要求严格对齐(如MIPS字访问需4字节对齐) - x86支持非对齐访问(性能损失) --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值