首页 > 解决方案 > 如何使用 MIPS 加载字

问题描述

也许这个问题听起来很愚蠢:)但我有点困惑,有人可以解释为什么代码使用andlw来将单词从内存加载到寄存器,而0x1b430010已经在寄存器 $t1 中吗?luiori

lui $t1,0x1b43 
ori $t1,$t1,0x0010 
lui $t2,0xabbb 
ori $t2,$t2,0x8050

lw $t0,0($t1) 
srl $t0,$t0,6 
andi $t0,$t0,0x3

lw $t3,0($t2) 
andi $t3,$t3,0xff9f 
sll $t0,$t0,5 
or $t3,$t3,$t0 
sw $t3,0($t2)

标签: assemblymemorymips

解决方案


0x1b430010t1数字(32 位无符号整数)表示,表示内存地址。从直接在指令操作码中编码的部分立即值lui + ori构建这个常量(每个 MIPS 指令被编码为 32 位字,因此这些位的一部分形成 CPU 称为指令或指令的模式,其余的 16 位 IIRC,形成指令使用的立即数)。t1lui/oriluiori

lw $t0,0($t1)完全不同,它会首先使用(t1由常量“位移”+0修改-即括号前面的“0”)中的值作为内存地址,即CPU将地址总线设置为值0x1b430010,然后它将向内存芯片发出信号,它应该使用这些地址线并从该地址进行内存加载,在总线数据线上设置读取值。一旦内存芯片向 CPU 发出信号,表明数据已被读取并且数据线处于正确状态,CPU 就会将该状态存储为 的新值t0

简而言之,它会将地址 0x1b430010 的计算机内存中的字加载到寄存器t0中 - 但是存储在内存中的实际值是什么,这无法从您的简短片段中看出。

JFYI:MIPS 上的内存可按字节寻址(地址总线是 28 位还是 30 位宽?还是全 32 位?可能取决于特定的目标硬件 = 地址总线的宽度定义了您可以寻址的最大区域,即它限制了最大可能的内存在 CPU 地址空间中可用)。因此,通过设置特定地址,您可以读取/修改任何字节的内存(只要您有足够的权限,并且它不是只读内存,或者任何内存芯片未映射的空白空间)。

有一个小问题,加载/存储字指令要求(以使内存管理单元的硬件设计更简单)内存地址是“字对齐”的,即可被 4 整除(等于“底部两位为零”)。与读取半字类似,存储器地址必须是半字对齐的(可被 2 整除 = 底部地址位为零)。如果您正在使用未对齐的数据缓冲区,则必须按单个字节加载它(并从四个字节读取中组合字值),以避免由于使用lw错误的地址而导致未对齐的内存访问崩溃。

值 0x1b430010 可以被 4 整除(后四位为零,而两个就足够了,这实际上可以被 16 整除),并且该内存地址可能指向.data区域,因此lw从那里执行应该没有问题。


推荐阅读