我需要从寄存器$ t0中将位22中的值提取到4,计算该值的一半(假设无符号整数),并使用新值将寄存器$ t1中的位24替换为6而不更改$ t1中的其他位。价值没有给出但我不认为这应该是一个问题。每个寄存器有32位
我对MIP有点新意,所以我不确定如何解决这个问题
答案 0 :(得分:0)
我已经分解了算法的各个步骤。然后我创建了一个C原型/测试程序。最后,我创建了一个mips asm程序。
这些是我为你[或其他任何人]推荐的步骤,特别是在开始使用时。
首先在C中编写代码[或者至少使用类似C的伪代码对其进行原型设计],可以更轻松地调试算法。
从C程序中,我能够为mips程序创建测试数据。测试数据包括C程序获得的解决方案。
mips程序会将此视为通过/失败诊断。这似乎有点矫枉过正,但在asm程序的第一个版本中,有一个错误。我在srlv
指令的第三个参数中使用了错误的寄存器,诊断实际上未通过测试(例如,我使用$t0
代替$t1
)。
<强>术语:强>
这是术语的匹配:
xval: $t0
xhi: 22
xlo: 4
yval: $t1
yhi: 24
ylo: 6
提取步骤(1):
给定值xval
,每当您看到&#34; 提取位xhi
到xlo
&#34;时,首先要做的是xval
右移xlo
:
xshf = xval >> xlo
但现在,xshf
仍然位于xhi
左侧的位,因此我们需要屏蔽它们。
<强>公式:强>
&#34;包含&#34;的位宽位范围是:
wid = (hi - lo) + 1
所以,&#34;右对齐&#34;面具是:
rmsk = (0xFFFFFFFF >> (32 - wid))
&#34;左对齐&#34;面具是:
lmsk = (rmsk << lo)
注意:上述方程式动态[如上]。或者,如果我们有固定的数字,我们可以手动计算最终值以产生常数。
提取步骤(2):
因此,为了获得位范围的隔离值,我们现在应用掩码:
xshf &= xrmsk
这是问题的第一部分。我们已经隔离了必要的位,因此它们现在位于xshf
的最右边位(即位(xwid-1)
到0
)。
提取步骤(3):
以上是一般的比特提取。具体问题要求我们除以2:
xshf >>= 1
合并步骤(1):
问题的第二部分是我们必须将xshf
应用于目标值yval
。
yval
的范围不同:yhi
到ylo
。我们应用公式来获取yval
的适当值。
我们必须清除yval
中的旧位:
yval &= ~ylmsk
合并步骤(2):
我们需要对xshf
做两件事:
xshf
以便{em>仅 yval
中的正确位被修改xshf
转移到与yval
我们可以通过两种方式之一来实现这一目标。以下两个序列是等效的:
xshf &= yrmsk
xshf <<= ylo
或者:
xshf <<= ylo
xshf &= ylmsk
注意:因为特定问题中的 width 位是相同的,所以屏蔽步骤可以是已消除(即xshf
已被xrmsk
屏蔽,且与yrmsk
相同。因此, 屏蔽步骤不必填)。
合并步骤(3):
现在,我们合并了移位值:
yval |= xshf
那是 - 我们已经完成了......
<强>原型:强>
这里有一些结合了所有这些的C代码。
由于位范围值已固定,因此掩码值预先计算。如果它们必须变化,则掩码代码必须在每次合并调用时重新计算它们。
另请注意,蒙版是常量,因为范围是固定的。
#include <stdio.h>
#include <stdlib.h>
int opt_v;
typedef unsigned int u32;
u32 xval;
#define XHI 22
#define XLO 4
u32 yval;
#define YHI 24
#define YLO 6
u32 xrmsk;
u32 xlmsk;
u32 yrmsk;
u32 ylmsk;
#define WID(_hi,_lo) (((_hi) - (_lo)) + 1)
#define RMSK(_hi,_lo) (0xFFFFFFFF >> (32 - WID(_hi,_lo)))
#define LMSK(_hi,_lo) (RMSK(_hi,_lo) << (_lo))
#define SHOW(_sym) \
show(_sym,#_sym)
#define SHOWX(_sym) \
if (opt_v) \
SHOW(_sym)
void
show(u32 val,const char *sym)
{
u32 bitmsk;
u32 bitval;
printf("%8.8X ",val);
for (bitmsk = 1u << 31; bitmsk != 0; bitmsk >>= 1) {
bitval = val & bitmsk;
printf("%d",bitval ? 1 : 0);
}
printf(" %s\n",sym);
}
void
merge(void)
{
u32 xshf;
SHOW(xval);
SHOW(yval);
// extract (1):
xshf = xval >> XLO;
SHOW(xshf);
// extract (2):
SHOWX(xrmsk);
xshf &= xrmsk;
SHOW(xshf);
// extract (3):
xshf >>= 1;
SHOW(xshf);
// merge (1):
SHOWX(yrmsk);
SHOWX(ylmsk);
yval &= ~ylmsk;
SHOW(yval);
// merge (2):
xshf &= yrmsk; // belt and ...
SHOW(xshf);
xshf <<= YLO;
SHOW(xshf);
xshf &= ylmsk; // ... suspenders
SHOW(xshf);
// merge (3)
yval |= xshf;
SHOW(yval);
}
void
test(u32 y,u32 x)
{
printf("\n");
yval = y;
xval = x;
merge();
}
// main -- main program
int
main(int argc,char **argv)
{
char *cp;
--argc;
++argv;
for (; argc > 0; --argc, ++argv) {
cp = *argv;
if (*cp != '-')
break;
switch (cp[1]) {
case 'v':
opt_v = ! opt_v;
break;
default:
break;
}
}
xrmsk = RMSK(XHI,XLO);
SHOW(xrmsk);
xlmsk = LMSK(XHI,XLO);
SHOW(xlmsk);
yrmsk = RMSK(YHI,YLO);
SHOW(yrmsk);
ylmsk = LMSK(YHI,YLO);
SHOW(ylmsk);
test(0,~0);
test(~0,0);
for (int idx = 0; idx <= 5; ++idx)
test(rand(),rand());
return 0;
}
<强>输出:强>
0007FFFF 00000000000001111111111111111111 xrmsk
007FFFF0 00000000011111111111111111110000 xlmsk
0007FFFF 00000000000001111111111111111111 yrmsk
01FFFFC0 00000001111111111111111111000000 ylmsk
FFFFFFFF 11111111111111111111111111111111 xval
00000000 00000000000000000000000000000000 yval
0FFFFFFF 00001111111111111111111111111111 xshf
0007FFFF 00000000000001111111111111111111 xshf
0003FFFF 00000000000000111111111111111111 xshf
00000000 00000000000000000000000000000000 yval
0003FFFF 00000000000000111111111111111111 xshf
00FFFFC0 00000000111111111111111111000000 xshf
00FFFFC0 00000000111111111111111111000000 xshf
00FFFFC0 00000000111111111111111111000000 yval
00000000 00000000000000000000000000000000 xval
FFFFFFFF 11111111111111111111111111111111 yval
00000000 00000000000000000000000000000000 xshf
00000000 00000000000000000000000000000000 xshf
00000000 00000000000000000000000000000000 xshf
FE00003F 11111110000000000000000000111111 yval
00000000 00000000000000000000000000000000 xshf
00000000 00000000000000000000000000000000 xshf
00000000 00000000000000000000000000000000 xshf
FE00003F 11111110000000000000000000111111 yval
6B8B4567 01101011100010110100010101100111 xval
327B23C6 00110010011110110010001111000110 yval
06B8B456 00000110101110001011010001010110 xshf
0000B456 00000000000000001011010001010110 xshf
00005A2B 00000000000000000101101000101011 xshf
32000006 00110010000000000000000000000110 yval
00005A2B 00000000000000000101101000101011 xshf
00168AC0 00000000000101101000101011000000 xshf
00168AC0 00000000000101101000101011000000 xshf
32168AC6 00110010000101101000101011000110 yval
643C9869 01100100001111001001100001101001 xval
66334873 01100110001100110100100001110011 yval
0643C986 00000110010000111100100110000110 xshf
0003C986 00000000000000111100100110000110 xshf
0001E4C3 00000000000000011110010011000011 xshf
66000033 01100110000000000000000000110011 yval
0001E4C3 00000000000000011110010011000011 xshf
007930C0 00000000011110010011000011000000 xshf
007930C0 00000000011110010011000011000000 xshf
667930F3 01100110011110010011000011110011 yval
74B0DC51 01110100101100001101110001010001 xval
19495CFF 00011001010010010101110011111111 yval
074B0DC5 00000111010010110000110111000101 xshf
00030DC5 00000000000000110000110111000101 xshf
000186E2 00000000000000011000011011100010 xshf
1800003F 00011000000000000000000000111111 yval
000186E2 00000000000000011000011011100010 xshf
0061B880 00000000011000011011100010000000 xshf
0061B880 00000000011000011011100010000000 xshf
1861B8BF 00011000011000011011100010111111 yval
2AE8944A 00101010111010001001010001001010 xval
625558EC 01100010010101010101100011101100 yval
02AE8944 00000010101011101000100101000100 xshf
00068944 00000000000001101000100101000100 xshf
000344A2 00000000000000110100010010100010 xshf
6200002C 01100010000000000000000000101100 yval
000344A2 00000000000000110100010010100010 xshf
00D12880 00000000110100010010100010000000 xshf
00D12880 00000000110100010010100010000000 xshf
62D128AC 01100010110100010010100010101100 yval
238E1F29 00100011100011100001111100101001 xval
46E87CCD 01000110111010000111110011001101 yval
0238E1F2 00000010001110001110000111110010 xshf
0000E1F2 00000000000000001110000111110010 xshf
000070F9 00000000000000000111000011111001 xshf
4600000D 01000110000000000000000000001101 yval
000070F9 00000000000000000111000011111001 xshf
001C3E40 00000000000111000011111001000000 xshf
001C3E40 00000000000111000011111001000000 xshf
461C3E4D 01000110000111000011111001001101 yval
3D1B58BA 00111101000110110101100010111010 xval
507ED7AB 01010000011111101101011110101011 yval
03D1B58B 00000011110100011011010110001011 xshf
0001B58B 00000000000000011011010110001011 xshf
0000DAC5 00000000000000001101101011000101 xshf
5000002B 01010000000000000000000000101011 yval
0000DAC5 00000000000000001101101011000101 xshf
0036B140 00000000001101101011000101000000 xshf
0036B140 00000000001101101011000101000000 xshf
5036B16B 01010000001101101011000101101011 yval
MIPS计划:
这是为mars
模拟器设置的。特别是,以{十六进制打印值的syscall
34仅存在mars
中的spim
和 中。spim
。因此,要么获取火星:http://courses.missouristate.edu/KenVollmar/mars/或[使用 # these work for the mars simulator
.eqv XHI 22
.eqv XLO 4
.eqv YHI 24
.eqv YLO 6
# these work for the spim simulator
###XHI = 22
###XLO = 4
###YHI = 24
###YLO = 6
.data
testdata:
.word 0xFFFFFFFF,0x00000000,0x00FFFFC0
.word 0x00000000,0xFFFFFFFF,0xFE00003F
.word 0x6B8B4567,0x327B23C6,0x32168AC6
.word 0x643C9869,0x66334873,0x667930F3
.word 0x74B0DC51,0x19495CFF,0x1861B8BF
.word 0x2AE8944A,0x625558EC,0x62D128AC
.word 0x238E1F29,0x46E87CCD,0x461C3E4D
.word 0x3D1B58BA,0x507ED7AB,0x5036B16B
edata:
msg_nl: .asciiz "\n"
msg_xrmsk: .asciiz "xrmsk "
msg_xlmsk: .asciiz "xlmsk "
msg_yrmsk: .asciiz "yrmsk "
msg_ylmsk: .asciiz "ylmsk "
msg_xval: .asciiz "xval "
msg_yval: .asciiz "yval "
msg_pass: .asciiz "pass "
msg_fail: .asciiz "FAIL "
msg_ans: .asciiz "answ "
.text
.globl main
main:
jal setup2
la $s6,testdata
la $s7,edata
main_loop:
jal test
addiu $s6,$s6,12
blt $s6,$s7,main_loop
li $v0,10
syscall
# test -- test the merge
test:
subu $sp,$sp,4
sw $ra,0($sp)
li $v0,4
la $a0,msg_nl
syscall
lw $t0,0($s6) # get source value
lw $t1,4($s6) # get destination value
lw $t2,8($s6) # get solution value
# print the X value
la $a0,msg_xval
move $a1,$t0
jal print
# print the Y value
la $a0,msg_yval
move $a1,$t1
jal print
# do the operation
jal merge
bne $t1,$t2,test_fail
la $a0,msg_pass
move $a1,$t1
jal print
j test_done
test_fail:
la $a0,msg_fail
move $a1,$t1
jal print
# print the result
la $a0,msg_ans
move $a1,$t2
jal print
test_done:
lw $ra,0($sp)
addu $sp,$sp,4
jr $ra
# print -- print number
#
# arguments:
# a0 -- string
# a1 -- value
print:
# output the string
li $v0,4
syscall
li $v0,34 # syscall print hex
move $a0,$a1
syscall
li $v0,4
la $a0,msg_nl
syscall
jr $ra
# merge -- merge the data
#
# arguments:
# t0 -- source value
# t1 -- target value
#
# registers:
# t7 -- xshf
# t6 -- ~ylmsk
merge:
srl $t7,$t0,XLO # E1: xshf = xval >> xlo
and $t7,$t7,$s0 # E2: xshf &= xrmsk
srl $t7,$t7,1 # E3: xshf >>= 1
not $t6,$s3 # M1: get ~ylmsk
and $t1,$t1,$t6 # M1: yval &= ~ylmsk
sll $t7,$t7,YLO # M2: xshf <<= ylo
and $t7,$t7,$s3 # M2: xshf &= ylmsk
or $t1,$t1,$t7 # M3: yval |= xshf
jr $ra # return
# setup2 -- set up the mask values
#
# RETURNS:
# s0 -- xrmsk
# s1 -- xlmsk
# s2 -- yrmsk
# s3 -- ylmsk
#
# registers:
# a0 -- hi bit value
# a1 -- lo bit value
setup2:
subu $sp,$sp,4
sw $ra,0($sp)
# set up the xval masks
li $a0,XHI
li $a1,XLO
jal setup1
move $s0,$v0
move $s1,$v1
la $a0,msg_xrmsk
move $a1,$s0
jal print
la $a0,msg_xlmsk
move $a1,$s1
jal print
# set up the yval masks
li $a0,YHI
li $a1,YLO
jal setup1
move $s2,$v0
move $s3,$v1
la $a0,msg_yrmsk
move $a1,$s2
jal print
la $a0,msg_ylmsk
move $a1,$s3
jal print
lw $ra,0($sp)
addu $sp,$sp,4
jr $ra # return
# setup1 -- set up the mask values
#
# RETURNS:
# v0 -- rmsk
# v1 -- lmsk
#
# arguments:
# a0 -- hi bit value
# a1 -- lo bit value
#
# registers:
# t0 -- wid
# t1 -- 32 - wid
setup1:
sub $t0,$a0,$a1 # wid = hi - lo
addi $t0,$t0,1 # wid += 1
li $v0,0xFFFFFFFF # rmsk = 0xFFFFFFFF
# get 32 - wid
li $t1,32
sub $t1,$t1,$t0
srlv $v0,$v0,$t1 # rmsk >>= (32 - wid)
sllv $v1,$v0,$a1 # lmsk = rmsk << lo
jr $ra # return
]将34更改为1以十进制打印
{{1}}