2010-10-15 7 views
2

J'apprends l'arithmétique des ordinateurs. Le livre que j'utilise (Patterson et Hennessey) énumère la question ci-dessous.soustraction d'entier double précision avec registres 32 bits (MIPS)

Ecrire code mips pour conduire à double soustraction entier de précision pour données de 64 bits. Supposons que le premier opérande figure dans les registres $ t4 (hi) et $ t5 (lo), deuxième dans $ t6 (hi) et $ t7 (lo).

Ma solution à la réponse est

sub $t3, $t5, $t7 # Subtract lo parts of operands. t3 = t5 - t7 
sltu $t2, $t5, $t7 # If the lo part of the 1st operand is less than the 2nd, 
        # it means a borrow must be made from the hi part 
add $t6, $t6, $t2 # Simulate the borrow of the msb-of-low from lsb-of-high 
sub $t2, $t4, $t6 # Subtract the hi's. t2 = t4 - t6 

Cependant, l'auteur solutions proposées à ce problème sont comme ci-dessous

Pour doubles entiers de précision signés,

subu $t3, $t5, $t7 
sltu $t2, $t5, $t7 
add $t6, $t6, $t2 
sub $t2, $t4, $t6 

Pour double non signé entiers de précision,

subu $t3, $t5, $t7 
sltu $t2, $t5, $t7 
addu $t6, $t6, $t2 
subu $t2, $t4, $t6 

Ma compréhension de la différence dans le fonctionnement sub/add et subu/addu est que débordement exception est générée dans sub/add et non subu/addu. sub/add et subu/addu soustraient/ajoutent les bits des opérandes et l'interprétation des opérandes signés ou non signifient ne fait aucune différence avec le résultat contrairement aux instructions slt et sltu.

Question 1
Je déduis des solutions d'auteur étant donné que la détection de débordement est traitée alors que je ne pensais pas à la même chose dans ma solution. Ai-je raison? Y a-t-il autre chose qui me manque?

Question 2
En supposant que ma conclusion ci-dessus est juste, pourquoi la détection de débordement mis hors pour les solutions fournis par l'auteur dans le cas de soustraction de double précision non signé par l'utilisation de addu et subu?

Répondre

6

Pour l'addition et la soustraction, il n'y a pas de différence entre les opérandes signés et non signés, à l'exception de la notion de dépassement. Un débordement est ce qui se passe lorsque la valeur numérique du résultat ne correspond pas à l'interprétation de la séquence de bits que vous obtenez. Par exemple, considérons des séquences de 8 bits (MIPS a des registres de 32 bits, mais 8 bits sont plus faciles pour mes exemples). Supposons une interprétation non signée: une séquence de 8 bits représente une valeur numérique comprise entre 0 et 255 (inclus). Si j'ajoute 10010011 (valeur numérique 147) à 01110110 (valeur numérique 118) alors j'obtiens 00001001 (valeur numérique 9). 9 n'est pas égal à 147 + 118. J'obtiens ce résultat parce que la valeur mathématique est 265, qui ne peut pas tenir dans 8 bits. Le résultat de l'addition aurait nécessité 9 bits, mais le neuvième bit supérieur a été supprimé.

Maintenant, imaginez le même exemple avec l'interprétation signée. 10010011 a maintenant une valeur numérique -109. 01110110 a toujours la valeur numérique 118, et le résultat obtenu (00001001) a la valeur 9. La somme mathématique de -109 et 118 est 9, donc il n'y a pas de débordement.Cela signifie que la notion de dépassement dépend de la façon dont vous interprétez les valeurs. La mécanique d'addition est la même pour les interprétations signées et non signées (pour les mêmes séquences de bits d'entrée, vous obtenez la même séquence binaire de sortie - c'est le point d'utilisation du complément à deux pour les valeurs signées négatives).

L'architecture MIPS fournit des moyens pour déclencher des exceptions en cas de débordement. Schématiquement, on peut trois opérations d'addition possibles sur les mots de 32 bits:

  • une addition qui ne tient pas compte en silence déversoirs (résultat est tronqué)
  • une addition qui soulève une exception lorsqu'un débordement signé se produit (il y a un débordement si les séquences d'entrée et de sortie sont interprétées comme des nombres signés)
  • une addition qui génère une exception lorsque se produit un débordement non signé (il y a un débordement si les séquences de intput et de sortie sont interprétées comme des nombres non signés)

Le MIPS implémente les deux premiers types d'additions, avec, respectivement, les opcodes addu et add. Dans les documentations MIPS, elles sont appelées respectivement non signée et arithmétique signée. Il n'y a pas d'opcode pour lever des exceptions sur les débordements non signés. En pratique, les compilateurs C utilisent seulement addu, mais ils peuvent utiliser add pour les types signés (ceci est autorisé par le standard C, mais casserait énormément de code existant). Les compilateurs Ada utilisent add car Ada rend la vérification de débordement obligatoire.

Cela dit ...

Patterson et Hennessey veulent mettre en œuvre signés et non signés Arithmétique sur les entiers 64 bits. Pour arithmétique non signée, ils ne veulent aucune exception, d'où ils utilisent addu et subu. Pour les arithmétiques signées, ils veulent qu'une exception se produise lorsque le résultat mathématique ne rentre pas dans une séquence 64 bits avec interprétation signée. Ils ne veulent pas déclencher une exception en raison d'une condition de type débordement parasite lors du traitement des moitiés de 32 bits. C'est pourquoi ils utilisent un subu pour les parties basses.

Votre solution est erronée car elle peut déclencher une exception là où elle ne devrait pas l'être. Supposons que vous voulez soustraire 2000000000 (deux milliards) de -2000000000 (moins deux milliards). Le résultat mathématique est 4000000000 (quatre milliards). Les deux opérandes et le résultat correspondent certainement à 64 bits (la plage représentable est -9223372036854775808 à 9223372036854775807). Par conséquent, pour l'arithmétique signée 64 bits, il n'y a pas de débordement: il ne devrait y avoir aucune exception. Cependant, dans cette situation, votre premier sub signalera un débordement. Ce sub fonctionne avec des valeurs de 32 bits et est signé 32 bits arithmétique. Ses opérandes seront 01110111001101011001010000000000 et 10001000110010100110110000000000. Notez que ces valeurs correspondent à 32 bits: l'interprétation signée 32 bits de ces valeurs est, respectivement, plus et moins deux milliards. Le résultat de la soustraction, cependant, est de quatre milliards, et il ne rentre pas dans 32 bits (comme un nombre signé). Ainsi, votre sub déclenche une exception. En règle générale, la détection de dépassement de capacité consiste à effectuer des opérations qui dépendent de l'interprétation de la signature, ce qui a une incidence sur la gestion du bit le plus significatif.Pour les grands arithmétiques entiers, tous les mots sauf les plus significatifs doivent être traités comme non signés, donc addu/subu partout. Dans un premier temps, les choses sont plus faciles à comprendre si vous vous concentrez d'abord sur l'arithmétique non signée, sans exception (alors vous utilisez simplement addu et subu, et jamaisadd ou sub).

+0

Merci beaucoup pour cette réponse détaillée. Vous dites: "Pour les arithmétiques non signées, ils ne veulent aucune exception". Y a-t-il une raison particulière pour laquelle l'exception ne devrait pas être soulevée pendant l'arithmétique non signée? –

+1

En C, l'arithmétique non signée implique une troncature silencieuse: c'est ce que dit la norme. Un _could_ voudrait avoir des nombres de 64 bits non signés avec des exceptions sur débordement, mais pour un 'long long non signé de 64 bits, vous avez besoin d'une troncature silencieuse. Patterson et Hennessey veulent également imiter ce que le MIPS fournit pour l'arithmétique 32 bits, c'est-à-dire non signée, sans exception, et les arithmétiques signées avec des exceptions sur débordement. –

+0

Oh, d'accord. Je reçois l'image entière maintenant. Merci encore une fois pour votre réponse détaillée. Appréciez-en beaucoup. –

Questions connexes