Código de hamming.

Em alguns casos, você não pode confiar totalmente na memória de dados do sistema. Por exemplo, em situações onde os dados foram transmitidos por um meio sujeito a erros. Ainda, mesmo estando inicialmente corretos em uma memória do tipo DRAM, os bits podem mudar aleatoriamente de estado devido ao decaimento de partículas alfa (soft errors) proveniente de isótopos radioativos presentes no encapsulamento do chip (*). Para contornar esse problema e usando seus conhecimentos de correção de erros, você decide implementar duas funções em linguagem de montagem ARM. A primeira recebe 4 bits de dados e os transforma em 7 bits, sendo 3 deles destinados à verificação da consistência dos 4 bits de dados. A segunda, recebe os 7 bits codificados e recupera os 4 bits de dados. A codificação é conhecida como código de Hamming(7,4) e irá aumentar a confiabilidade da memória de dados, uma vez que, checando os 7 bits, você conseguirá determinar se um dos 4 bits originais foi alterado por uma partícula alfa (ou outros tipos de partículas que perturbam o estado da DRAM).

Codificação

Escreva uma função folha (que não faz outras chamadas) com o rótulo "code". No registrador R0, sua função deve receber o valor de 4 bits a ser codificado. Lembre-se que R0 possui 32 bits, então suponha que os 4 bits menos significativos de R0 serão a entrada.

Para construir a saída, você deve entender como o código de Hamming(7,4) codifica 4 bits. Assuma que o vetor de 4 bits da entrada contenha

d1 d2 d3 d4

A saída então será

p1 p2 d1 p3 d2 d3 d4

Os novos bits introduzidos com o radical p são bits de paridade. Cada um dos 3 bits de paridade é responsável por refletir a paridade de um determinado subconjunto de bits (um subconjunto de 3 elementos dos 4 bits de entrada disponíveis). Um bit de paridade contém 1 caso o conjunto de bits avaliado tenha um número ímpar de 1s, ou 0 caso contrário. Siga a tabela:

Bit de paridadeSubconjunto de bits testados
p1d1 d2 d4
p2d1 d3 d4
p3d2 d3 d4

Coloque a saída em R0 e retorne.

Dica: O "ou exclusivo" é um operador lógico que facilita muito o cálculo de bits de paridade.

Decodificação

Se você for um aficcionado por matemática ou simplesmente ler o artigo sobre o código de Hamming, eventualmente irá perceber que a mágica está em calcular a paridade de subconjuntos que se sobrepõem. Isto faz com que não só seja possível detectar quando um bit foi invertido, mas também determinar exatamente qual bit foi invertido e corrigí-lo. Infelizmente, se dois bits forem invertidos, não há como corrigir. Três ou mais erros podem gerar um dado válido e causar um erro indectável. Neste exercício, porém, você deve assumir que no máximo 2 bits podem ser alterados. Sua função decode deve receber em R0 o código de Hamming(7,4) de um dado qualquer. Como esse código possui apenas 7 bits e o registrador R0 possui 32, assuma que a entrada está nos 7 bits menos significativos do registrador. Como saída de sua função, você deverá retornar o dado original (de 4 bits) no registrador R0. Utilize os 4 bits menos significativos de R0 e garanta que todos os outros bits estejam zerados. Também retorne em R1 o número 1 caso você tenha detectado algum erro, ou 0 caso contrário.

Extrair o campo de dados é trivial. Contudo, para detectar se o campo de dados extraído está correto, isto é, se não contém nenhum erro devido à inversões de bits na memória, você deve verificar a paridade para cada um dos 3 subconjuntos. Você pode utilizar o operador ou exclusivo nos bits de um determinado subconjunto. Por exemplo, para verificar a paridade pela qual o bit p1 está responsável, p1 EOR d1 EOR d2 EOR d4 deve ser igual a 0. Caso contrário, há um erro no dado codificado. Faça isso para os três subconjuntos a fim de atestar se você deve confiar no dado codificado com Hamming(7,4).

Testes

Por fim, crie um rótulo main, o ponto de entrada de seu programa ARM, que chama as suas funções e realiza um teste. Sua função deverá ter o seguinte código:

0		.globl main
1	main:	 ldr r0, entrada1
2		 bl code
3		 str r0, entrada1
4	resultado1:	
5		 ldr r0, entrada2
6		 bl decode
7		 str r0, entrada1
8		 str r1, entrada2
9	resultado2:	
10		 mov r7, #1
11		 svc 0x0
12	entrada1:	 .word 0
13	entrada2:	 .word 0

      

Os rótulos das linhas 4 e 9 são marcadores a serem utilizados por um script GDB para a correção de seu exercício. Você poderá utilizar esses scripts para testar seu código, também. O código das linhas 10 e 11 chama a syscall exit para encerrar seu programa. Os rótulos das linhas 12 e 13 são dados armazenados na memória, correspondendo às entradas que serão aplicadas para as funções de codificação e decodificação, respectivamente. Você poderá alterar o número 0 por qualquer outro número que represente uma entrada válida para a sua função, e testar o resultado usando o GDB.

Utilize o mesmo ambiente criado para o laboratório anterior. Porém, substitua o código do programa helloworld pelo código deste laboratório.

Dica: Quando utilizar o depurador, utilize a opção -debug-core do simulador para que, além das informações do GDB, o simulador também imprima o que ele está executando, instrução por instrução, para facilitar o seu entendimento sobre como o programa está sendo executado.

(*) O problema de isótopos radiotivos do encapsulamento é (parcialmente) resolvido exigindo-se um certo nível de purificação (remoção dos isótopos) do material próximo ao chip DRAM (que o reveste). Na prática, um ambiente com radiação acima do comum (e.g. Fukushima) poderia facilmente bombardear um chip DRAM com erros, tornando impraticável o funcionamento do sistema. Isto é um problema cada vez maior conforme os chips diminuem de tamanho e aproximam-se de escalas atômicas, e por esse motivo uma partícula alfa é suficiente para perturbar um chip. Este problema foi descoberto por volta da década de 70.

A submissão deve ser feita pelo sistema Susy em: http://susy.ic.unicamp.br:9999/mc404ab/06