Pergunta

Se eu tiver um número inteiro do tipo INT32 na memória do processador de 8 bits, digamos, 8051, como eu poderia identificar a endianess desse número inteiro? É específico do compilador? Eu acho que isso é importante ao enviar dados multybyte através de linhas seriais etc.

Foi útil?

Solução

Com um microcontrolador de 8 bits que não possui suporte nativo para números inteiros mais amplos, a Endianness dos números inteiros armazenados na memória depende do escritor do compilador.

O compilador SDCC, que é amplamente utilizado no 8051, armazena números inteiros em formato pouco endiano (o guia do usuário para esse compilador afirma que é mais eficiente nessa arquitetura, devido à presença de uma instrução para incrementar um ponteiro de dados, mas não um para diminuir).

Outras dicas

Se o processador tiver quaisquer operações que atuem em valores multi-bytes ou possuam registros de vários bytes, ele terá a possibilidade de ter um endian-ness.

http://69.41.174.64/forum/printable.phtml?id=14233&thread=14207 sugere que o 8051 misture diferente endian-ness em diferentes lugares.

A Endianness é específica para a arquitetura da CPU. Como um compilador precisa atingir uma CPU específica, o compilador também teria conhecimento da endianidade. Portanto, se você precisar enviar dados sobre uma conexão serial, rede, etc., poderá usar funções de construção para colocar dados em ordem de bytes de rede - especialmente se o seu código precisar suportar várias arquiteturas.

Para mais informações, veja: http://www.gnu.org/s/libc/manual/html_node/byte-order.html

Não cabe ao compilador - '51 possui alguns registros nativos de 16 bits (DPTR, PC em padrão, adc_in, dac_out e tal em variantes) de dado endianness que o compilador deve obedecer - mas fora disso, o compilador é livre para usar qualquer endianness que prefere ou um que você escolher na configuração do projeto ...

Um número inteiro não tem Endianness nele. Você não pode determinar apenas olhando para os bytes, seja grande ou pequeno Endian. Você só precisa saber: por exemplo, se o seu processador de 8 bits é pequeno Endian e você está recebendo uma mensagem de que você sabe ser grande Endian (porque, por exemplo, o sistema de barramento de campo define Big Endian), você deve converter valores de mais de 8 bits. Você precisará codificar isso ou ter alguma definição no sistema em que bytes trocarem.

Observe que trocar bytes é a coisa mais fácil. Você também pode ter que trocar bits nos campos de bits, pois a ordem dos bits nos campos de bits é específica do compilador. Novamente, você basicamente precisa saber disso no momento da construção.

unsigned long int x = 1;
unsigned char *px = (unsigned char *) &x;

*px == 0 ? "big endian" : "little endian"

Se X for atribuído ao valor 1, o valor 1 estará no byte menos significativo. Se então lançarmos X para ser um ponteiro para bytes, o ponteiro apontará para o local mais baixo da memória de x. Se a localização da memória for 0, é grande Endian, caso contrário, é pouco Endian.

#include <stdio.h>

union foo {
    int as_int;
    char as_bytes[sizeof(int)];
};

int main() {
    union foo data;
    int i;
    for (i = 0;  i < sizeof(int);  ++i) {
        data.as_bytes[i] = 1 + i;
    }
    printf ("%0x\n", data.as_int);
    return 0;
}

Interpretar a saída depende de você.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top