Memória e bytes: ordem dos bytes, tipos e endereços

A memória guarda um byte por endereço. Um número que ocupa vários bytes distribui-se por vários endereços. A instrução de leitura determina quais os bytes que formam um número, a sua ordem e o tipo de número que representam. Escolhe uma leitura abaixo: os bytes usados ficam realçados, com o valor posicional pelo qual cada um é multiplicado.

A carregar a simulação interativa...

Lição

A teoria — Memória e bytes: ordem dos bytes, tipos e endereços

Um byte tem oito bits e representa um valor de 0 a 255. Cada endereço da memória guarda um byte. Um número que ocupa vários bytes usa endereços consecutivos: quatro, no caso de um inteiro de 32 bits. A ordem dos bytes determina a disposição desses bytes na memória. Em little-endian, o byte menos significativo fica no endereço mais baixo; em big-endian, fica aí o mais significativo. Lidos como inteiro sem sinal, quatro bytes dão b₀·256⁰ + b₁·256¹ + b₂·256² + b₃·256³, sendo bₖ o byte na posição k. Uma leitura com sinal subtrai 2³² quando essa soma é igual ou superior a 2³¹. Uma leitura em vírgula flutuante interpreta os mesmos bits segundo a norma IEEE 754.

O que significa cada símbolo

bₖ
o byte na posição k, de 0 (a menos significativa) a 3
256ᵏ
o seu valor posicional: 1, 256, 65 536 ou 16 777 216
Pressupõe
Os inteiros com sinal usam complemento de dois e os números de vírgula flutuante usam precisão simples IEEE 754, como em todos os processadores atuais de computadores pessoais e telemóveis. O texto usa ASCII, com um byte por carácter; UTF-8, usado hoje na maioria dos ficheiros, pode precisar de até quatro bytes para um carácter.

Com a ordem dos bytes trocada, 1 passa a 16 777 216 🖖

Carrega em 1 lido ao contrário. Um processador x86, tal como um ARM na configuração usada nos telemóveis, guarda 1 como inteiro de 32 bits com 01 no endereço mais baixo, seguido de três bytes nulos. Esta ordem chama-se little-endian: o byte menos significativo vem primeiro. Uma leitura em big-endian interpreta o primeiro byte como o mais significativo, pelo que o mesmo 01 vale 256³ e o número é 16 777 216. Os bytes continuam iguais. Dos 4 294 967 296 valores possíveis com 32 bits, apenas 65 536 dão o mesmo resultado nas duas ordens: aqueles em que o primeiro byte é igual ao quarto e o segundo é igual ao terceiro. −1, FF FF FF FF, é um deles. Danny Cohen deu nome às duas ordens em 1980, inspirado na guerra de As Viagens de Gulliver sobre a ponta por onde se devia partir um ovo cozido.

π e 1 078 530 011 são os mesmos quatro bytes 🖖

Carrega em π como inteiro. Guardado em vírgula flutuante de 32 bits, π, arredondado para o valor representável mais próximo, 3,14159274, corresponde aos quatro bytes DB 0F 49 40. Lidos como inteiro com sinal, dão 1 078 530 011; com a ordem dos bytes trocada, dão −619 755 200. Como texto, são dois caracteres, I e @, e dois bytes sem representação imprimível. Nenhum destes bytes indica que o valor está em vírgula flutuante. O Little Man Computer não conseguia distinguir uma instrução de um número. Uma memória de bytes também não distingue os vários tipos de números: o tipo é determinado pela instrução que os lê. Por isso, um programa que use o tipo errado pode obter um resultado errado sem que seja assinalado qualquer erro.

Um endereço ao lado, dois números positivos dão um negativo 🖖

Carrega em Um endereço ao lado. No endereço 0 está 1 000 e no endereço 4 está 2 000, ambos em little-endian: E8 03 00 00 D0 07 00 00. Uma leitura de 32 bits que comece no endereço 1 em vez de 0 usa 03 00 00 do primeiro número e D0 do segundo. D0 fica na posição mais significativa: 3 + 208 × 256³ = 3 489 660 931. Como inteiro com sinal, o resultado é −805 306 365, porque o bit mais significativo de D0 está ativo. Nenhum dos números guardados aparece no resultado. Na memória, nada assinalava onde terminava cada número.

Problema resolvido na íntegra

  1. Quais são as dimensões desta imagem? 4 passos

    Carrega em Cabeçalho PNG. Estes são os primeiros 24 bytes de um ficheiro PNG. A especificação PNG estabelece que todos os inteiros que ocupem mais de um byte usam big-endian e que o bloco IHDR começa pela largura, seguida da altura, com quatro bytes para cada uma. Determina a largura e a altura e calcula as dimensões que obteria um programa que as lesse em little-endian.

    Abrir este problema na ferramenta

    1. O ficheiro começa com uma assinatura de oito bytes: 89 50 4E 47 0D 0A 1A 0A. Os quatro bytes seguintes indicam o comprimento do primeiro bloco, em big-endian: 00 00 00 0D vale 13. Segue-se o tipo do bloco, 49 48 44 52, que em texto é IHDR. Os dados do bloco começam, portanto, no endereço 16.

    2. Largura, nos endereços de 16 a 19: 00 00 01 E0. Em big-endian, 01 ocupa a posição de valor 256¹ e E0, que vale 224, a posição de valor 256⁰: 256 + 224 = 480. A leitura no endereço 16 mostra esse mesmo resultado na ferramenta.

    3. Altura, nos endereços de 20 a 23: 00 00 01 0E, ou seja, 256 + 14 = 270.

    4. Em little-endian, o último byte passa a ser o mais significativo. A largura seria 224 × 256³ + 1 × 256² = 3 758 161 920 e a altura seria 14 × 256³ + 256² = 234 946 560.

    Resposta

    480 × 270 píxeis. Lidos em little-endian, os mesmos bytes indicam 3 758 161 920 × 234 946 560, cerca de 8,83 × 10¹⁷ píxeis. Com quatro bytes por píxel, isso corresponde a 3,53 × 10¹⁸ bytes. A ordem dos bytes é definida na especificação, sem estar assinalada no ficheiro; o programa precisa dessa informação para o ler.

Percurso de aprendizagem

Como um computador executa um programa

Referências (2)