Diferenças entre BigEndian, Little Endian e Bit Endianness
Post

Diferenças entre BigEndian, Little Endian e Bit Endianness

Para o iniciante este conceito pode parecer bastante confuso, e até inútil, mas para quem deseja trabalhar com microcontroladores, processadores e principalmente redes a nível de protocolos é fundamental seu entendimento. Big Endian ou Little Endian, qual o impacto na transmissão de dados de um sistema para outro, entre o módulo e o microcontrolador?

Artigo originalmente publicado no site de Carlos Delfino.

O conceito de Big Endian e Little Endian, nomeado simplesmente de Endianess vem da transição dos computadores de médio porte para os microcomputadores, quando estes passaram a endereçar tantos os bits quantos os Bytes de forma diferente. Mas tal problema é principalmente observado quando lidamos com os Bytes, já que pode acarretar o embaralhamento até de texto causando confusão, mas no caso de tratamento numérica pode se tornar a falência total do sistema.

O problema se deu inicio, como já foi dito quando os microcomputadores surgiram, já que estes optaram em trabalhar com o conceito de Little Endian, mas o que é este Endian? porque Big ou Little? bem Endian é um termo cunhado em uma história que faz alusão as disputas politicas e religiosas na Europa, e descrita em uma história de ficção escrita por Jonathan Swift em uma sátira escrita em 1726, Conhecida em português como as Viagens de Gulliver, conta a história, que dois grupos de cidadãos entram em guerra por não concordarem qual o lado certo se deve quebrar o ovo, do lado maior (Big End) ou do lado menor (Little End), com isso uma guerra civil se instala separando os grupos.

Na informática isso não foi muito diferente, não chegamos a uma guerra civil por isso, mas tivemos os sistemas separados em “Big End in” e “Little End in” que define como os bits são transmitidos em algum sistemas, e em outros, apenas quando lidamos com palavras (World/2 bytes, DWorld/4 bytes), seja o microprocessador 8 bits ou maiores.

Nos tempos atuais, não temos muitos problemas relativos a tal modo de endereçamento, porque quase todos os microprocessadores usam o Little Endian para endereçar seus dados, com exceção de alguns como o antigo PowerMAC que usava um PowerPC especial travado para BIG Endian. Os outros computadores que não usam este travamento permitem o chaveamento entre os dois modos no que tange a manipulação dos bytes.

Outras arquiteturas que trabalham com Big Endian são, Motorola 68000 series (incluindo Freescale ColdFire), Xilinx Microblaze, SuperH, IBM z/Architecture, Atmel AVR32 e o Intel 8051 com atenção para instrução LCALL que endereça usando Little Endian.

Mas então, o que é realmente Big Endian e Little Endian?

Como já dito, nada mais é do que a forma que os bytes e bits são endereçados na memória, quando se trata de bytes o Big Endian endereça em uma palavra por exemplo do tipo 2 bytes, o primeiro byte como sendo o endereço menor, e a segunda palavra o endereço seguinte (+1 byte). Ja no Little Endian, o segundo Byte é endereçado primeiro, isso para quem está começando pode causar um certo desconforto, apesar que as linguagens abstraem para nós tal problema, mesmo no C, isso não é percebido, mas podemos vir a ter problemas quando lidamos com ponteiros e até mesmo estruturas de dados (struct), já que o primeiro endereço em um sistema Big Endian, não será a menor parte do número, ou seja a parte menos significante (LSB), mas sim a parte mais significante (MSB).

Vejamos abaixo para entendermos primeiro o conceito de LSB e MSB, que trata a importância do bit ou byte na composição numérica.

LSB representa a parte menos significativa do número ou seja a parte mais a direita. Least Significant bit/Byte.

Já o MSB representa a parte mais significativa, ou seja a parte mais a esquerda do número. Most Significant bit/Byte.

Agora podemos entender melhor o conceito Little Endian e Big Endian, vejamos primeiro a nível de bits do que se trata.

Para o Little Endian a representação numérica em bits, onde o algoritmo de conversão numérico que a maioria de nós está acostumado pode ser facilmente representado na fórmula:

\[\sum_{i=0}^{N-1} b_i \cdot 2^i\]

Temos então a seguinte ordenação dos bits para a representação do número 180 em Little Endian, onde o bit menos significativo é tratado como sendo o bit 0 e o bit 7 é o bit mais significativo.

Representação gráfica do Little Endian

Para o Big Endian os bits mantem sua disposição, porém sua ordem de transmissão inverte, ou seja são endereçados do MSB como sendo o primeiro bit, e o LSB como sendo o último bit, portanto a fórmula de conversão passa a ser:

\[\sum_{i=0}^{N-1} b_i \cdot 2^{(N - 1 - i)}\]
Representação gráfica do Big Endian

O Conceito Endianess

Em se tratando de bits, o conceito Endianess afeta mais o hardware no que tange o endereçamento de memória, transferência de dados em barramentos, principalmente nos seriais, e operações de manipulação de bits. Já que, principalmente se formos usarmos máscaras do tipo bitwise é preciso saber exatamente a ordem dos bits para não haver enganos fatais.

Vejamos agora como é tratado o conceito endianess quando se trata de bytes, o que afeta mais a manipulação do dado na memória, quando é representado com mais de dois bytes, por exemplo números inteiros e short int em maquinas 32 bits.

As imagem abaixo representam dois números inteiros armazenado na memória de um microcontrolador qualquer que seja do tipo Little Endian, a primeira representa um número de 16bits ou seja um Word, o segundo um número de 32 bits, Double Word (DWord).

Representação gráfica do Big Endian para um Word
Representação gráfica do Big Endian para um DWord

Como pode ver o byte mais significativo é armazenado no endereço mais baixo da memória, sendo então acessado primeiramente, e o byte menos significativo é armazenando posteriormente. Na representação o endereço de memória começa a contar em a.

Vejamos agora como o mesmo número fica representado em um sistema Little Endian. Temos a seguir os mesmos números usados na representação anterior, porém agora utilizado o mecanismo Little Endian para armazená-lo.

Representação gráfica do Little Endian para um Word
Representação gráfica do Little Endian para um DWord

Houve épocas que tal conflito quando transferindo dados entre computadores que usavam sistemas diferentes (chamdos bytesex), ou seja transmitindo de um sistema Little Endian para um sistema Big Endian a string UNIX, foi identificado como NUXI Problem, ou seja o “problema NUXI”, devido a inversão da String “UNIX”.

Como pode ver a cada par de bytes, haveria uma inversão, de dos dois bytes, causando um certo transtorno.

Um exemplo do formato Little Endian em C

Abaixo estão dois códigos que demonstra como um número inteiro é armazenado na mémoria, o primeiro um número de 16 bits, um típico inteiro, o outro um número de de 32 bits, ou seja um típico inteiro longo.

Neste exemplo mostramos como um inteiro de 2 bytes (16bits) é armazenado na memória em um formato Little Endian:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <stdint.h>
#include <stdio.h>
#include <string.h>

struct DWORD
   {
      uint8_t a0;
      uint8_t a1;
   } ;


int main(void)
{
   struct DWORD dw;  

   dw.a0 = 0xDF;
   dw.a1 = 0xEA;  

   printf("Endereço 0: %#X\nEndereço 1: %#X\n: %#X\n", dw.a0, dw.a1);

   uint32_t dw1;
   memcpy(&dw1, &dw,4);
   //dw1 = 2;

   printf("   Endereços   1 0\n");
   printf("-------------------\n");
   printf("Valor Word: %#hX\n", dw1);

    return 0;
Resultado para um Word

A seguir um outro exemplo para um inteiro longo de 4 bytes (32 bits), apresentando como é armazenado na memória em um formato Little Endian. Observe as pequenas diferenças no código:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <stdint.h>
#include <stdio.h>
#include <string.h>

struct DWORD
   {
      uint8_t a0;
      uint8_t a1;
      uint8_t a2;
      uint8_t a3;
   } ;


int main(void)
{
   struct DWORD dw;  

   dw.a0 = 0xDF;
   dw.a1 = 0xEA;
   dw.a2 = 0xAB;
   dw.a3 = 0xCF;

   printf("Endereço 0: %#X\nEndereço 1: %#X\nEndereço 2: %#X\nEndereço 3: %#X\n", dw.a0, dw.a1, dw.a2, dw.a3);

   uint32_t dw1;
   memcpy(&dw1, &dw,4);

   printf("   Endereços   3 2 1 0\n");
   printf("-------------------\n");
   printf("Valor DWord: %#lX\n", dw1);

    return 0;
}
Resultado para um DWord

Outras formas de representação

Há outras formas de representação Endianess formas que misturam convenientemente os dois formatos acima, porém não entraremos em detalhes aqui como são apresentadas e utilizadas.

Fontes

This post is licensed under CC BY 4.0 by the author.

“Zicsr”, Control and Status Register (CSR) Instructions, Version 2.0

Programming Language Interface (PLI)

Comments powered by Disqus.