Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

big/little endian

91 réponses
Avatar
David ROMAN
Est-il possible avoir un code en C capable de detecter le type de
processeur, en de lui forcer l'ecriture ou la lecture d'un fichier
binnaire en little ou big endian indifferement ???


Merci
David

10 réponses

Avatar
Richard Delorme
Anthony Fleury wrote on 22/10/04 :

Une petite question qui va sembler sûrement idiote, que devient ce
type de
code pour des architectures ayant des byte de plus de 8 bits ? est-ce la
bonne manière de faire dans tous les cas ?

En fait je dois avouer que ce type d'architecture «défie» un peu mon
imagination, pour la simple et bonne raison que je n'ai jamais travaillé
dessus, je devrais peut être me remettre à l'architecture et me
documenter
un peu :-)



C'est pas pire qu'un architecture avec des int qui font 32 bits au lieu
des 16 requis. Les 16 bits de poids forts ne doivent pas être utilisés
si on veut écrire du code portable. C'est tout.

Le C, c'est simple :

8 bits -> char
16 bits -> int ou short
32 bits -> long
[C99]
64 bits -> long long

le reste c'est du pipeau.



On peut faire plus simple :
8, 16, 32 bits -> long [C90]
8, 16, 32, 64 bits -> long long [C99]
Comme ça on n'utilise qu'un seul type et on écrit du code portable.
Alors je me demande bien à quoi servent tous ces types : char, short,
int,...

Evidemment, si l'on dispose de tout ces types c'est pour controler
l'usage de la mémoire et/ou les performances du type utilisé. Par
exemple, si j'utilise un système I32LP64 où :
char : 8 bits
short : 16 bits
int : 32 bits
long : 64 bits
et que j'ai besoin d'immenses tableaux, accessible rapidement, avec un
type dont les valeurs vont de -1000000 à +1000000, dois-je utiliser le
type long pour être portable, ou le type int pour éviter le risque de
manquer de mémoire ?
Personnellement je choisis la seconde option, car je préfère un
programme non portable qui marche sur ma machine qu'un programme
portable qui ne marche que sur des machines dont je ne dispose pas.

Celui qui utilise une int pour des grandeurs 32 bits ou un char pour des
grandeurs 16 bits doit être fusillé tout les matins pendant une semaine
avec des balles rouillées.


Attrape moi d'abord :þ

--
Richard


Avatar
Jean-Marc
"Richard Delorme" a écrit dans le message de
news:4179589d$0$15756$
Anthony Fleury wrote on 22/10/04 :



Personnellement je choisis la seconde option, car je préfère un
programme non portable qui marche sur ma machine qu'un programme
portable qui ne marche que sur des machines dont je ne dispose pas.



C'est une opinion défendable, tant que tu ne programmes que pour toi.
Evidemment, c'est inacceptable si ton programme a ne serait ce qu'une
chance sur un million de sortir de ta machine.


Celui qui utilise une int pour des grandeurs 32 bits ou un char pour des
grandeurs 16 bits doit être fusillé tout les matins pendant une semaine
avec des balles rouillées.


Attrape moi d'abord :þ




--
Jean-marc
"There are only 10 kind of people
those who understand binary and those who don't."


Avatar
James Kanze
David ROMAN writes:

|> David ROMAN wrote:

|> > Est-il possible avoir un code en C capable de detecter le type de
|> > processeur, en de lui forcer l'ecriture ou la lecture d'un fichier
|> > binnaire en little ou big endian indifferement ???

|> Je dois mal m'exprimer ... excusez moi ....

|> Bon je vais essayer de me clarifier

|> l'ordre des bits dans un octet ne changent pas selon les differents
|> processeurs (est ce qu'on est ok la dessus ?)

D'abord, il faut dire ce que tu entends par ça. La plupart des
processeurs lisent un octet d'un coup, et ne permet pas l'accès direct à
un bit. Ça n'a donc pas de sens de parler de l'ordre de bits dans un
octet.

Sauf, peut-être, si on utilise les champs de bits, par exemple :

struct S { unsigned b1 : 1 ; unsigned b2 : 2 ; } ;

Et là, ça dépend du compilateur -- certain mettra b1 aux poids faibles,
d'autres au poids forts.

|> Par contre l'ordre des octets dans un mot ou un dble mot ou un dble
|> dble mot changent

Là aussi, strictement parlant, il faudrait définir ce qu'on veut dire.
Sur la plupart des machines, quand je lis un mot, je lis un mot, non des
octets.

Dans la mésure où le C offre l'adressage direct aux octets, en revanche,
il y a un consensus qu'on parle de la façon que les octets apparaissent
si j'y accède au moyen d'un char*. Mais c'est un peu tricher, quand
même.

|> c a d

|> => pour un court soit un int sur 2 octets octect_1,octect_2 devient
|> octect_2,octect_1
|> pour un long octect_1,octect_2,octect_3,octect_4 devient
|> octect_4,octect_3,octect_2,octect_1
|> et pour un long long
|> octect_1,octect_2,octect_3,octect_4,octect_5,octect_6,octect_7,octect_8
|> devient
|> octect_4,octect_3,octect_2,octect_1,octect_8,octect_7,octect_6,octect_5

|> Est ce que je raconte des anneries ou ai je bien tout compris
|> jusqu'a present ????

Moi, j'avoue que je ne comprends pas trop. Un int, c'est un int. Ce
n'est pas des octets. Quand je veux lire un int, je lis un int, et non
une suite d'octets.

Autrefois, on parlait un peu de l'ordre des octets, parce que les
déboggueurs ne savait sortir que les octets. Depuis qu'on a les
déboggueurs symboliques qui connaissaissent aussi le type de la variable
au départ, un int est un int, et on n'en parle plus.

--
James Kanze
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34
Avatar
gl
James Kanze wrote:
|> c a d

|> => pour un court soit un int sur 2 octets octect_1,octect_2 devient
|> octect_2,octect_1
|> pour un long octect_1,octect_2,octect_3,octect_4 devient
|> octect_4,octect_3,octect_2,octect_1
|> et pour un long long
|> octect_1,octect_2,octect_3,octect_4,octect_5,octect_6,octect_7,octect_8
|> devient
|> octect_4,octect_3,octect_2,octect_1,octect_8,octect_7,octect_6,octect_5

|> Est ce que je raconte des anneries ou ai je bien tout compris
|> jusqu'a present ????

Moi, j'avoue que je ne comprends pas trop. Un int, c'est un int. Ce
n'est pas des octets. Quand je veux lire un int, je lis un int, et non
une suite d'octets.



Et comment fais tu alors pour lire un int dans fichier ecrit par une
autre architecture ou pour relier en reseau deux architectures
differentes ou les int n'auront pas forcement la meme taille, le meme
boutisme, etc. ?

Avatar
James Kanze
Pierre Maurette writes:

|> Au départ, il faut définir l'atome de mémoire, c'est à dire la plus
|> petite quantité adressable, correspondant à une unité d'adresse.

Sur la plupart des processeurs actuels, il n'y a pas qu'une seule taille
qui correspond à une unité d'adresse. Un 80x86 moderne, par exemple, est
capable de lire des unités de 8, 16, 32 ou 64 bits d'un coup, sans les
découper en octets.

|> En x86, c'est l'octet.

|> Ensuite, il faut voir pour chaque taille plus grande de donnée gérée
|> par le processeur dans quel ordre celui-ci va les écrire en mémoire.
|> Soit le WORD (16 bits) 0x1234 à écrire (ou lire) à l'adresse A. Il
|> occupera A et A+1. Mais il peut écrire soit les poids faibles (0x34)
|> en A et les poids forts (0x12) en A+1 (little endian), soit
|> l'inverse (big endian). Si on représente la mémoire adresses
|> croissantes de la gauche vers la droite, ça donne:
|> little endian: 34 12
|> big endian: 12 34
|> De même pour le DWORD 0x12345678, écrit comme un DWORD:
|> little endian: 78 56 34 12
|> big endian: 12 34 56 78

Ou 56 78 12 34, comme c'était le cas sur certains processeurs ou avec
certains compilateurs (sur 8086, par exemple).

|> Donc, en dehors des cas d'échanges entre machines, l'endianité nous
|> intéressera (et éventuellement posera problème) quand la lecture et
|> l'écriture dans une même zone mémoire se fera au travers de données
|> de tailles différentes (en C, par transtypage de pointeur). En
|> little endian, après avoir écrit le DWORD 0x12345678 en A, nous
|> lirons les BYTE 0x78, 0x56, 0x34, 0x12 dans cet ordre aux adresses
|> A, A+1, A+2 et A+4.

Mais la vraie question reste. Si on a écrit à travers une entité de 32
bits, pourquoi est-ce qu'on lirait autrement. En fait, le résultat n'est
pas défini (sauf que c'est garanti cohérent).

|> Et les WORD 0x5678, 0x1234 aux adresses A et A+2. Dernière remarque:
|> il est courant d'entendre que "little endian", c'est "à l'envers".

Marrant, moi, j'ai toujours entendu le contraire.

Il est courant d'entendre que celui dont on a le moins l'habitude est à
l'envers.

|> Ce n'est pas plus vrai que le contraire. Un avantage de little
|> endian: nous avons à l'adresse A un DWORD dont la valeur est <= 255,
|> par exemple 69, c'est à dire 0x00000045. Nous trouvons à l'adresse A
|> également un WORD et un BYTE de même valeur. Vu comme ça, little
|> endian est "plus logique" que big endian. </hors C>

|> Question aux spécialistes du C: est-il possible de concevoir une
|> machine dont l'atome mémoire (donc la base de l'endianité) serait de
|> 16 bits et la taille du char de 8 bits ?

Je ne sais pas si c'est possible, mais je m'en suis servi. C'est la
raison principale pourquoi il est permis que les pointeurs aient de
tailles différentes -- un char* doit comporter d'avantage
d'informations, pour pouvoir savoir à quelle partie du mot accéder.

(En passant, j'espère que tu ne prends pas mal mes critiques. J'estîme
que tu as quand même montré une meilleur compréhesion du problème que la
plupart des gens.)

--
James Kanze
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34
Avatar
Jean-Marc Bourguet
gl writes:

Et comment fais tu alors pour lire un int dans fichier
ecrit par une autre architecture ou pour relier en reseau
deux architectures differentes ou les int n'auront pas
forcement la meme taille, le meme boutisme, etc. ?


Voir par exemple.

A+

--
Jean-Marc
FAQ de fclc: http://www.isty-info.uvsq.fr/~rumeau/fclc
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Avatar
Jean-Marc Bourguet
"Jean-Marc" writes:

"Richard Delorme" a écrit dans le message de
news:4179589d$0$15756$
Anthony Fleury wrote on 22/10/04 :



Personnellement je choisis la seconde option, car je préfère un
programme non portable qui marche sur ma machine qu'un programme
portable qui ne marche que sur des machines dont je ne dispose pas.



C'est une opinion défendable, tant que tu ne programmes
que pour toi. Evidemment, c'est inacceptable si ton
programme a ne serait ce qu'une chance sur un million de
sortir de ta machine.


Mais non. C'est une opinion défendable dans beaucoup de
contextes.

A+

--
Jean-Marc
FAQ de fclc: http://www.isty-info.uvsq.fr/~rumeau/fclc
Site de usenet-fr: http://www.usenet-fr.news.eu.org



Avatar
James Kanze
Jean-Marc Bourguet writes:

|> Pierre Maurette writes:

|> > Question aux spécialistes du C: est-il possible de concevoir une
|> > machine dont l'atome mémoire (donc la base de l'endianité) serait
|> > de 16 bits et la taille du char de 8 bits ?

|> Oui. On utilise alors des pointeurs vers char qui contiennent plus
|> d'info. C'est a cause de ce genre de machines qu'on peut avoir
|> sizeof (int*) < sizeof(char*). Les C pour PDP-10 que j'ai vu (j'ai
|> pas utilise le C sur ces machines mais des compilateurs C pour elles
|> existent) ont CHAR_BIT==9 et sizeof(int)==4; mais ces machines
|> etaient utilise avec de l'ASCII, 7 bits, 5 char par mot + 1 bit de
|> padding ou du 6 bits , 6 char par mots et il me semble me souvenir
|> qu'il etait possible de mettre les compilo C dans un mode plus
|> compatible avec le systeme meme si moins conforme a l'ISO.

Sur le C pour le PDP-10 que j'ai vu, la taille des pointeurs était
toujours 24 bits. En revanche, il n'y avait que les bits de poids
faibles (j'en oublies combien) qui servait pour l'adressage des mots ;
certains bits de poids fort servaient à selectionner les bytes dans le
mot, le cas échéant (les char*). Ce qui donnait la situation que si p
était un char*, "(int)p > (int)( p+1 )" pour certains valeurs de p.

(Sur le PDP-10, grosso modo, le poids fort d'un mot était ignoré dans la
plupart des adressages. Dans le cas des instructions load byte et store
byte, en revanche, une partie du poid fort spécifier l'offset du premier
bit, et une autre partie le nombre de bits concerné. En C, évidemment,
le nombre de bits concerné était toujours 9, mais dans la plupart des
autres langages, on utilisait 6.)

|> Alternativement on peut naturellement les faire fonctionner avec des
|> chars equivalent au mot.

C'était quand même assez rare sur les machines à vocation générale.

--
James Kanze
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34
Avatar
James Kanze
Jean-Marc Bourguet writes:

|> Il y a quelques processeurs (en fait seul le 8051 me vient a
|> l'esprit pour le moment) qui permette d'acceder aux bits
|> individuellement. Dans ces cas l'ordre peut avoir de l'importance.

Et le PDP-10 ?

--
James Kanze
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34
Avatar
James Kanze
Jean-Marc Bourguet writes:

|> cedric writes:

|> > Jean-Marc Bourguet wrote:

|> > > Il y a quelques processeurs (en fait seul le 8051 me vient a
|> > > l'esprit pour le moment) qui permette d'acceder aux bits
|> > > individuellement. Dans ces cas l'ordre peut avoir de
|> > > l'importance.

|> > Le 386 et successeurs ont aussi quelques instructions pour accéder
|> > à la mémoire en bits (bc par exemple, qui si ma mémoire est bonne
|> > copie dans le flag de retenu le xième bit en partant de l'adresse
|> > donnée, x pouvant etre > à 32).

|> > Pour ces instructions, l'ordre des bits est celui "conventionnel"
|> > : le bit "0" est le bit de poids faible du premier octet. Là
|> > encore le little endianess s'avère pratique.

|> Ce sont des instructions de manipulation de bits. Le 8051 peut
|> acceder a des bits individuels en memoire (pour une partie de
|> celle-ci) sans charger le contenu dans un registre.

|> Dans le genre, il y a le 68000 (processeur grand boutien) qui si
|> j'ai bonne memoire a des instructions de manipulation de bits petit
|> boutiennnes et d'autres grand boutiennes (et je ne veux pas dire des
|> versions d'une meme instruction...)

Que j'y pense, le VAX avait (et je suppose, a toujours) des instructions
pour lire n bits à partir d'une adresse et un offset de bits. Dans la
première version de compress que j'ai vu, on s'en servait, moyennant un
petit coup de asm, pour insérer et extraire les bits dans le flux --
c'était nettement plus rapide que tout ce qu'on aurait pu écrire en C.

--
James Kanze
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34