如何在MIPS中实现NOT操作?

时间:2017-03-22 17:04:32

标签: mips mips32

我是MIPS的新手,我正在尝试判断字符串中的每个字符是否为alpha。我使用ASCII代码来帮助我判断它,而我发现没有代表larger than含义的指令。所以我尝试从我所知道的指令中实现not操作。这是我的代码的一部分:

isAlpha:
  sltiu $t0, $s2, 123
  sltiu $t1, $s2, 97
  nor $t1, $t1, $t1
  and $t0, $t0, $t1

  sltiu $t2, $s2, 107
  sltiu $t3, $s2, 81
  nor $t3, $t3, $t3
  and $t2, $t2, $t3

  or $t0, $t0, $t2

  bne $t0, $zero, countAlpha
  jr $ra

然而,我无法得到我想要的结果。我设置了一个断点,发现我的not操作似乎有一些问题: After judge

在我的例外中,$ t1应该是1而$ t2应该是0,而实际情况则不是。

我的代码中哪里错了?有没有办法在MIPS中实现not操作?或者是否有更好的方法在MIPS中实现larger than含义?提前谢谢。

2 个答案:

答案 0 :(得分:7)

你在这里没有操作:

nor $t1, $t1, $t1

通常您只需键入not助记符,汇编程序就会将其解释为pseudo instruction

我认为你想要一个独家或操作来告诉你输入是否只有一个小于123且小于97.

像这样(完全未经测试)

isAlpha:
  sltiu $t0, $s2, 123
  sltiu $t1, $s2, 97
  xor $t0, $t0, $t1

  sltiu $t2, $s2, 107
  sltiu $t3, $s2, 81
  xor $t2, $t2, $t3

  or $t0, $t0, $t2

  bne $t0, $zero, countAlpha
  jr $ra

答案 1 :(得分:1)

您可以通过将参数反转为gt来获得slt*的效果:

    sltu   $v0,$t0,$t1             # v0 = $t0 < $t1 (what you have)
    sltu   $v0,$t1,$t0             # v0 = $t0 > $t1 (what you want)

请注意,gele有点棘手。考虑各种分支伪操作,例如:blt, bge, bgt, bge [它们生成slt*后跟beqbne]。他们通常更容易合作。

xor可以做出按位否定。 not伪操作会生成nor

下面是一些可以满足您需求的代码。请注意,它类似于发布的代码sfi,但在范围检查期间还有一个额外的[和必要的] and以防止误报。

例如,没有 anda-z的范围检查会在高于z的任何内容上报告为真(例如0x7B {)。这是因为两个slt指令都会生成0.但是,两个零的xor为1.因此,xor结果必须与高范围值slt结果相对应

# isAlpha -- decide if char is alpha
#
# RETURNS:
#   v0 -- 1=is alpha
#   s6 -- count of alpha chars
#
# arguments:
#   s2 -- character to test
#
# registers:
#   t0 -- holds lt 'a/A'? value
#   t1 -- holds lt 'a/A' + 1? value
#   t2 -- bool for within 'a-z'
#   t3 -- bool for within 'A-Z'
isAlpha:
    # within a-z range
    sltiu   $t0,$s2,0x61            # lt 'a'? (i.e. not a-z)
    sltiu   $t1,$s2,0x7B            # lt 'z' + 1? (i.e. le 'z')
    xor     $t2,$t0,$t1             # want one but not both
    and     $t2,$t2,$t1             # want only lt 'z' + 1

    # within A-Z range
    sltiu   $t0,$s2,0x41            # lt 'A'? (i.e. not A-Z)
    sltiu   $t1,$s2,0x5C            # lt 'Z' + 1? (i.e. le 'Z')
    xor     $t3,$t0,$t1             # want one but not both
    and     $t3,$t3,$t1             # want only lt 'Z' + 1

    or      $v0,$t2,$t3             # decide if alpha
    add     $s6,$s6,$v0             # increment alpha count
    jr      $ra