Pentru Byte (endianness), dsp, programare

Notă: procesor ARM poate fi orice arhitectura endian mare, sau puțin endian, în funcție de tipul de cip, dar cel mai adesea este mare endian. arhitectura PowerPC poate fi configurat să funcționeze fie în mod endian mare, sau puțin endian, dar Linux este folosit doar endian mare.

[De ce ar trebui să vă faceți griji despre endianness]

După cum sa menționat deja, ordinea de octeți la un nivel scăzut în sistem este complet transparent pentru programator (aproximativ endianness pot uita de multe ori). Cu toate acestea, poate exista o problemă atunci când datele sunt schimbate cu un alt sistem, deoarece celălalt sistem se poate aștepta pentru a vedea date într-o unitate de stocare în ordine inversă.

De exemplu, dacă nu se poate prezice în avans tipul de sistem la un capăt al unei conexiuni la rețea, protocoale de rețea trebuie să fie utilizate pentru a determina în prealabil ordinea de octeți utilizate pentru a stoca valori de mai mulți octeți în header-ul pachetului. În acest caz, ordinea de octet se numește ordinea octet de rețea (ordinea octet de rețea) și TCP / IP, acesta va fi mare endian. Astfel, sistemul convertește pachetele care provin de la octetul comanda de stocare a datelor locale în rețea. După aceea, sistemul de recepție convertește datele de la comanda octet de rețea la un local. În practică, atunci când există cerințe stricte pentru viteză și este cunoscut faptul că ordinea de octet locală este aceeași ca o rețea, operațiunea de conversie este aruncată în vederea optimizării.

Un alt exemplu bun - USB Protocol. în care ordinea octet pentru cantitățile multibyte puțin endian.

[Cum se determină prin calcul endianness]

Puteți scrie un program simplu care va determina ordinea de octeți în sistemul utilizat.

Liniile 1..4 definesc foo variabilă, care poate fi accesat fie ca la numărul de tip int (tip int aproape întotdeauna compus din mai multe bytes), sau ca o matrice de caractere de caractere. Pe linia 6, variabila este inițializată cu o valoare întreagă de 1, astfel încât cel puțin un octet în numărul multibyte va fi egal cu 1 (octetul cel mai puțin semnificativ), precum și toate celelalte octet semnificativ va fi zero. Dacă octet 0 matrice cel mai puțin semnificativ, va fi egal cu 1, ceea ce înseamnă că sistemul endian mic. Dacă octet 0 matrice cel mai semnificativ octet, acesta va fi zero, și înseamnă sistemul endian mare.

Kernel definește diferitele tipuri de variabile și macro pentru procesarea valorilor, care depind de ordinea de octet, care diferă de sistemul actual utilizat de către procesor.

Următorii identificatori corespund tip U16. u32 si u64. cu excepția cazului în care acestea sunt definite cu bit (bitwise) atribut care este utilizat pentru a restricționa le folosi ca numere întregi. utilitate bitwise-atribut utilizează rare, pentru a se asigura că variabila este transformată într-un procesor de tip local, înainte de a efectua alte peste o variabilă (nesigur nesigur,) operare.

Următoarele tipuri pot fi folosite pentru variabile dependente de endian, după conectarea Linux / kernel.h header-fișier.

[Macros pentru transformări]

Există o multitudine de macro-uri pentru a converti ordinea de octet utilizat de procesorul curent în ordine, fie mare, sau puțin endian. În plus, pentru fiecare tip de conversie are macro-uri separate pentru valorile 16-, 32- și 64-biți. macro nume codifica valoarea comenzii sursă și țintă octet, astfel încât numele clar imediat ce face fiecare macro.

Pentru a scrie cod portabil, ar trebui să utilizați întotdeauna aceste macro-uri pentru a converti de la un ordin țintă octet la altul, chiar dacă știți dinainte că nu este necesară pentru procesor, care utilizează în prezent. În cazul în care comanda sursă și țintă octet este aceeași, macro nu va efectua nicio acțiune, astfel încât utilizarea de macro-uri nu va afecta performanța.

Următoarele Macrocomenzile returnează valoarea după conversie. Observați că antet Linux / fișierul kernel.h este antetul care trebuie să fie conectat la fișierele cod sursă, în cazul în care sunt utilizate macro-uri, dar acest lucru nu este fișierul antet în cazul în care macro-urile sunt de fapt definite.

Următoarele macro-uri sunt aceleași ca și cele anterioare, singura diferență este că parametrul macro - un pointer la valorile convertite. Vă rugăm să rețineți că numele acestor macro-uri sunt aceleași, dar a adăugat sufixul „p“ (de la cuvântul pointerul) la sfârșitul fiecărui nume.

Următoarele macro-uri fac același lucru ca și cele anterioare, dar aici locația valoarea inițială și valoarea convertită a acestuia. Vă rugăm să rețineți că numele acestor macro-uri sunt aceleași, dar a adăugat sufixul „s“ (din expresia latină in situ, ceea ce înseamnă în același loc) la sfârșitul fiecărui nume.

Următoarele macro-uri oferă alias-uri pentru Imer, care sunt utilizate în mod obișnuit pentru a converti ordinea de octet în codul de aplicații de rețea. Primele două sunt folosite pentru a converti un macro dintr-o comandă octet de rețea locală. Celelalte două furnizează o transformare inversă. Literele „s“ și „L“ la sfârșitul numelor în acest caz înseamnă scurt (valoare de 16 biți) și (valoarea 32-bit) lung.

După cum sa menționat mai devreme, ordinea de octet de rețea este întotdeauna mare endian, precum și punerea în aplicare a acestor macro-uri asigură utilizarea corectă a ordinului de octet al unei gazde de rețea.

1. Byte site-ul de comandă: bruceblinn.com.