Como implementar a não operação em MIPS?

Sou novo em MIPS, e estou a tentar julgar se cada caroço numa corda é um alfa. Eu usei o código ASCII para me ajudar a julgá-lo, enquanto eu descobri que não há nenhuma instrução representando 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.: After judge

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 implementar larger than significado em MIPS? Obrigado antecipadamente.

Author: longj, 2017-03-22

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

Acho que quer um exclusivo ou uma operação para lhe dizer se a sua entrada é apenas uma de menos de 123 e menos de 97. Algo assim (totalmente não testado)
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
 6
Author: sfi, 2017-03-22 17:28:48

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
 1
Author: Craig Estey, 2017-03-23 00:26:30