Como implementar a não operação em MIPS?
larger than
Significado. Então eu tento implementar uma operação not
a partir das instruções que eu conheci. Aqui está parte do meu código:
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
No entanto, não consegui obter o resultado que queria. Estabeleci um ponto de paragem e descobri que a minha operação parece ter alguns problemas.:
Na minha exceção, $t1 deve ser 1 e $t2 deve ser 0, enquanto a realidade não é.
Onde está o lugar errado no meu código? Existe alguma forma de implementar a operação {[2] } em MIPS? Ou há uma maneira melhor de implementarlarger than
significado em MIPS? Obrigado antecipadamente.
2 answers
Você tem uma operação não aqui:
nor $t1, $t1, $t1
Muitas vezes você pode apenas digitar a not
mnemônica e seu montador irá interpretá-la como uma pseudo instrução
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
Pode obter o efeito de {[2] } invertendo os argumentos para slt*
:
sltu $v0,$t0,$t1 # v0 = $t0 < $t1 (what you have)
sltu $v0,$t1,$t0 # v0 = $t0 > $t1 (what you want)
Note que ge
ou le
é um pouco mais complicado. Considere os vários pseudo-ops como: blt, bge, bgt, bge
[eles geram slt*
seguido de beq
ou bne
]. Normalmente é mais fácil trabalhar com eles.
xor
pode fazer uma negação bidirecional. O pseudo-op not
irá gerar um nor
.
Abaixo está um código que faz o que você quer. Note que é semelhante ao código SFI postado, mas tem um adicional [e necessário] and
durante a verificação da gama para evitar um falso positivo.
Por exemplo, sem o and
, a verificação do intervalo de a-z
irá relatar verdadeiro em qualquer coisa superior a z
(por exemplo 0x7B
também conhecido por {
). Isto porque ambas as instruções slt
irão gerar 0. Mas, xor
de dois zeros é 1. Assim, o resultado xor
deve ser comparado com o valor de gama superior 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