Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly MIPS组件,lui 0x1001_Assembly_Mips_Mars Simulator - Fatal编程技术网

Assembly MIPS组件,lui 0x1001

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$

我有一个作业,其中我必须解释关于以下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$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)