我试图了解MIPS32 "ld“中的伪指令是如何工作的。我用火星模拟器来测试代码。当火星组装以下代码时
.data
LEN:
.word 12
.text
ld $6, LEN上面写的是基本代码
lui $1, 0x00001001
lw $6, 0x00000000($1)
lui $1, 0x00001001
lw $7, 0x00000004($1)lw指令似乎完成了所需的一切:它将特定地址0x00000000处的32位加载到寄存器$6中,并将以下32位加载到下面的寄存器中。
对我来说,吕氏的指令似乎是无用的。它甚至做了两次相同的事情,为什么?它被用作lw指令的偏移量,但是它必须有两倍相同的值,否则我们不能在内存地址上得到64位,而是两个“随机”32位?
有人能帮我找出我在想错的地方吗?可能和我想的完全不同..。
发布于 2018-05-18 10:19:52
LEN位于偏移量+0处的.data段内,这是地址0x0000100100000000 ( .data段的开始)。
因此,lw指令从地址0x0000100100000000+0和0x0000100100000000+4获取数据,这是从$1 + 0和$1 + 4中计算出来的。
lui将该值设置为$1。
两次,因为MARS汇编程序有点“愚蠢”,以固定的方式生成本地MIPS指令,而不是优化已经在$1寄存器中的值的特殊情况。有些伪指令甚至可以用更有效的方式实现,如果你检查所有这些指令,这并不是说火星正在产生最优的变体。
理论上,可以在不影响结果的情况下删除第二个lui,但是删除第一个lui会使lw访问完全不同的内存区域(因为$1寄存器包含不同的值)。
编辑:顺便说一下,您只为LEN保留了一个.word,所以第二个lw正在获取超出该词的值,通常在更复杂的源中,即bug/lw。
如果您要在已经使用的其他LEN内存之后保留.data,则在lui之后将ori放入$1完整地址,包括较低的16位。这是一个罕见的火星优化,删除ori的“加载地址”时,低16位都是零。
我想ld会看起来像lui, ori, lw, lui, ori, lw,也就是说会有更多的冗余。
https://stackoverflow.com/questions/50408935
复制相似问题