假定$ t2 = 0x55555550
,然后执行以下指令:
andi $t2, $t2, -1
$ t2成为0x0005550
这已由MIPS模拟器确认[<1
但是,这不是我所期望的。我认为答案应该是0x55555550和0xFFFFFFFF = 0x55555550。我认为常数-1在和逻辑之前被符号扩展为0xFFFFFFFF。但似乎答案是0x55555550&0x0000FFFF为什么将-1的符号扩展为0x0000FFFF而不是0xFFFFFFFF
0xffffffff
,从而使$t2
保持不变。否则,MARS和SPIM都将其拒绝,并出现错误,表明该错误不可编码。其他汇编程序可能有所不同。您的期望是正确的,但是您对实验结果的解释是not] >>$ t2变为0x0005550,这已由MIPS仿真器确认。
不,这是不正确的。因此,以下之一:
0x55555550
中没有$t2
,在andi
中没有0x5550
,但是您却没有设置$t2
(即)您的测试程序[ C0]正确。是正确。而且,我将在下面解释发生了什么以及为什么。
但是似乎答案是0x55555550和0x0000FFFF。为什么将-1的符号扩展为0x0000FFFF而不是0xFFFFFFFF
它不是。它的[[was符号扩展到
0xFFFFFFFF
。同样,您错误地读取了实验结果[或您的测试程序有错误]。mips
模拟器和汇编器具有pseudo ops
“纯”伪操作的示例是li
(“立即加载”)。它具有no
lui
,ori
(其中are物理指令)。伪操作应该
不是与汇编器伪指令
,例如.text
,.data
,.word
,.eqv
等混淆某些伪操作可能与实际的物理指令重叠。这就是您的示例所发生的情况。实际上,汇编器将any
给定的指令作为potential伪操作进行检查。它可以确定in可以通过单个物理指令满足intent
。如果没有,它将生成1-3条指令序列,并且可以使用[reserved]$at
寄存器[$1
]作为该序列的一部分。在mars
中,要查看实际的实际指令,请查看源代码窗口的Basic
列。为了我的回答的完整性,下面的所有内容均以开头的评论开头。
addi
和您的原始帖子一样>
andi
与您更正后的帖子一样>>
使用[[unsigned
参数的andi
addi
的原始问题的汇编源: .text
.globl main
main:
li $t2,0x55555550
addi $t3,$t2,-1
nop
mars
的解释如下: Address Code Basic Source
0x00400000 0x3c015555 lui $1,0x00005555 4 li $t2,0x55555550
0x00400004 0x342a5550 ori $10,$1,0x00005550
0x00400008 0x214bffff addi $11,$10,0xffffffff 5 addi $t3,$t2,-1
0x0040000c 0x00000000 nop 6 nop
addi
将符号扩展
其16位立即数,因此我们有0xFFFFFFFF
。然后,执行two'scomplement加法运算,我们得到的最终结果为
0x5555554F
因此,汇编程序不需要为addi
生成额外的指令,因此addi
pseudo-op生成了一个
real
addi
((2)这是andi
来源: .text
.globl main
main:
li $t2,0x55555550
andi $t3,$t2,-1
nop
Address Code Basic Source
0x00400000 0x3c015555 lui $1,0x00005555 4 li $t2,0x55555550
0x00400004 0x342a5550 ori $10,$1,0x00005550
0x00400008 0x3c01ffff lui $1,0xffffffff 5 andi $t3,$t2,-1
0x0040000c 0x3421ffff ori $1,$1,0x0000ffff
0x00400010 0x01415824 and $11,$10,$1
0x00400014 0x00000000 nop 6 nop
哇!
发生了什么事?andi
生成了三个指令。A值是real
andi
指令不会not符号扩展其直接参数。因此,我们可以在实际andi
中使用的最大unsigned
0xFFFF
但是,通过指定-1
,我们告诉汇编器我们did
想要符号扩展名(即0xFFFFFFFF
)所以,汇编器可以用单个指令not充分实现意图,我们得到了上面的序列。并且生成的序列可以not使用andi
,但必须使用寄存器形式:and
。这是将andi
生成的代码转换回更友好的asm源: lui $at,0xFFFF
ori $at,$at,0xFFFF
and $t3,$t2,$at
0x55555550
和0xFFFFFFFF
进行和运算,这是0x55555550
的[仍然不变]的值(3)这是[andi
的unsigned版本的来源:
.text
.globl main
main:
li $t2,0x55555550
andi $t3,$t2,0xFFFF
nop
这里是汇编输出:
Address Code Basic Source
0x00400000 0x3c015555 lui $1,0x00005555 4 li $t2,0x55555550
0x00400004 0x342a5550 ori $10,$1,0x00005550
0x00400008 0x314bffff andi $11,$10,0x0000ffff 5 andi $t3,$t2,0xFFFF
0x0040000c 0x00000000 nop 6 nop
当汇编器看到我们使用的是十六进制常量(即0x
前缀)时,它将尝试以unsigned
andi
可以满足请求。其结果是0x5550
请注意,如果我们使用的掩码值为
0x1FFFF
,则该掩码将是无符号的。但是,它大于16位,因此汇编器将生成多指令序列来满足请求。
而且,这里的结果将是0x15550
根据specification,立即数为16位宽。
因此,
andi $t2, $t2, -1
可以读为andi $t2, $t2, 0xFFFF
。所有逻辑运算都将立即数视为一个位串,并将其零扩展为32位。
从本参考表开始,对于
andi
指令,它清楚地表明立即数上的符号扩展名是零扩展名。对于