Em computação, extremidade (tradução literal de endianness, que também pode significar fim, término) refere-se à ordem utilizada para representar determinado tipo de dado.

O termo em inglês para uma forma de endianness, big-endian, é uma referência às Viagens de Gulliver: em Lilliput houve uma guerra civil, entre os que preferiam quebrar os ovos cozidos pelo lado maior (big-endians - termo traduzido como "pontagrandenses" nas edições em português) contra quem preferia quebrar os ovos cozidos pelo lado menor. Este conflito, por sua vez, era uma paródia entre as diferenças entre católicos e protestantes a respeito da transubstanciação.

Como caso típico temos a ordem como os números inteiros são guardados na memória em grupos sequenciais de bytes e a ordem utilizada para transmitir sucessivos bytes pela Internet ou qualquer outro meio.

Quando falamos especificamente em bytes, o termo inglês endianness (extremidade) é referido simplesmente como ordem dos bytes.Para hardware, existe um ficheiro de jargão que refere a menos comum expressão byte sex . Não é explícito como esta terminologia é usada quando são possíveis mais que dois critérios de ordenação. Do mesmo modo, o manual do montador ORCA/M refere-se a um campo que indica a ordem dos bytes num campo numérico como NUMSEX, e o sistema Operativo Mac OS X refere o termo "byte sex" nos seus manuais de compiladores .

De forma genérica, extremidade é o formato de representação - qual o byte de um caracter UCS-2 deve ser guardado no endereço inferior, etc. A ordem dos bytes é extremamente importante na programação para redes, dado que dois computadores com ordem de armazenamento de bytes diferentes, ao comunicarem, dão origem a corrupção de dados e a mensagem torna-se ininteligível no destino.

Analogia Extremidade é a forma de ordenar dados pela sua ordem de magnitude ou ordem de grandeza. Como analogia, nas línguas europeias, os números são representados na ordem extremidade maior primeiro (big-endian), em que os primeiros dígitos a serem representados são os de maior peso. Por exemplo, o número 1234 significa 1 milhar (10³), 2 centenas (10²) 3 dezenas (101) e 4 unidade (100). Datas escritas no formato big-endian devem ser escritas como AAAA-MM-DD. O formato DD-MM-AAAA é a representação da data em little-endian, e finalmente o formato MM-DD-AAAA é a representação em middle-endian, porque o campo com a ordem de grandeza média está escrito primeiro. No entanto, os números que representam (individualmente) os dias, meses e anos estão todos no formato big-endian.

A ordenação de bytes e o hardware A maioria dos processadores lê e escreve os bytes na memória principal, com os bits "dentro" dos bytes individuais quase sempre na mesma ordem (embora haja raríssimas excepções). Isto significa que um byte será lido ou escrito, da mesma forma em praticamente todos os sistemas digitais (computadores pessoais mainframes, sistemas de automação e controlo e até consoles de jogos).

Os números inteiros são normalmente guardados em sequências de bytes, sendo que o valor é obtido por simples concatenação. Os dois métodos mais comuns são: Os bytes são guardados por ordem crescente do seu "peso numérico" em endereços sucessivos da memória (extremidade menor primeiro ou little-endian). Os bytes são guardados por ordem decrescente do seu "peso numérico" em endereços sucessivos da memória (extremidade maior primeiro ou big-endian).

Os processadores mais conhecidos que utilizam o formato little-endian são os da Intel (x86), AMD, Zilog (Z80), MOS Technology (6502), DEC (VAX e PDP-11). No caso dos processadores que utilizam o formato big-endian, os mais conhecidos são os da Motorola (famílias 6800 e 68000). O PowerPC que integrava os Apple Macintosh antes da mudança para os processadores da Intel, bem como o System/370. O SPARC historicamente usou sempre big-endian, embora a versão 9 seja bi-endian (ver abaixo).

Hardware bi-endian Algumas arquitecturas de hardware (incluindo a ARM, PowerPC (excepto PPC970/G5), DEC Alpha, SPARC V9, MIPS, PA-RISC e IA64) implementam ordenação comutável (em inglês switchable endianness). Esta característica melhora o desempenho e simplifica a lógica dos dispositivos físicos de rede, bem como o respectivo software. A designação bi-endian, relativa ao hardware, denota a capacidade de processar ou enviar dados em qualquer dos dois formatos.

Algumas destas arquitecturas podem ser alteradas via software para um formato específico (normalmente quando o computador arranca); no entanto, em alguns sistemas o formato default é seleccionado por hardware na placa-mãe e não pode ser alterado por software. (e.g., o DEC Alpha, funciona apenas no modo big-endian Cray T3E.)

De salientar que o termo "bi-endian" se refere principalmente ao modo como o processador acede aos dados. O acesso às instruções num determinado processador pode ter um formato de ordem de pesquisa fixo e pré-determinada, mesmo que o acesso aos dados seja bi-endian.

De salientar também, alguns processadores "bi-endian" podem, na realidade utilizar "magia" internamente (ao contrário de comutação real para outro tipo de ordenação de bytes) para um dos seus modos de funcionamento. Por exemplo, alguns processadores PowerPC no modo little-endian agem como little-endian do ponto de vista da execução de programas, mas não guardam os dados em memória no formato (valores multi-byte são trocados durante o processo de leitura/escrita da/na memória). Isto pode causar problemas quando o conteúdo da memória é transferido para um dispositivo externo, se alguma parte do driver, não tem em conta essa situação.

Transferência de dados entre processador e memória

thumb|500px|none|Tipos de ordenação de bytes.

Os processadores actuais, têm todos (salvo casos pontuais) um barramento de dados de 64 bits, embora os seus registadores internos se mantenham com 32 bits e por isso, se continuem a classificar como processadores de 32 bits. Numa acesso a 64 bits, são usados internamente dois registadores de 32 bits. Por isso a transferência de dados entre o processador e a memória pode ser feita a 8, 16, 32 ou 64 bits. Neste diagrama podemos ver como essa transferência de dados se faz em ambos os modos: extremidade menor primeiro (little endian) e extremidade maior primeiro (big endian). Para ajudar a entender o diagrama, no modo extremidade menor primeiro os endereços de memória crescem da direita para a esquerda e no modo extremidade maior primeiro os endereços de memória crescem da esquerda para a direita.

No entanto, para os não entendidos em hardware, deve ser salientado o seguinte: Isto é apenas uma representação gráfica, para ajudar a explicar o funcionamento da transferência de dados. Na realidade, na construção física das memórias, não existe este conceito de "direcção". As memórias têm um barramento de endereços onde se coloca um padrão de bits que define a célula da memória a que queremos ter acesso, e um barramento de dados onde se coloca um byte (8 bits) (no caso de acesso para escrita), e de onde se lê um byte (no caso de acesso para leitura).

Se o acesso for para múltiplos de um byte - 2 (16 bits), 4 (32 bits) ou 8 (64 bits), poderão ter necessários vários acessos à memória, caso aconteça uma das situações (ou ambas):

A memória estar organizada com menos de 64 bits de barramento de dados (8, 16 ou 32) O alinhamento dos bytes na memória não estar optimizado.

Deve ser referido, que as transferências de dados entre o processador e a memória, são feitos sempre em potências de dois: 1 byte = 20, 2 bytes = 21, 4 bytes = 2², 8 bytes = 2³.

Exemplos Armazenamento do valor 0x0A0B0C0D na memoria Nota: O prefixo 0x indica notação hexadecimal.

Para ilustrar ainda melhor, mostram-se exemplos de um número inteiro de 32 bits, guardado na memória, nos tipos de ordenação de bytes mais comuns. Nem todas as plataformas usam os formatos representados mas, na prática, são muito poucas as excepções.

Os exemplos referem-se ao armazenamento em memória RAM do valor 0x0A0B0C0D. A razão porque se salienta o facto da memória ser do tipo RAM, é porque as acções representadas, referem-se a escrita de dados. No caso das memórias do tipo ROM (e similares), só se podem efectuar acções de leitura (da memória para o processador). No entanto, em qualquer dos casos (leitura ou escrita), os diagramas aplicam-se, tendo apenas em conta que no caso de leitura de dados, as setas devem ser desenhadas na direcção contrária. Exceptuando isto, tudo o resto é igual.

450px

Verificação do formato de ordenação de bytes A linguagem assembly, é de longe, a mais poderosa, mais rápida, mais flexível e que permite tirar partido de todas as características de um microprocessador. No entanto, todo este poder de controle sobre o processador tem um preço: Para a maioria das aplicações, programar em assembly seria uma tarefa "titânica", razão pela qual foram criadas linguagens designadas de alto nível (porque estão mais próximas do raciocínio do programador), que facilitam muito a tarefa ao programador para a maioria das tarefas.

De qualquer forma, existem sempre casos em que não podemos prescindir da Linguagem Assembly, nomeadamente: Software que controla directamente o hardware (BIOS, drivers, etc.). Software para automação e controlo.

Além disso (apesar de em muitos casos não ser preciso), só quem tenha sólidos conhecimentos de Electrónica Digital, tem acesso a todas as funcionalidades dos microprocessadores. Sem entrar em demasiados detalhes, apresenta-se a seguir um segmento de código escrito em Linguagem Assembly, que mostra bem o modo como o processador manipula números inteiros em 64 bits.

Em primeiro lugar, devemos criar um número suficientemente grande, para ocupar 64 bits (8 bytes). Por outro lado, o número deve ser de fácil memorização (1 num byte, 2 no seguinte, 3 depois, etc. até chegar a 8 no último.) Como temos de criar um número em base 2, criamos a sequência 8, 7, 6, 5, 4, 3, 2, 1; em seguida, construímos um número em base 2 baseado nos números anteriores. a operação fica:

Abaixo segue um programa em assembly que executa a ação i = 72.623.859.790.382.856, escrito para processadores Intel (Pentium Pro e superiores), AMD e compatíveis:

Endereço Instrução (opcode + dados) Mnemónica / Directiva Comentários .686P ; código para os processadores Pentium Pro esuperiores que permite utilizar todas as instruções(incluindo em modo privilegiado) .MODEL FLAT ; modelo de utilização de memória com omáximo de desempenho (velocidade e flexibilidade)00 00 00 42 C7 05 00 00 00 00 08 07 06 05 MOV DWORD PTR i, 84281096 ; 05060708H00 00 00 4C C7 05 04 00 00 00 04 03 02 01 MOV DWORD PTR i+4, 16909060 ; 01020304H

Reparando bem na tabela, a coluna da esquerda representa os endereços de memória onde o programa corre e a coluna a seguir as instruções (que são constituídas pelo código nativo do processador e os dados). Se repararmos com atenção, vê-se que nos endereços 00 00 00 42 e 00 00 00 43 temos respectivamente C7 e 05 que são dois bytes que representam a instrução que está indicada na terceira coluna (MOV DWORD PTR i). Nos bytes 00 00 00 44 a 00 00 00 47 temos em todos 00 (endereço onde se encontra a variável i e nos endereços 00 00 00 48 a 00 00 00 4B temos os bytes 08, 07, 06, 05.

Analogamente, se compararmos com a segunda linha, vemos que depois do código da segunda instrução C7 05 vem 04 00 00 00 (endereço de memória onde fica guardada a segunda metade dos 64 bits) e que têm por conteúdo 04, 03, 02, 01.

Tiram-se assim duas conclusões importantes:

O processador utiliza extremidade menor primeiro (little-endian) O processador, apesar de processar dados de 64 bits, não consegue fazê-lo com uma única instrução em código nativo. São precisas duas instruções-máquina (MOV DWORD PTR, em que cada uma move 32 bits), para copiar 64 bits de dados entre duas localizações na memória.