Endianness: Διαφορά μεταξύ των αναθεωρήσεων

Περιεχόμενο που διαγράφηκε Περιεχόμενο που προστέθηκε
εμπλουτισμός με παραδείγματα στην C
Γραμμή 1:
[[Εικόνα:Little-Endian.svg|thumb|right|300px|Little-endian: Τo λιγότερο σημαντικ;o byte αποθηκεύεταιι στις "μικρότερη" θέση μνήμης.]]
[[Εικόνα:Big-Endian.svg|thumb|right|300px|Big-endian: Το σημαντικότερο byte αποθηκεύεται στην "μικρότερη" θέση μνήμης.]]
Ο όρος '''endianness''' χρησιμοποιείται στην [[Πληροφορική|επιστήμη των υπολογιστών]] για τον τρόπο αποθήκευσης των σειρών [[Byte|bytes]] μέσα στην μνήμη του [[Ηλεκτρονικός υπολογιστής|ηλεκτρονικού υπολογιστή]]. Υπάρχουν δύο τρόποι αναπαράστασης των bytes που αναπαριστάται ένας αριθμός μέσα στην εσωτερική μνήμη του υπολογιστή: η αναπαράσταση ''big-endian'' και η αναπαράσταση ''little-endian''. Οι υπολογιστές με επεξεργαστές 80x86 από την Intel όπως και κλώνοι αυτών χρησιμοποιούν αναπαράσταση little-endian ενώ υπολογιστές όπως οι Sun SPARC, Motorola 68K ή η οικογένεια των PowerPC χρησιμοποιούν αναπαράσταση big-endian. Τα πρωτόκολλα δικτύου υπολογιστών κάνουν τους κατάλληλους μετασχηματισμούς δεδομένων δύο υπολογιστές με διαφορετικό endianness επικοινωνούν. <ref name="ibm_endianness"/>
 
==Ορολογία==
Γραμμή 9:
Οι άνθρωποι αναπαριστούν του ακέραιους αριθμούς στο [[Δεκαδικό σύστημα|δεκαδικό σύστημα αρίθμησης]] με τιμές 0-9 και τοποθετούν το πιο σημαντικό ψηφία στην αρχή αριστερά (στον αριθμό 2356 το σημαντικότερο ψηφίο είναι το 2 που αναπαριστά τις χιλιάδες, ενώ το λιγότερο σημαντικό ψηφίο είναι το 6). Οι ηλεκτρονικοί υπολογιστές αναπαριστούν τους αριθμούς στο [[Δυαδικό σύστημα|δυαδικό σύστημα αρίθμησης]] όπου υπάρχου δύο μόνο ψηφία, το 0 και το 1. Η [[Μνήμη υπολογιστή|μνήμη του υπολογιστή]] είναι σχεδιασμένη ώστε να αποθηκεύει ομάδες 8 δυαδικών ψηφίων γνωστά ως [[Byte|bytes]] (υπάρχουν και υπολογιστές οι οποίοι αποθηκεύουν περισσότερα από 8 δυαδικά ψηφία αλλά είναι σπάνιοι και έτσι μπορεί να γίνει παραδοχή ότι κάθε διεύθυνση μνήμης αποθηκεύει 8 δυδαδικά ψηφία, δηλαδή ένα byte <ref name="ibm_endianness">{{cite web | url=http://www.ibm.com/developerworks/aix/library/au-endianc/ | title=Writing endian-independent code in C - Don't let endianness "byte" you | accessdate=2013-04-24 | author=Harsha S. Adiga | date=2007-04-24 | publisher=Ibm.com}}</ref>). Ένα byte μπορεί να αποθηκεύσει 0-255 διαφορετικές τιμές (από 0000 0000 έως 1111 1111 τιμές). Ένας [[Ακέραιος αριθμός|ακέραιος αριθμός]] μεγαλύτερος από 255 θα χρειαστεί περισσότερα από ένα bytes για να αποθηκευτεί στην μνήμη του υπολογιστή. Επίσης στους σύγχρονους υπολογιστές με 32bit ή 64bit με σειρά 32 ή 64bit αποθηκεύεται αντίστοιχα σε 4 ή 8 bytes (4*8bits = 32, 8*8bits= 64). Υπάρχουν δύο τρόποι / '''endianess''' με τους οποίους μια σειρά bytes μπορεί να αποθηκευτεί στις θέσεις μνήμης (η κάθε θέση αποθηκεύει 1 byte) <ref name="Computer_systems_book_Addressing_and_Byte_Ordering">{{cite book | title=Computer Systems - A Programmer's Perspective | author=Randal E. Bryant, David R. O’Hallaron | year=2011 | publisher=Prentice Hall | pages=39-46 | isbn=978-0-13-610804-7}}</ref>:
 
* '''Big-endian''': Το σημαντικότερο byte αποθηκεύεται στην "μικρότερη" θέση μνήμης.
* '''Little-endian''': Το λιγότερο σημαντικότερο byte αποθηκεύεται στην "μικρότερη" θέση μνήμης.
 
Ο προγραμματιστής κατά τον προγραμματισμό σε μια γλώσσα υψηλού επιπέδου δεν ασχολείται με τον τρόπο που αποθηκεύονται οι τιμές των μεταβλητών (είτε με την μορφή big-endian ή little-endian) μέσα στην μνήμη του υπολογιστή. Το λειτουργικό σύστημα και ο [[Μεταγλωττιστής|μεταγλωττιστής]] που θα μετατρέψει τον πηγαίο κώδικα (από τη γλώσσας υψηλού επιπέδου) σε γλώσσα μηχανής (assembly) θα αποφασίσει αν θα χρησιμοποιηθεί big-endian ή little-endian αναπαράσταση. Πρόβλημα με την αναπαράσταση big-endian ή little-endian δημιουργείται όταν ένας υπολογιστής επικοινωνεί με ένα άλλο υπολογιστή μέσω ενός [[Δίκτυο υπολογιστών|δικτύου]] και χρησιμοποιεί διαφορετικό ''endianness''. Για να αποφεύγονται τα προβλήματα αυτά στην επικοινωνίες μέσω δικτύου χρησιμοποιούνται τα πρωτόκολλα επικοινωνίας και γίνονται οι απαραίτητες μετατροπές στην κωδικοποίηση ώστε να επιτευχθεί η δικτυακή μεταφορά δεδομένων. <ref name="Computer_systems_book_Addressing_and_Byte_Ordering"/>
Γραμμή 29:
| '''little''' || ''λιγότερο σημαντικό'' || '''...''' ||''σημαντικότερο'' || 5B 47 15 ||style="text-align: left;"| Το λιγότερο σημαντικό byte, δηλαδή το 5Β μπαίνει στην "μικρότερη" θέση μνήμης.
|}
 
==Παράδειγμα προβλήματος endianness στην C==
Το παρακάτω κομμάτι κώδικα μεταγλωττίζεται χωρίς λάθη και σε υπολογιστές όπου χρησιμοποιείται little-endian και σε υπολογιστές όπου χρησιμοποιείται big-endian κωδικοποίηση. Το πρόγραμμα αυτό αρχικοποιεί μια δομή με τρεις μεταβλητές (δύο συμβολοσειρές/πίνακες χαρακτήρων και ενός ακεραίου αριθμού) και στην συνέχεια την γράφει στο εξωτερικό αρχείο data.one.
<source lang="C">
#include <stdio.h>
#include <string.h>
 
int main (int argc, char* argv[]) {
FILE* fp;
 
/* Παράδειγμα μιας δομής δεδομένων */
struct {
char one[4];
int two;
char three[4];
} data;
 
/* Αρχικοποίηση της δομής data με δεδομένα */
strcpy (data.one, "foo");
/* Δεκαεξαδικός αριθμός 01234567
data.two = 0x01234567;
strcpy (data.three, "bar");
 
/* Εγγραφή των δεδομένων σε ένα εξωτερικό αρχείο */
fp = fopen ("output", "wb");
if (fp) {
fwrite (&data, sizeof (data), 1, fp);
fclose (fp);
}
}
</source>
Οι συμβολοσειρές/αλφαριθμητικά (strings) "foo" και "bar" θα αποθηκευτούν με τον ίδιο τρόπο και σε μηχανήματα όπου χρησιμοποιείται little-endian αλλά και σε υπολογιστές όπου χρησιμοποιείται big-endian. Ο δεκαεξαδικός αριθμός (01234567)<sub>16</sub> (δηλαδή ο 0x01234567) θα γραφτεί με διαφορετική κωδικοποίηση σε υπολογιστή little-endian από ότι σε υπολογιστή big-endian. Αυτό αποτελεί πρόβλημα, αν αργότερα το αρχείο αυτό διαβαστεί σε υπολογιστή με διαφορετική κωδικοποίηση endianness. <ref name="ibm_endianness"/>
 
==Έλεγχος endianness στην C==
Ο παρακάτω κώδικας ελέγχει την κωδικοποίηση endianness του υπολογιστή και μας δείχνει πως κωδικοποιείται ο δεκαεξαδικός αριθμός (01234567)<sub>16</sub> μέσα στις θέσεις μνήμης του υπολογιστή.
<source lang="c">
#include <stdio.h>
 
#define LITTLE_ENDIAN 0
#define BIG_ENDIAN 1
 
void show_bytes (char *start, int len) {
int i;
 
for (i=0;i<len;i++)
// %p Print pointer \t Tab %x Print value as hex \n New line
printf("%p\t0x%.2x\n",start+i, *(start+i));
printf("\n");
}
 
void show_int (int x) {
show_bytes( (char *) &x, sizeof(int));
}
 
int endianness() {
int i = 1;
// παίρνει την διεύθυνση του i και την κάνει cast
// στον δείκτη char *p.
char *p = (char *)&i;
 
if (p[0] == 1)
return LITTLE_ENDIAN;
else
return BIG_ENDIAN;
}
 
int main (int argc, char* argv[]) {
 
printf("Ο υπολογιστής χρησιμοποιεί την κωδικοποίηση: ");
if (endianness()==BIG_ENDIAN)
printf("big-endian \n");
else
printf("little-endian \n");
 
i=0x01234567;
printf("ο αριθμός int i=0x01234567 (δηλαδή ο %.18i στο δεκαδικό) έχει αποθηκευτεί ως:\n",i);
show_int(i);
return 0;
}
</source>
 
Παρακάτω φαίνονται οι θέσεις μνήμης (σε κάθε εκτέλεση του προγράμματος εμφανίζονται διαφορετικές θέσεις) και οι τιμές που αποθηκεύτηκαν. Το λιγότερο σημαντικό ψηφίο του αριθμού (01234567)<sub>16</sub> το (67)<sub>16</sub> αποθηκεύτηκε στην "μικρότερη" θέση μνήμης, εδώ στην διεύθυνση 0xbfab6ff0 ή (bfab6ff0)<sub>16</sub> κάτι το οποίο δείχνει κωδικοποίηση "little-endian".
<pre>
Ο υπολογιστής χρησιμοποιεί την κωδικοποίηση: little-endian
ο αριθμός int i=0x01234567 (δηλαδή ο 000000000019088743 στο δεκαδικό) έχει αποθηκευτεί ως:
0xbfab6ff0 0x67
0xbfab6ff1 0x45
0xbfab6ff2 0x23
0xbfab6ff3 0x01
</pre>
 
==Παραπομπές==
Ανακτήθηκε από "https://el.wikipedia.org/wiki/Endianness"