IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

Chargement dans un registre d'un long long


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre expérimenté
    Avatar de Tesing
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2009
    Messages
    272
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2009
    Messages : 272
    Par défaut Chargement dans un registre d'un long long
    Bonjour,

    je m'interroge sur la manière dont le processeur effectue des calculs sur des "long" (flottants ?) representés sur 64 bits (long int) alors qu'il me semble que la taille des registres est de 32 bits.

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 504
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 504
    Par défaut
    Bonjour,

    Cela se passe exactement comme toi, tu le ferais sur papier : en plusieurs fois. En fait, c'est ton compilateur qui va générer une courte séquence d'instructions (donc un mini-programme) pour y parvenir.

    Pour simplifier au maximum, tu peux considérer que le micro-processeur manipule chaque mot de 32 bits comme s'il s'agissait d'un seul chiffre, travaillant ainsi en « base 4294967295 ». Lorsqu'il fait une addition, la somme de deux nombres 32 bits tient au maximum sur 33 bits. Le bit excédentaire peut alors simplement être retenu dans le bit C (Carry) des flags du micro-processeur et être directement exploitée par d'autres instructions.

    Dans le cas d'une multiplication, le résultat d'un produits de deux nombres 32 bits tient sur 64 bits, au maximum. Ton micro-processeur utilise 2 registres pour sauver le résultat, par exemple EDX et EAX, sur x86. Tu peux alors « poser EAX » et « retenir EDX » comme tu le ferais sur papier avec une multiplication ordinaire en décimal.

    Ça veut dire que c'est surtout une question algorithmique. Je te conseille de jeter un œil à l'assembleur si la façon dont ces choses sont résolues t'intéresse. Tu peux également lire cette discussion.

  3. #3
    Membre expérimenté
    Avatar de Tesing
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2009
    Messages
    272
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2009
    Messages : 272
    Par défaut
    Citation Envoyé par Obsidian Voir le message
    Bonjour,

    Cela se passe exactement comme toi, tu le ferais sur papier : en plusieurs fois. En fait, c'est ton compilateur qui va générer une courte séquence d'instructions (donc un mini-programme) pour y parvenir.

    Pour simplifier au maximum, tu peux considérer que le micro-processeur manipule chaque mot de 32 bits comme s'il s'agissait d'un seul chiffre, travaillant ainsi en « base 4294967295 ». Lorsqu'il fait une addition, la somme de deux nombres 32 bits tient au maximum sur 33 bits. Le bit excédentaire peut alors simplement être retenu dans le bit C (Carry) des flags du micro-processeur et être directement exploitée par d'autres instructions.

    Dans le cas d'une multiplication, le résultat d'un produits de deux nombres 32 bits tient sur 64 bits, au maximum. Ton micro-processeur utilise 2 registres pour sauver le résultat, par exemple EDX et EAX, sur x86. Tu peux alors « poser EAX » et « retenir EDX » comme tu le ferais sur papier avec une multiplication ordinaire en décimal.

    Ça veut dire que c'est surtout une question algorithmique. Je te conseille de jeter un œil à l'assembleur si la façon dont ces choses sont résolues t'intéresse. Tu peux également lire cette discussion.
    donc, lors de l'addition de 2 ints et l'obtention d'un nombre qui ne peut pas être représenté sur 32 bits on ne peut pas stocker le résultat dans un registre ni dans une case mémoire (dans le cas d'une architecture 32 bits).
    Ca simplifie pas les choses.

  4. #4
    Expert confirmé
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Par défaut
    Pas en utilisant les instructions d'addition de int du processeur en tout cas, mais tu peux écrire toi-même des routines de calcul adaptés à tes besoins. GMP est un exemple de bibliothèque permettant de travailler avec de grands entiers.

  5. #5
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 504
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 504
    Par défaut
    Citation Envoyé par Tesing Voir le message
    donc, lors de l'addition de 2 ints et l'obtention d'un nombre qui ne peut pas être représenté sur 32 bits on ne peut pas stocker le résultat dans un registre ni dans une case mémoire (dans le cas d'une architecture 32 bits).
    Ca simplifie pas les choses.
    Si, c'est ce que je t'explique au dessus. Le dernier bit est considéré comme une retenue (ce qu'il est, d'ailleurs, au cours de l'opération) et donc il n'est pas perdu (heureusement), il est gardé dans les flags du CPU et c'est un fonctionnement tout-à-fait normal. En C, évidemment, c'est plus difficile à voir, mais c'est possible. D'une manière générale, si le résultat d'une addition non signée est inférieur à la plus grande des opérandes, c'est qu'il y a eu débordement et tu peux ajouter un « 1 » à gauche de ton résultat.

    Maintenant, il est logique de conserver au cours du temps les résultats des opérations sur des registres du même format. Sinon, si l'on stockait le produit de deux nombres 32 bits sur un registre 64 bits, où stockerait-on le produit de deux nombres 64 bits ? En admettant que l'on ait des registres 128 bits dédiés à cela, où stockerait-on, alors, le produit de ces registres 128 bits ? Il n'y a pas de raison que ça s'arrête.

    D'autre part, le premier des registres d'un micro-processeur est pratiquement toujours un « accumulateur », qui s'appelle d'ailleurs A, ou AX, ou EAX, etc. Le propre d'un accumulateur est de recevoir le résultat d'une opération et de servir immédiatement d'opérande pour l'opération suivante. Par exemple, dans « 5 + 6 + 3 + 9 + 2 », 5 + 6 = 11 ; 11 + 3 = 14 ; 14 + 9 = 23 ; 23 + 2 = 25. Cette manière de faire impose de fait que les opérandes et le registre de sortie soit du même format.

    L'exemple criant est celui d'une calculatrice quatre opérations ordinaire. Quand tu t'en sers pour faire le calcul ci-dessus, c'est ton écran qui sert d'accumulateur. Si cet écran peut afficher, disons, sept chiffres, rien ne t'empêche de faire « 9999999 + 9999999 » et là, le résultat ne pourra pas être affiché, ni même contenu par la calculatrice.

    Tu retrouveras donc le problème du débordement sur tous les calculateurs existants. À toi, soit de faire avec, soit de prévoir le cas en décomposant le calcul. Si tu es sûr d'avoir besoin de calculs exacts sur de très grands nombres, tu peux utiliser une bibliothèque telle que GMP, comme indiqué plus haut, mais le plus sage étant encore de s'assurer à l'avance que tes calculs tiendront toujours sur le format choisi (32 bits devraient être suffisants pour les applications courantes). Sinon, si c'est un problème que tu rencontres a posteriori, c'est qu'il y a probablement une erreur de conception.

  6. #6
    Membre expérimenté
    Avatar de Tesing
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2009
    Messages
    272
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2009
    Messages : 272
    Par défaut
    ok, merci beaucoup pour toutes ces explications, Obsidian.

    J'irai jetter un coup d'oeil sur le forum dédié à l'assembleur pour plus d'information sur les utilisations des registres.

    Je me demande quelle est l'utilisation prévue de la base, du compteur et du registre "data", bien que ce sont des registres généraux, à tout faire.

  7. #7
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 504
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 504
    Par défaut
    Citation Envoyé par Tesing Voir le message
    Je me demande quelle est l'utilisation prévue de la base, du compteur et du registre "data", bien que ce sont des registres généraux, à tout faire.
    C'est une question que tu peux effectivement poser dans le forum Assembleur x86. On scindera la discussion présente si le sujet dérive trop (pour l'instant, cela reste en relation avec ton post initial).

    Intel a fait en sorte, autant que possible, que les noms de ces registres correspondent grosso-modo à leur fonction tout en suivant l'ordre alphabétique. Donc, sur 16 bits, AX = Accu (celui que l'on retrouve partout), BX = Index de Base (≠ BP), CX = Compteur, DX = Donnée. Ce n'est vrai que dans une certaine mesure, et ce n'est pas une règle générale. Sur 68000, par exemple, il y a huit registres A0 à A7 et huit autres D0 à D7.

    Pour répondre à ta question : BX a un rôle dans les modes d'adressage. C'est le seul des quatre premiers registres (ceux en -X) qui pouvait servir de pointeur sur x86 16 bits. BP, pour Base Pointer, peut le faire aussi. Mais BP est généralement utilisé dans la définition d'un cadre de pile : en entrant dans une fonction, on sauvegarde le pointeur de pile dans BP, puis on décale ce pointeur de pile pour faire de la place aux variables locales. Ainsi quelque soit l'état de l'exécution, on accède à ces variables à l'aide d'un offset par rapport au pointeur de base BP. En outre, en cas de sortie en catastrophe (goto, exception C++,…) on peut restaurer l'état initial de la pile en remettant BP dans le pointeur de pile et, de là, quitter la fonction normalement.

    Le registre DX « data », est le registre utilisé par défaut quand il y a une donnée à lire, après l'accumulateur AX. C'est pourquoi les instructions qui, par nature, renvoie une donnée de taille double de celle de leur opérandes (comme la multiplication), utilisent le couple DX:AX. Sinon, c'est le registre utilisé par défaut par les programmeurs car, en dehors de ces cas de figure, il n'est pratiquement jamais modifié par les différentes instructions.

Discussions similaires

  1. convertir en Texte mais dans sa forme entière un nombre long
    Par deca2 dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 19/05/2010, 14h14
  2. Réponses: 4
    Dernier message: 09/06/2009, 14h20
  3. Réponses: 19
    Dernier message: 01/02/2008, 11h54
  4. DBLink et types LONG/LONG RAW
    Par bchristo dans le forum Administration
    Réponses: 7
    Dernier message: 28/04/2004, 12h46
  5. Lire une valeur dans le registre
    Par John.s dans le forum C
    Réponses: 2
    Dernier message: 26/11/2003, 19h55

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo