Les processeurs Intel (et peut-être quelques autres) utilisent le format little endian pour le stockage.
Je me demande toujours pourquoi quelqu'un voudrait stocker les octets dans l'ordre inverse. Ce format présente-t-il des avantages par rapport au format big endian?
architecture
storage
advantages
endianness
Biscuit salé
la source
la source
Réponses:
Il y a des arguments dans les deux sens, mais un point est que, dans un système little-endian, l'adresse d'une valeur donnée en mémoire, d'une largeur de 32, 16 ou 8 bits, est la même.
En d'autres termes, si vous avez en mémoire une valeur de deux octets:
prendre ce '16' comme valeur 16 bits (c 'short' sur la plupart des systèmes 32 bits) ou comme valeur 8 bits (généralement c 'char') ne change que l'instruction d'extraction que vous utilisez - pas l'adresse que vous extrayez de.
Sur un système big-endian, avec ce qui précède, présenté comme suit:
vous devrez incrémenter le pointeur, puis effectuer l'opération d'extraction plus étroite sur la nouvelle valeur.
En bref, "sur les systèmes little endian, le casting n’est pas une opération".
la source
Le big-endian et le petit-endian ne sont qu'un "ordre normal" et un "ordre inverse" d'un point de vue humain, et seulement si tout cela est vrai ...
Ce sont toutes des conventions humaines qui ne comptent pas du tout pour un processeur. Si vous deviez conserver les numéros 1 et 2 et le flip 3, le petit-endian semblerait «parfaitement naturel» aux personnes qui lisent l'arabe ou l'hébreu, qui sont écrites de droite à gauche.
Et il y a d'autres conventions humaines qui font du big-endian qui ne semblent pas naturelles, comme ...
À l'époque où je programmais principalement 68K et PowerPC, je considérais le big-endian comme étant "correct" et le petit-endian comme étant "faux". Mais comme je travaille davantage avec ARM et Intel, je me suis habitué au petit-endian. Cela n'a pas d'importance.
la source
OK, voici la raison qui m’a été expliquée: Addition et soustraction
Lorsque vous ajoutez ou soustrayez des nombres sur plusieurs octets, vous devez commencer par l'octet le moins significatif. Si vous ajoutez deux nombres de 16 bits, par exemple, il peut y avoir un report de l'octet le moins significatif à l'octet le plus significatif. Vous devez donc commencer par l'octet le moins significatif pour voir s'il y a un report. C'est la même raison pour laquelle vous commencez par le chiffre le plus à droite lorsque vous effectuez une addition longue. Vous ne pouvez pas partir de la gauche.
Considérons un système 8 bits qui récupère les octets de manière séquentielle à partir de la mémoire. S'il extrait en premier l' octet le moins significatif , il peut commencer à faire l'addition pendant que l'octet le plus significatif est extrait de la mémoire. Ce parallélisme est la raison pour laquelle les performances sont meilleures dans les versions plus petites, telles que les systèmes. S'il devait attendre que les deux octets soient extraits de la mémoire ou les récupérer dans l'ordre inverse, cela prendrait plus de temps.
Ceci est sur les anciens systèmes 8 bits. Sur un processeur moderne, je doute que l’ordre des octets fasse toute la différence et nous utilisons little endian uniquement pour des raisons historiques.
la source
Avec les processeurs 8 bits, il était certainement plus efficace, vous pouvez effectuer une opération 8 ou 16 bits sans avoir besoin de code différent ni de mettre en tampon des valeurs supplémentaires.
C'est encore mieux pour certaines opérations d'addition si vous traitez un octet à la fois.
Mais il n'y a aucune raison pour que big-endian soit plus naturel - en anglais, vous utilisez treize (petit endian) et vingt-trois (big endian)
la source
0x12345678
est stocké comme78 56 34 12
alors que sur un système BE, c’est12 34 56 78
(l’octet 0 est à gauche, l’octet 3 à droite). Notez que plus le nombre est grand (en bits), plus il nécessite d’échange; un mot nécessiterait un échange; un DWORD, deux passes (trois swaps totaux); un mot QWORD trois passes (7 au total), et ainsi de suite. C'est-à-dire des(bits/8)-1
échanges. Une autre option est de les lire en avant et en arrière (lire chaque octet en avant, mais en balayant tout le # en arrière).La convention de date japonaise est "big endian" - aaaa / mm / jj. C'est pratique pour les algorithmes de tri, qui peuvent utiliser une simple comparaison de chaîne avec la règle habituelle du premier caractère est le plus significatif.
Quelque chose de similaire s'applique aux nombres big-endian stockés dans un enregistrement de champ le plus significatif. L'ordre de signification des octets dans les champs correspond à la signification des champs dans l'enregistrement. Vous pouvez donc utiliser a
memcmp
pour comparer les enregistrements sans vous soucier de savoir si vous comparez deux mots longs, quatre mots ou huit octets distincts.Si vous inversez l'ordre de signification des champs, vous obtenez le même avantage, mais pour les nombres little-endian plutôt que big-endian.
Cela a bien sûr très peu de signification pratique. Que votre plate-forme soit big-endian ou little-endian, vous pouvez commander des champs d'enregistrements pour exploiter cette astuce si vous en avez vraiment besoin. C'est juste pénible si vous devez écrire du code portable .
Je peux aussi bien inclure un lien vers l'appel classique ...
http://tools.ietf.org/rfcmarkup?url=ftp://ftp.rfc-editor.org/in-notes/ien/ien137.txt
MODIFIER
Une pensée supplémentaire. Une fois, j'ai écrit une grande bibliothèque de nombres entiers (pour voir si je pouvais le faire), et pour cela, les morceaux de 32 bits sont stockés dans un ordre little-endian, quelle que soit la manière dont la plate-forme ordonne les bits dans ces morceaux. Les raisons étaient ...
De nombreux algorithmes commencent tout naturellement à fonctionner aux extrémités les moins significatives et souhaitent que ces extrémités soient mises en correspondance. Par exemple, les portées se propagent à des chiffres de plus en plus significatifs, il est donc logique de commencer par la fin la moins significative.
Augmenter ou réduire une valeur signifie simplement ajouter / supprimer des morceaux à la fin - pas besoin de décaler des morceaux vers le haut ou le bas. La copie peut encore être nécessaire en raison de la réallocation de la mémoire, mais pas souvent.
Bien entendu, cela n’a aucune pertinence pour les processeurs - jusqu’à ce que les processeurs soient conçus avec un support matériel gros-entier, c’est une pure bibliothèque.
la source
Personne d'autre n'a répondu POURQUOI cela pourrait être fait, beaucoup de choses sur les conséquences.
Prenons un processeur 8 bits capable de charger un seul octet de la mémoire dans un cycle d'horloge donné.
Maintenant, si vous voulez charger une valeur de 16 bits dans (par exemple) le registre unique et unique de 16 bits que vous avez - c’est-à-dire le compteur de programme, un moyen simple de le faire est:
le résultat: vous n'incrémentez jamais uniquement l'emplacement de recherche, vous ne chargez que dans la partie inférieure de votre registre le plus large, et il vous suffit de pouvoir passer à gauche. (Bien sûr, le déplacement à droite est utile pour les autres opérations, donc celle-ci est un peu un spectacle parallèle.)
La conséquence en est que les éléments 16 bits (double octet) sont stockés dans l’ordre Most..Least. C'est-à-dire que l'adresse la plus petite a l'octet le plus significatif - le gros endian.
Si vous essayez plutôt de charger avec little endian, vous devrez charger un octet dans la partie inférieure de votre registre large, puis charger l'octet suivant dans une zone intermédiaire, le déplacer, puis le placer en haut de votre registre plus large. . Ou utilisez un arrangement plus complexe de gating pour pouvoir charger sélectivement dans l'octet supérieur ou inférieur.
En essayant d’aller un peu en arrière, vous avez besoin de plus de silicium (commutateurs et portes) ou de plus d’opérations.
En d’autres termes, en ce qui concerne le rapport qualité-prix, jadis, vous obtenez plus de rendement pour la plupart des performances et la plus petite surface de silicium.
De nos jours, ces considérations sont à peu près hors de propos, mais des choses comme le remplissage de pipeline peuvent encore être un gros problème.
Quand il s’agit d’écrire s / w, la vie est souvent plus facile avec l’adressage little endian.
(Et les grands processeurs endian ont tendance à être grand endian en termes de l' ordre des octets et peu endian en termes de bits-en-octets. Mais certains processeurs sont étranges et utiliseront grand peu endian la commande ainsi que l' ordre des octets. Cela rend la vie très intéressant pour le concepteur h / w qui ajoute des périphériques mappés en mémoire mais n’a aucune autre conséquence pour le programmeur.)
la source
jimwise a fait valoir un bon point. Il y a un autre problème, en little endian vous pouvez faire ce qui suit:
Plus simple pour les programmeurs qui ne sont pas affectés par l'inconvénient évident des emplacements échangés en mémoire. Personnellement, je trouve que le big endian est l’inverse de ce qui est naturel :). 12 devrait être stocké et écrit comme 21 :)
la source
for(i=0; i<4; i++) { num += data[i] << (24 - i * 8); }
correspond àmove.l data, num
un processeur big endian.Le nombre décimal est écrit big endian. C’est aussi la façon dont vous l’écrivez en anglais. Vous commencez par le chiffre le plus significatif, puis le chiffre le plus significatif au moins significatif. par exemple
est mille deux cent trente quatre.
C'est ainsi que big endian est parfois appelé l'ordre naturel.
En little endian, ce nombre serait un, vingt, trois cent quatre mille.
Cependant, lorsque vous effectuez une opération arithmétique telle qu'une addition ou une soustraction, vous commencez par la fin.
Vous commencez avec 4 et 7, écrivez le chiffre le plus bas et rappelez-vous le report. Ensuite, vous ajoutez 3 et 6, etc. Pour ajouter, soustraire ou comparer, il est plus simple à implémenter, si vous avez déjà la logique de lire la mémoire dans l’ordre, si les nombres sont inversés.
Pour prendre en charge big endian de cette façon, vous avez besoin d'une logique pour lire la mémoire à l'envers ou vous avez un processus RISC qui n'opère que sur des registres. ;)
Une grande partie de la conception Intel x86 / Amd x64 est historique.
la source
Le big-endian est utile pour certaines opérations (comparaisons de "bignums" d'égales longueurs d'octets). Little-endian pour les autres (en ajoutant éventuellement deux "bignums"). En fin de compte, cela dépend de la configuration du matériel de la CPU, il s’agit généralement de l’une ou de l’autre (certaines puces MIPS étaient, IIRC, commutables au démarrage pour être LE ou BE).
la source
Lorsque seuls le stockage et le transfert avec des longueurs variables sont impliqués, sans arithmétique à valeurs multiples, alors LE est généralement plus facile à écrire, tandis que BE est plus facile à lire.
Prenons une conversion entre chaînes (et retour) comme exemple spécifique.
Lorsque l'int est converti en chaîne, le chiffre le moins significatif est plus facile à extraire que le chiffre le plus significatif. Tout peut être fait dans une boucle simple avec une condition de fin simple.
Maintenant, essayez la même chose dans l'ordre BE. Vous avez généralement besoin d'un autre diviseur qui détient la plus grande puissance de 10 pour le nombre spécifique (ici 100). Vous devez d’abord trouver ceci, bien sûr. Beaucoup plus de choses à faire.
La conversion de chaîne en int est plus facile à faire dans BE, lorsqu'elle est effectuée en tant qu'opération d'écriture inversée. Write stocke le dernier chiffre le plus significatif, il doit donc être lu en premier
Maintenant, faites la même chose dans l'ordre. Encore une fois, vous auriez besoin d'un facteur supplémentaire commençant par 1 et multiplié par 10 pour chaque chiffre.
Ainsi, je préfère généralement utiliser BE pour le stockage, car une valeur est écrite exactement une fois, mais lue au moins une fois et peut-être plusieurs fois. Pour sa structure plus simple, j’utilise aussi généralement la route pour convertir en LE puis inverser le résultat, même s’il écrit la valeur une seconde fois.
Un autre exemple de stockage BE serait le codage UTF-8, et bien d’autres.
la source