Agora, que já sabemos como funciona uma célula de memória, poderíamos implementar certo número delas, identificá-las para que possamos mais tarde encontrar o bit depositado em cada uma delas e começar a armazenar dados.
O problema é que, como vimos no final da coluna anterior, armazenar e recuperar informações bit a bit, embora seja possível e até eventualmente útil, é pouco prático. Mais interessante seria agrupá-los e tratar cada grupo como uma entidade independente, uma “unidade de armazenamento” que seria armazenada em uma única operação de escrita e recuperada também em uma única operação de leitura (em alguns tipos de memória, aquelas cuja escrita e leitura, como veremos adiante, se faz “em bloco”, cada operação de escrita e leitura envolve não apenas uma mas um número fixo de unidades de armazenamento, mas isto não invalida o conceito).
Mas agrupar quantos bits? Em outras palavras: qual o tamanho ideal, em bits, para a unidade de armazenamento?
Bem, quanto maior o número de bits a constituir uma unidade de armazenamento, maior o valor que pode ser ali armazenado. Por exemplo: se adotarmos unidades de armazenamento de quatro bits, o maior número que nela pode ser armazenado será 1111 (lembre-se: o sistema binário, ou de base 2, só adota os algarismos “0” e “1”). Que, convertido para a base decimal com a qual nós, humanos, estamos mais acostumados a lidar, resulta no decimal quinze. Portanto em uma unidade de armazenamento de quatro bits pode-se armazenar dezesseis diferentes quantidades (os números de zero a 15).
Pelas mesmas razões o maior número a ser armazenado em unidades de armazenamento de oito bits corresponde a 11111111 (na base dois), que resulta em 255 quando convertido para a base decimal e que, portanto, indica que se pode armazenar 256 diferentes números nestas unidades de armazenamento. E, caso se viesse a adotar unidades de armazenamento de dezesseis bits teríamos como maior número 1111111111111111 (na base dois) que corresponde ao decimal 65.535. E assim sucessivamente.
Em princípio somos tentados a adotar unidades de armazenamento mais “largas” (de maior número de bits) porque assim poderíamos depositar números maiores em cada uma delas. Porém isto tem um inconveniente: como a unidade de armazenamento será, como bem diz o nome, tratada unitariamente, para armazenar um valor pequeno como, por exemplo, cinco (em binário: 101) teríamos que utilizar todos os bits da unidade de armazenamento. E se escolhêssemos, digamos, dezesseis bits, teríamos que armazenar o número cinco como “0000000000000101”. Veja quantos bits “zero” foram “gastos” antes do primeiro bit significativo. Um notável desperdício de “bits” (ou células de memória).
Por outro lado, nada impede que valores maiores que o máximo contido em uma única unidade de armazenamento sejam armazenados em mais de uma delas, que serão combinadas tomando-as em conjunto (se isso não fosse possível, o maior número que um computador pode processar seria o maior que “coubesse” em sua unidade de armazenamento). Portanto o “tamanho” (largura, em bits) da unidade de armazenamento foi escolhido de tal forma que não limitou demasiadamente o valor do maior número a ser armazenado e nem resultou em grande desperdício de células de memória quando se armazena uma grande quantidade de valores pequenos.
Por diversas razões adotou-se, quase por consenso, uma largura de oito bits (ou um byte) para a unidade de armazenamento. Como algumas destas razões já foram discutidas nas colunas iniciais, quando abordamos os bits, bytes e a digitalização de grandezas (entre as quais ressalta o fato de que com oito bits, ou 256 valores, podem ser representadas todas as letras do alfabeto ocidental, incluindo números, sinais gráficos e principais letras acentuadas) não voltaremos a justificá-las.
Talvez hoje, com o custo relativamente baixo das memórias (de todo tipo...) oito bits nos pareça uma largura demasiadamente exígua e caso a decisão fosse tomada agora provavelmente a unidade de armazenamento seria maior, digamos 16 bits (para acomodar o conjunto de caracteres do padrão Unicode). Mas é bom levar em conta que o conceito de byte foi idealizado em 1967, quando memória era caríssima, e atualizado em 1986 com nossa velha conhecida tabela ASCII, quando era apenas cara.
Assim, por convenção, adotou-se uma largura de oito bits para a unidade de armazenamento. Como resultado disso, até hoje, mesmo nas máquinas mais gigantescas, capacidades de memória são medidas em bytes e seus múltiplos (megabyte, gigabyte, terabyte e assim por diante).
Como os oito bits de uma unidade de armazenamento são tratados em conjunto (ou seja, são escritos ou lidos em uma única operação), eles formam uma entidade que pode ser identificada para efeito de armazenamento.
Dependendo do tipo de leitura/escrita efetuada na memória (voltaremos ao tema adiante) as unidades de armazenamento podem ser lidas/escritas e transferidas individualmente (como no caso da memória principal) ou em bloco (como no caso dos discos rígidos). Mas jamais será possível ler, escrever ou transferir apenas uma parte de uma unidade de armazenamento (senhores programadores, atenção: eu sei que é possível usar artifícios para conhecer ou alterar o valor isolado de qualquer bit em qualquer tipo de memória, mas esta explicação é de ordem geral, portanto não me venham com comentários explicando como isso pode ser feito).
Então, resumindo o que foi dito até aqui para tornar as coisas mais claras:
- Para serem processadas por um computador as informações devem ser digitalizadas, ou codificadas em números expressos no sistema binário;
- Estes dígitos binários (bits) são armazenadas individualmente em células de memória;
- Como não seria prático lidar com informações tratando individualmente com seus bits, concebeu-se o conceito de “unidade de armazenamento”, um número arbitrário de bits (no caso, oito bits, ou um byte) que seria tratado como uma entidade para fins de identificação e transferência;
- Em virtude disso, no que diz respeito à memória, dados e informações são identificados, gravados, lidos e transferidos em conjuntos de oito bits cada (ou em blocos desses conjuntos) que formam as unidades de armazenamento.
Em qualquer caso, para permitir que o valor nela depositado possa vir a ser recuperado, uma unidade de armazenamento tem que ser inconfundivelmente identificada. Isso ocorre mesmo nos dispositivos de memória secundária onde a escrita e leitura são feitas “em bloco”, ou seja, diversas unidades de armazenamento são escritas ou lidas em uma única operação (voltaremos ao assunto adiante). Nos discos rígidos, por exemplo, as unidades de armazenamento são agrupadas em “setores” que contêm 512 unidades de armazenamento (bytes) cada que são movimentados (lidos/escritos e transferidos) em conjunto. Mas cada byte contido nos setores continua sendo uma unidade de armazenamento (tanto que a capacidade dos discos rígidos também é medida em múltiplos de bytes) que pode ser inconfundivelmente identificada como, por exemplo, “o quinto byte do trigésimo setor da oitava trilha da terceira face do disco rígido zero”.
Mas a noção de unidade de armazenamento e sua ligação com a forma de identificá-la fica ainda mais clara no caso da memória principal.
Como sabem os que leram as colunas “XVII: Placas-mãe e memória principal” a “XIX: Leitura e escrita na MP”, a memória principal é “vista” pela UCP como um enorme conjunto, uma imensa “pilha” (no sentido de “pilha de livros”) de unidades de armazenamento, cada uma identificada por um número (o “endereço”) que exprime seqüencialmente sua posição relativa entre os demais, sendo portanto uma “unidade endereçável” (ou unidade de endereçamento). Nesse caso, cada unidade de armazenamento corresponde a uma “posição de memória” formada por oito células nas quais se pode armazenar um bit em cada. Como cada “posição de memória” é identificada por um endereço único e inconfundível, na memória principal dos computadores modernos dos conceitos de “posição de memória”, “unidade de armazenamento” e “unidade de endereçamento” se confundem.
Uma forma clássica de representar esquematicamente um trecho de memória com seu conjunto de posições de memória e respectivos endereços é usar a metáfora do escaninho, como na Figura 1.
|
Figura 1: Escaninhos. |
Cada escaninho pode ser encarado como uma posição de memória. Ele é identificado por um número, um nome, um código estampado em sua borda, ou seja lá que outro tipo de artifício, de modo que não possa em hipótese alguma ser confundido com qualquer outro escaninho.
Em cada escaninho só se pode efetuar duas ações: ou se deposita nele um objeto (escrita na memória) ou se remove dele um objeto (leitura da memória). Quando o objeto é depositado, anota-se a identificação do escaninho (seu número, nome, código ou endereço). Quando se deseja recuperar o objeto, verifica-se a identificação anotada, localiza-se aquele escaninho em particular entre todos os demais e retira-se o objeto.
A metáfora pode ser útil para que se entenda de uma forma genérica o funcionamento das posições de memória, mas existem diferenças fundamentais que devem ser apontadas.
A primeira é que ao contrário de escaninhos, que podem receber ao mesmo tempo diversos objetos ou objetos de “tamanhos” diferentes em momentos diferentes, uma posição de memória só pode conter um dado, e sempre do mesmo tamanho (8 bits, como vimos).
A segunda é que quando se recupera um objeto de um escaninho, o objeto e dele removido e o escaninho se esvazia. Mas, como vimos na coluna anterior, a operação de recuperação de dados nas posições de memória é naturalmente conservativa, ou seja, o conteúdo da memória permanece lá, apenas é “lido” (no caso do escaninho, é como se a recuperação resultasse na retirada de uma cópia idêntica do objeto nele contido, que no entanto lá permaneceria e seria capaz de fornecer tantas cópias adicionais quantas solicitado, até que se venha a nele efetuar uma operação de escrita, quando aquele objeto seria substituído por outro). Desta forma, ao contrário de um escaninho, uma posição de memória jamais estará “vazia”. Sempre haverá algo nela, mesmo que o usuário nada tenha ali escrito (tenha em mente que se você realizar uma operação de leitura da memória e obtiver o valor “00000000” em binário isto não significa que ela está vazia, apenas que armazena o valor “zero”).
O importante é sempre levar em conta que toda e qualquer posição de memória (ou unidade endereçável ou ainda unidade de armazenamento) deve obrigatoriamente permitir ser precisa e inconfundivelmente identificada para ensejar a recuperação do dado nela armazenado. Esta identificação pode se dar de diferentes maneiras, dependendo do tipo de memória, desde que não permita ambigüidades. Por exemplo: pode-se usar um “endereço” (um número seqüencial, único para cada unidade de armazenamento, que representa sua posição em relação às demais) no caso de uma posição da memória principal ou sua posição dentro de um dado setor, trilha, face e disco no caso de memória secundária (disco rígido). Tanto em um caso quanto em outro, um byte – ou seja, uma posição de memória – foi precisamente identificado sem que se possa confundi-lo com nenhum outro. E se assim não fosse, aquele byte em particular não poderia ser utilizado como memória (“depósito” de dados) pois, não se podendo identificá-lo sem qualquer ambigüidade, o dado nele depositado não poderia ser recuperado.
O que nos leva à terceira diferença relativa à metáfora dos escaninhos.
Pois acontece que, ao contrário dos escaninhos onde a identificação está claramente estampada em sua moldura, posições de memória são partes de dispositivos semicondutores, óticos ou magnéticos e seus endereços (ou seja lá qual for sua identificação) não estão representados fisicamente em ponto algum do sistema. Quando se vê uma representação esquemática de uma face de disco rígido com os setores e trilhas marcados e numerados ou uma “pilha” de posições de memória com os endereços escritos ao lado de cada posição (como mostram algumas das figuras das colunas XVII a XIX desta série), isto é meramente um recurso para facilitar o entendimento do tema.
Pronto, agora já temos uma boa noção do que sejam posições de memória, unidades de armazenamento ou unidades de endereçamento (ou endereçáveis).
Já podemos ver quais são os principais tipos e características das memórias para que possamos classificá-las hierarquicamente.
Na próxima coluna, naturalmente.
B.
Piropo