Assembly MIPS组件,lui 0x1001
我有一个作业,其中我必须解释关于以下MIPS汇编代码的一些事情:Assembly MIPS组件,lui 0x1001,assembly,mips,mars-simulator,Assembly,Mips,Mars Simulator,我有一个作业,其中我必须解释关于以下MIPS汇编代码的一些事情: .data x: .word 4711 y: .word 10 z: .word 0x0A91 e: .word 0 .text .globl main main: lw $2, x lw $3, y lw $4, z add $2, $2, $3 sub $3, $2, $4 sw $3, e li $2, 10 syscall 第一条指令lw$2,x在组装时分为两条指令。说明是lui$1,0x00001001,后面是lw$
.data
x: .word 4711
y: .word 10
z: .word 0x0A91
e: .word 0
.text
.globl main
main:
lw $2, x
lw $3, y
lw $4, z
add $2, $2, $3
sub $3, $2, $4
sw $3, e
li $2, 10
syscall
第一条指令
lw$2,x
在组装时分为两条指令。说明是lui$1,0x00001001
,后面是lw$2,0x00000000($1)
。我知道lui将十六进制值1001移动到寄存器的上部,此时存储在$1中的值为0x10010000,但我根本不了解1001来自何处以及第二条指令的含义。我非常感谢您对我的帮助。我正在使用MARS来汇编和运行这个程序。MIPS指令的长度为32位,程序使用的地址也是32位。这意味着指令无法将完整的32位地址指定为立即数。 简单地说,指令
lw$t,var
无效(极少数情况除外)
事实上,它的编码是
lw $t, offset($s)
1000 11ss ssst tttt iiii iiii iiii iiii
其中,i位表示仅使用16位来指定地址(并且必须始终指定基址寄存器,最终可以使用$zero
寄存器)
因此,汇编程序执行以下操作:每当使用lw$t,var
时,它都会将该指令汇编成两条指令,一条指令将地址的上16位加载到$at
中,另一条指令将$at
用作基址寄存器,地址的下16位作为偏移量
lui $at, ADDR_H #ADDR_H is ADDR >> 16
lw $t, ADDR_L($at) #ADDR_L is ADDR & 0xffff
注意,由于
lw
从$at
+ADDR\L读取,因此使用的最终地址是ADDR\u H>16+ADDR[15],其中ADDR[15]
表示ADDR
的位15的值(这是ADDR\u L
0x10010000
的符号位恰好是x
的地址。哦,那好吧。谢谢一个小错误:lw指令中的偏移量是有符号的,所以单独用移位计算ADDR\u H是不正确的。如果ADDR\u L结果为负数,则需要将ADDR\u H增加1以进行补偿。assembler当然会处理这个问题。@MikeSpivey非常感谢!这是一个非常好的观点!我相信将原始地址的第15位添加到ADDR_H就足够了。我正在编辑答案。在编写MIPS汇编程序时,我将短ADDR_L=(short)ADDR;短ADDR_H=(ADDR-ADDR_L)>>16;断言(ADDR==ADDR_H)