MIPS中如何实现NOT操作?
How to implement NOT operation in MIPS?
我是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
操作似乎有一些问题:
在我的例外情况下,$t1应该是1,$t2应该是0,而实际不是。
我的代码哪里出错了?有什么方法可以在 MIPS 中实现 not
操作吗?或者有没有更好的方法来实现 MIPS 中的 larger than
含义?提前致谢。
你这里有一个not操作:
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
您可以通过将参数反转为 slt*
:
来获得 gt
的效果
sltu $v0,$t0,$t1 # v0 = $t0 < $t1 (what you have)
sltu $v0,$t1,$t0 # v0 = $t0 > $t1 (what you want)
请注意 ge
或 le
有点棘手。考虑各种分支伪操作,如:blt, bge, bgt, bge
[它们生成 slt*
后跟 beq
或 bne
]。他们通常更容易合作。
xor
可以进行按位取反。 not
伪操作将生成一个 nor
.
下面是一些可以满足您要求的代码。请注意,它类似于 sfi 发布的代码,但在范围检查期间有一个额外的[和必要] and
以防止误报。
例如,没有 and
,a-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
我是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
操作似乎有一些问题:
在我的例外情况下,$t1应该是1,$t2应该是0,而实际不是。
我的代码哪里出错了?有什么方法可以在 MIPS 中实现 not
操作吗?或者有没有更好的方法来实现 MIPS 中的 larger than
含义?提前致谢。
你这里有一个not操作:
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
您可以通过将参数反转为 slt*
:
gt
的效果
sltu $v0,$t0,$t1 # v0 = $t0 < $t1 (what you have)
sltu $v0,$t1,$t0 # v0 = $t0 > $t1 (what you want)
请注意 ge
或 le
有点棘手。考虑各种分支伪操作,如:blt, bge, bgt, bge
[它们生成 slt*
后跟 beq
或 bne
]。他们通常更容易合作。
xor
可以进行按位取反。 not
伪操作将生成一个 nor
.
下面是一些可以满足您要求的代码。请注意,它类似于 sfi 发布的代码,但在范围检查期间有一个额外的[和必要] and
以防止误报。
例如,没有 and
,a-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