MIPS Snippets用于确定位k的清除,设置和值

时间:2017-12-08 20:10:11

标签: assembly mips

  A:ori $t1, $zero, 1
    sra $t1, k
    andi $t0, $t0, $t1

  B:ori $t1, $zero, 1
    srl $t0, k
    and $t0, $t0, $t1

  C:ori $t1, $zero, 1
    sll $t1, k
    not $t1, $t1
    and $t0, $t0, $t1

  D:ori $t1, $zero, 1
    srl $t1, k
    not $t1, $t1
    and $t0, $t0, $t1

  E:ori $t1, $zero, 1
    sll $t1, k
    ori $t0, $t0, $t1
  1. 用什么代码清除t0中的位k?

  2. 哪个代码用于在t0中设置位k?

  3. 哪个代码用于t0中位k的值?

  4. 从我能够做到的: 1:C 2:D 3:B

    选项A和E被省略,因为andi不会立即添加,而ori也有相同的问题。我的答案是否正确?无论哪种方式,你可以给我一个解释每个片段如何工作,因为我与汇编混淆。

    提前致谢,

1 个答案:

答案 0 :(得分:0)

 A:ori $t1, $zero, 1
    sra $t1, k
    andi $t0, $t0, $t1

C中的A等同于:

int tmp1 = 0x00000000 | 0x00000001; // tmp1 = 1;
tmp1 >>= k;
tmp2 &= k;

假设k>> = 1,任何右移都会使tmp1成为全零。如果你&所有零都会返回全零,所以这基本上只是清除了tmp2的值,将其设置为0。

  B:ori $t1, $zero, 1
    srl $t0, k
    and $t0, $t0, $t1

我们再次设置tmp1等于0x00000001。然后这次我们用逻辑右移k位数。 MSB为0,因此在这种情况下,这实际上只相当于sra(右移算术)。最后,我们和tmp0一起使用tmp1,这些都是零,所以我们所做的只是清除了值(现在$t0,或者我称之为tmp0,只是0x00000000)。

  C:ori $t1, $zero, 1
    sll $t1, k
    not $t1, $t1
    and $t0, $t0, $t1

与以前相同,tmp1ori设置为0x00000001。 这次我们在逻辑上向左移动了k,所以我们得到了一些二进制格式[32 - k many 0s][1 in kth bit][k - 1 many 0s]。然后我们not它,它给出了逆(二进制[32 - k many 1s ][0][k - 1 many 1s])。然后我们and $t0 k'th,清除t0的{​​{1}}位。

  D:ori $t1, $zero, 1
    srl $t1, k
    not $t1, $t1
    and $t0, $t0, $t1

好的,和以前一样,tmp1只是数字1(0x00000001)。然后我们在逻辑上向右移动,只要k大于1意味着我们得到tmp1只是零。我们不是它本身,所以它全是1(假设k是≥1)(0xffffffff)。然后我们和它tmp0。用一堆东西来定义一些东西不会改变它的价值,所以我们从ori得到的值是tmp1的值。我们将其存储在$t0中,因此我想这只是一种不改变$t0值的错综复杂的方式。

  E:ori $t1, $zero, 1
    sll $t1, k
    ori $t0, $t0, $t1

此处tmp1与之前设置为1. sll将使我们在第k个位中以LSB顺序为1,所以如果我们或那个掩码为{{1}我们应该在{1}中得到tmp0(无论天气在tmp0中是否存在或者不是1中的1)。因此,这有效地将tmp0 LSB设置为kth中的1。

我可能在那里某处犯了一个错误;如果是这样,请随意评论或写下您自己的答案。我故意在没有回答明确问题的情况下布置代码的逻辑,因为这听起来像是一个家庭作业问题,所以我想帮助你理解问题,而不必放弃解决方案。希望这会有所帮助。