MIPS组件,Lui 0x1001 [英] MIPS Assembly, lui 0x1001

查看:267
本文介绍了MIPS组件,Lui 0x1001的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个作业,其中我必须解释有关以下MIPS汇编代码的一些事情:

I have an assignment in which I have to explain some things about the following MIPS Assembly code:

.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来组装和运行此程序.

The first instruction lw $2, x is separated into two instructions when assembled. The instructions are lui $1, 0x00001001 followed by lw $2, 0x00000000($1). I understand that lui moves the hex value 1001 into the upper part of the register and the value stored in $1 at this point is 0x10010000, but I do not understand where the 1001 comes from and what the second instruction means at all. I would really appreacitate any help on the subject.I am using MARS to assemble and run this program.

推荐答案

MIPS指令的长度为32位,程序使用的地址也是如此.
这意味着 lw 指令无法执行将完整的32位地址指定为立即数. 简而言之,指令lw $t, var无效(仅在少数情况下有效).

MIPS instructions are 32 bits longs, and so are the addresses uses by a program.
This implies that the lw instruction is unable to specify a full 32-bit address as an immediate. Simply put, the instruction lw $t, var is not valid (expect for very few cases).

实际上,它的编码是

lw $t, offset($s)
1000 11ss ssst tttt iiii iiii iiii iiii

i 位显示只有16位用于指定地址(并且必须始终指定基址寄存器,最终可以使用$zero寄存器).

Where the i bits show that only 16 bits are used to specify an address (and that a base register must always be specified, eventually the $zero register can be used).

因此,汇编程序会执行此技巧:每当您使用lw $t, var时,它将把该指令汇编为两条指令,其中一条将地址的高16位装入$at使用$at作为基址寄存器,地址的低16位作为偏移量.

So the assembler does this trick: whenever you use a lw $t, var it assembles that instruction into two instructions, one that load the upper 16 bits of the address into $at and a lw that use $at as a base register with the lower 16 bits of the address as the offset.

lui $at, ADDR_H            #ADDR_H is ADDR >> 16
lw $t, ADDR_L($at)         #ADDR_L is ADDR & 0xffff

请注意,由于lw$at + ADDR_L 中读取,因此最终使用的地址为 ADDR_H << 16 + ADDR_L = ADDR .如预期的那样.

Note that since the lw reads from $at + ADDR_L the final address used is ADDR_H << 16 + ADDR_L = ADDR. As expected.

这里有个微妙之处,由迈克·斯皮维(非常感谢他),请参见下文

There is subtlety here, pointed out by Mike Spivey (Many thanks to him), see below

这种不会直接映射到ISA中的指令称为 pseudo-instruction . $at寄存器保留给汇编器以实现它们.

This kind of instructions, that doesn't map directly into the ISA, are called pseudo-instruction. The $at register is reserved for the assembler exactly for implementing them.

在MARS中,您可以通过取消选中设置>允许扩展(伪)指令和格式来禁用伪指令.
尽管没有伪指令的编程将很快变得令人讨厌,但要完全了解MIPS架构,至少值得做一次.

In MARS you can disable the pseudo instructions by unchecking Settings > Permits extended (pseudo) instructions and format.
While programming without pseudo-instructions will grow annoying pretty quickly, it is worth doing at least once, to fully understand the MIPS architecture.

Mike Spivey 正确地指出了16位立即偏移量是 sign-extended ,然后再添加到基本寄存器中.
如果ADDR_L被解释为16位二进制补码,结果是负数,则需要更正称为ADDR_H的值.
如果事实如此,则必须将ADDR_H递增.
可以将ADDR_H的通用公式校正为ADDR_H = ADDR >> 16 + ADDR[15],其中ADDR[15]表示ADDR的第15位的值(这是ADDR_L的符号位.

Mike Spivey correctly noted that the 16-bit offset immediate is sign-extended before being added to the base register.
This calls for a correction of the value I called ADDR_H in case ADDR_L turns out to be negative when interpreted as a 16-bit two's complement number.
If this turns out to be true, ADDR_H must be incremented.
The general formula for ADDR_H can be corrected to ADDR_H = ADDR >> 16 + ADDR[15] where ADDR[15] denotes the value of bit 15 of ADDR (which is the sign bit of ADDR_L.

这篇关于MIPS组件,Lui 0x1001的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆