Atividade obrigatória 6 - Programação do ARM em linguagem de montagem


Atualizado em 30/10/2013 - MC404 20 semestre 2013

Os exercícios desta atividade foram sugeridos previamente na página de exercícios para o ARM.

  1. Escreva uma subrotina cmpstring para comparar lexicograficamente duas cadeias de caracteres (não necessariamente de mesmo comprimento), apontadas por r1 e r2 (parâmetros de entrada) e devolvendo em r1 o valor 0 se as cadeias forem iguais, -1 se a 1a for menor que a segunda e 1 se for maior. Faça testes com várias situações que comprovem a correção da sua subrotina, inclusive com cadeias de comprimentos diferentes, como, por exemplo: "abc" x "abca" ou "abca" x "abc".

  2. Substituindo os nibbles de um registrador
    Escreva um programa contendo um laço para substituir sucessivamente cada nibble (4 bits) do registrador r0 por uma constante. Por exemplo: se r0 contem aaaaaaaa e a constante é f após cada iteração r0 conterá aaaaaaaf, aaaaaaff, ..., ffffffff. O resultado de cada substituição deverá ser mostrado no vídeo.
    Sugestão: use a instrução bic.

  3. Escreva uma rotina recursiva para calcular com precisão de 32 bits o fatorial de um inteiro passado em r0 e devolvendo o fatorial em r1. O parâmetro de entrada deve ser sido lido previamente do teclado via scanf. Caso haja overflow no cálculo a rotina deverá retonar 0. Nesse caso há um problema com o uso da instrução MUL (que dá um resultado de 32 bits) pois o manual diz explicitamente:
    If S is specified, the MUL and MLA instructions:
    update the N and Z flags according to the result;
    corrupt the C and V flag in ARMv4 and earlier
    do not affect the C or V flag in ARMv5T and above (nosso caso).
    Sugestão: use a instrução de multiplicação umull
    

  4. Um vetor de bytes no formato "bcd compactado" ("packed binary coded decimal") tem em cada byte dois dígitos bcd (ou seja, cada "nibble" do byte tem um valor binário entre 0 e 9). Escreva um programa para converter o número decimal armazenado no vetor para o seu valor binário de 32 bits. Use a diretiva .byte para definir o conteúdo do vetor, onde o 10 byte do vetor contém o número de dígitos bcd do vetor. Use o seguinte algoritmo, exemplificado para 4 dígitos bcd, d1 d2 d3 d4, onde d1 é o mais significativo (você deve estendê-lo para um número variável de dígitos):
    (((d1*10) +d2)*10+d3)*10 +d4= d1*1000 + d2*100 + d3*10 + d4 que é o valor do número usando a notação posicional.
    Observe que basta colocar num laço e acumular os cálculos di*10 + di+1 para obter a conversão desejada. Além disso, usando o poder de endereçamento com deslocamento do ARM é possível multiplicar um valor binário por 10 com apenas 1 soma seguida de uma soma com deslocamento:
            @ código para multiplicar por 10 o valor em r1:
    	add r1, r1, r1		@ r1= r1*2
    	add r1, r1, r1, lsl #2	@ r1= r1*2 + (r1*2)*4 =valor original em r1 * 10
            ou assim:
            add r1, r1, r1, lsl #2  @ r1= r1*5
            mov r1, r1, lsl #1      @ r1= (r1*5)*2  dica: se em vez de "mov" usar "add", r1*10 pode ser somado a outro valor!
    
    Será avaliada a eficiência e concisão da implementação desse algoritmo!
    Faça vários testes do seu programa, inclusive com os valores bcd compactado: 4294967295 e 4294967296, verificando a correção com a calculadora do linux.