我试图理解MIPS32“ld”中的伪指令是如何工作的。我使用MARS Simulator来测试代码。 当MARS汇编以下代码时
.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位加载到以下寄存器中。
lui指令对我来说似乎毫无用处。它甚至两次做同样的事情,为什么? 它用作lw指令的偏移量,但它必须具有相同值的两倍,否则我们不能获得存储器地址的64位,而是两个“随机”32位?
任何人都可以帮助我,我的思维错误在哪里?它可能与我想的完全不同......
答案 0 :(得分:1)
LEN
位于.data
段内偏移+0,即地址0x0000100100000000
(.data
段的开头)。
因此,lw
说明从地址0x0000100100000000+0
和0x0000100100000000+4
获取数据,这些数据来自$1 + 0
和$1 + 4
。
lui
将该值设置为$1
。
两次,因为MARS汇编程序有点" dumb",以固定方式生成本机MIPS指令,而不是优化值已在$1
寄存器中的特殊情况。一些伪指令甚至可以更有效的方式实现,如果你要检查所有伪指令,它就不像MARS产生最佳的变体。
理论上,您可以删除此特定情况下的第二个lui
而不影响结果,但删除第一个lui
会使lw
访问完全不同的内存区域(如{ {1}}寄存器将包含不同的值。)
编辑:顺便说一句,你确实只为LEN保留了一个$1
,所以第二个.word
正在获取超出该单词的值,通常是更复杂的来源,这将是bug /监督。
如果您在已使用其他lw
内存之后保留LEN
,.data
后面会跟lui
进入ori
完整地址包括低16位。它是罕见的MARS优化之一,用于移除$1
的加载地址"当低16位全为零时。
我猜ori
看起来像ld
,即会有更多的冗余。