如何从寄存器中提取位中的值,并用它们替换其他寄存器中的位? (MIP汇编语言) [英] How to extract values in bits from a register and use them to replace bits in a different register? (MIPs assembly language)

查看:115
本文介绍了如何从寄存器中提取位中的值,并用它们替换其他寄存器中的位? (MIP汇编语言)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要从寄存器$ t0中提取位22到4的值,计算该值的一半(假定无符号整数),并使用新值替换寄存器$ t1中的位24到6的位,而无需更改$ t1中的其他位.没有给出值,但我认为这不应该成为问题.每个寄存器有32位

我对MIP有点陌生,所以我不确定如何解决这个问题

解决方案

我已经分解了算法的各个步骤.然后,我创建了一个C原型/测试程序.最后,我创建了一个mips asm程序.

这些是我会为您[或其他任何人]建议的步骤,尤其是在开始时.

首先使用C编写代码(或至少使用C伪代码编写原型),使算法的调试更加容易.

从C程序中,我能够为mips程序创建测试数据.测试数据包括C程序获得的解决方案.

mips程序会将其视为通过/失败诊断.这似乎有些矫kill过正,但是在asm程序的第一个版本中,存在一个错误.我在srlv指令的第三个参数中使用了错误寄存器,而诊断程序实际上未通过测试(例如,我使用$t0而不是$t1).


术语:

这是条款的配对:

xval:   $t0
xhi:    22
xlo:    4

yval:   $t1
yhi:    24
ylo:    6


提取步骤(1):

给定值xval,每当看到"提取xhixlo"时,要做的第一件事就是将xval右移xlo:

xshf = xval >> xlo

但是现在,xshf仍然具有xhi左侧的位,因此我们需要屏蔽它们.


公式:

包含"位范围的位宽为:

wid = (hi - lo) + 1

因此,右对齐"掩码为:

rmsk = (0xFFFFFFFF >> (32 - wid))

左对齐"掩码为:

lmsk = (rmsk << lo)

注意:上面的方程是动态运行的(如上所述).或者,如果我们有固定的数字,我们可以手工计算最终值以产生常数.


提取步骤(2):

因此,为了获得位范围的隔离值,我们现在应用掩码:

xshf &= xrmsk

这是问题的第一部分.我们已经隔离了必要的位,因此它们现在位于xshf的最右边的位(即(xwid-1)0的位).


提取步骤(3):

以上是用于一般位提取的.具体问题要求我们除以2:

xshf >>= 1


合并步骤(1):

问题的第二部分是我们必须将xshf应用于目标值yval.

yval具有不同的范围:yhiylo.我们应用公式来获取yval的适当值.

我们必须清除yval中的旧位:

yval &= ~ylmsk


合并步骤(2):

我们需要对xshf做两件事:

  1. 清理" xshf,以便修改yval中的正确位
  2. xshf移至正确的位置以与yval
  3. 合并

我们可以通过以下两种方法之一来完成此任务.以下两个序列是等效的:

xshf &= yrmsk
xshf <<= ylo

或者:

xshf <<= ylo
xshf &= ylmsk

注意:因为 specific 问题中的 width 位是 same ,所以屏蔽步骤可以是消除(即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(__lo)    (((_hi) - (_lo)) + 1)
#define RMSK(__lo)   (0xFFFFFFFF >> (32 - WID(__lo)))
#define LMSK(__lo)   (RMSK(__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中不存在 中.因此,要么获取火星: http://courses.missouristate.edu/KenVollmar/mars/或[使用spim]将34更改为1以十进制打印

    # 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

I need to extract the value in bits 22 down to 4 from register $t0, compute the half of this value (assumed unsigned integer), and use the new value to replace bits 24 down to 6 in register $t1 without changing the others bits in $t1. The value isn't given but I don't think that should be an issue. There are 32 bits per register

I'm a bit new to MIPs so I'm not sure how to go about solving this problem

解决方案

I've broken down the invidual steps of the algorithm. I then created a C prototype/test program. And, finally, I created a mips asm program.

Those are the steps I would recommend for you [or anybody else], particularly when getting started.

Writing the code in C first [or at least prototyping it in C-like pseudo code], makes debugging of the algorithm easier.

From the C program, I was able to create test data for the mips program. The test data includes the solution that the C program got.

The mips program would treat this as a pass/fail diagnostic. This might seem like overkill, but in the first version of the asm program, there was a bug. I had used a wrong register in the srlv instruction's third argument and the diagnostic actually failed the tests (e.g. I used $t0 instead of $t1).


Terminology:

This is the matchup of the terms:

xval:   $t0
xhi:    22
xlo:    4

yval:   $t1
yhi:    24
ylo:    6


Extract step (1):

Given a value xval, whenever you see "extract bits xhi to xlo", the first thing to do is right shift xval by xlo:

xshf = xval >> xlo

But now, xshf still has the bits that were to the left of xhi, so we need to mask them.


Formulas:

The bit width of an "inclusive" bit range is:

wid = (hi - lo) + 1

So, the "right justified" mask is:

rmsk = (0xFFFFFFFF >> (32 - wid))

The "left justified" mask is:

lmsk = (rmsk << lo)

Note: The above equations work dynamically [as above]. Or, if we have fixed numbers, we can calculate the final values by hand to produce constants.


Extract step (2):

So, to get the isolated value for the bit range, we now apply the mask:

xshf &= xrmsk

This is the first part of the problem. We've isolated the necessary bits, so they are now in the rightmost bits of xshf (i.e. bits (xwid-1) to 0).


Extract step (3):

The above was for general bit extraction. The specific problem requires that we divide by 2:

xshf >>= 1


Merge step (1):

The second part of the problem is that we have to apply the xshf to the target value yval.

yval has a different range: yhi to ylo. We apply the formulas to get the appropriate values for yval.

We must clear out the old bits in yval:

yval &= ~ylmsk


Merge step (2):

We need to do two things to xshf:

  1. "clean up" xshf so that only the correct bits in yval get modified
  2. Shift xshf into the correct position for merging with yval

We can accomplish this in one of two ways. The following two sequences are equivalent:

xshf &= yrmsk
xshf <<= ylo

Or:

xshf <<= ylo
xshf &= ylmsk

Note: Because the bit widths in the specific problem are the same, the masking step can be eliminated (i.e. xshf had already been masked by xrmsk and it is the same as yrmsk. So, either masking step is not required).


Merge step (3):

Now, we merge in the shifted value:

yval |= xshf

That's it--we're done ...


Prototype:

Here's some C code that combines all this.

Because the bit range values are fixed, the mask values are precalculated once. If they had to vary, the mask code would have to recalculate them on each merge call.

Also note that the masks are constants because the ranges are fixed.

#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;
}


Output:

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 program:

This is set up for the mars simulator. In particular, the syscall 34 to print a value in hex only exists in mars and not in spim. So, either get mars: http://courses.missouristate.edu/KenVollmar/mars/ or [using spim] change the 34 to 1 to print in decimal

    # 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

这篇关于如何从寄存器中提取位中的值,并用它们替换其他寄存器中的位? (MIP汇编语言)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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