问题描述
我正在了解MIPS数据路径中的指令解码(ID)阶段,并且得到以下报价:一旦知道了操作数,就可以从寄存器中读取实际数据或将数据扩展为32位(立即)."
I'm reading about the Instruction Decode (ID) phase in the MIPS datapath, and I've got the following quote: "Once operands are known, read the actual data (from registers) or extend the data to 32 bits (immediates)."
有人可以解释将数据扩展到32位(立即数)"部分的含义吗?我知道所有寄存器都包含32位,并且我知道立即数是什么.我只是不明白为什么您需要将立即数从26位扩展到32位.
Can someone explain what the "extend the data to 32 bits (immediates)" part means? I know that registers all contain 32 bits, and I know what an immediate is. I just don't understand why you need to extend the immediate from 26 to 32 bits.
谢谢!
推荐答案
26位立即数仅在跳转指令中,不会符号扩展或零扩展为32位,因为它们不是要添加的位移/减去.
26-bit immediates are only in jump instructions, and aren't sign- or zero-extended to 32 bit, because they're not displacements to be added/subtracted.
具有16位立即数的I型指令是不同的.
I-type instructions with 16-bit immediates are different.
-
addi
/addiu
立即数被符号扩展(通过将立即数的最高位/符号位复制到所有更高的位). https://en.wikipedia.org/wiki/Two%27s_complement#Sign_extension
这允许对-2^15
..+2^15-1
中的2的补码进行编码.
(从0xFFFF8000到0x00007FFF) -
ori
/andi
/xori
布尔立即数被零扩展(通过将所有高位设置为零)
这允许对来自0 .. 2^16-1
的无符号/2的补码进行编码.
(从0x00000000到0x0000FFFF)
addi
/addiu
immediates are sign-extended (by duplicating the top/sign bit of the immediate to all higher bits).https://en.wikipedia.org/wiki/Two%27s_complement#Sign_extension
This allows 2's complement numbers from-2^15
..+2^15-1
to be encoded.
(0xFFFF8000 to 0x00007FFF)ori
/andi
/xori
boolean immediates are zero-extended (by setting all higher bits to zero)
This allows unsigned / 2's complement numbers from0 .. 2^16-1
to be encoded.
(0x00000000 to 0x0000FFFF)
有关其他说明,请参见指令集引用,它分解显示0 ||的每条指令[I ]表示零扩展,或[I ] || [I ]用于扩展符号.
For other instructions see this instruction-set reference which breaks down each instruction showing 0 || [I] for zero-extension or [I] || [I] for sign-extension.
这使得可以将16位立即数用作32位二进制操作的输入,而32位二进制操作仅对2个等宽输入才有意义. (在一个简单的经典MIPS流水线中,解码级从寄存器和/或立即数中提取操作数.寄存器输入始终为32位,因此ALU连接了32位输入.将立即数扩展为32位意味着其余的CPU不必关心数据是来自立即数还是寄存器.)
This makes it possible to use 16-bit immediates as inputs to a 32-bit binary operation that only makes sense with 2 equal-width inputs. (In a simple classic MIPS pipeline, the decode stage fetches operands from registers and/or immediates. Register inputs are always going to be 32-bit, so the ALU is wired up for 32-bit inputs. Extending immediates to 32-bit means the rest of the CPU doesn't have to care whether the data came from an immediate or a register.)
也可以扩展符号:
-
lw
/sw
和其他加载/存储指令所使用的reg + imm16寻址模式下的偏移量 - 相对分支(
PC += imm16<<2
)
- offsets in the reg+imm16 addressing mode used by
lw
/sw
and other load/store instructions - relative branches (
PC += imm16<<2
)
也许是其他人,请查看手册以获取我没有提到的说明,以了解它们是否为正负号或零扩展.
maybe others, check the manual for instructions I didn't mention to see if they sign- or zero- extend.
您可能想知道为什么addiu
对其立即数进行符号扩展,即使它是未签名的呢?"
You might be wondering "why does addiu
sign-extend its immediate even though it's unsigned?"
请记住,没有,只有addiu
具有立即数负数.能够加或减-2^15 .. +2^15-1
范围内的数字比仅能加0 .. 2^16-1
有用.
Remember that there's no subiu
, only addiu
with a negative immediate. Being able to add or subtract numbers in the range -2^15 .. +2^15-1
is more useful than only being able to add 0 .. 2^16-1
.
通常,您不想在有符号的溢出时引发异常,因此通常编译器甚至对有符号的整数也使用addu
/addiu
. addu
的名称很错误:它不是用于无符号整数",它只是add
/addi
的允许包装/永不出错的版本.如果您想到的是C,这是有意义的,其中带符号的溢出是未定义的行为(因此,如果编译器希望以这种方式实现,则可以使用add
并在这种情况下引发异常),但是无符号的整数具有良好的定义溢出行为:以2为基础的环绕.
And usually you don't want to raise an exception on signed overflow, so normally compilers use addu
/ addiu
even on signed integers. addu
is badly named: it's not "for unsigned integers", it's just a wrapping-allowed / never-faulting version of add
/addi
. It sort of makes sense if you think of C, where signed overflow is undefined behaviour (and thus could use add
and raise an exception in that case if the compiler wanted to implement it that way), but unsigned integers have well-defined overflow behaviour: base 2 wraparound.
这篇关于什么是“立即扩展到32位"?在MIPS中意味着什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!