Exercícios básicos de programação em linguagem de montagem do ARM
MC404 2o semestre de 2013


Atualizado em 08/10/2013 - Prof. Célio

  1. Um byte é composto por dois campos de 4 bits denominados nibbles. Escreva uma rotina que recebe como parâmetro de entrada em R0 um valor de 8 bits e devolve em R1 o nibble de mais baixa ordem (bits 0 a 3) e em R2 o nibble de mais alta ordem (bits 4 a 7 de R0 vão para os bits 0 a 3 de R2).
  2. Utilize o exercício anterior para gerar o caracter "ASCII hexadecimal" ('0' a '9', 'A' a 'F') correspondente ao nibble obtido em R1. Obs: na representação binária dos caracteres ASCII existem 7 caracteres entre o '9' e o 'A'.
    Importante: este exercício é parte integrante da atividade obrigatória do "auto-retrato"!
  3. Inserindo bytes num vetor
    Escreva uma rotina appendbyte para inserir um byte no final de um vetor de bytes (inicialmente vazio), onde o 10 byte contem o tamanho do vetor (<=255) e uma rotina removebyte para remover o último elemento do vetor.
  4. Soma de dois inteiros de 64 bits:
    Escreva uma rotina que toma como parâmetros em (r0,r1) um valor inteiro sem sinal de 64 bits (low, high) e em (r2,r3) outro valor de 64 bits sem sinal, somando o segundo ao primeiro (resultado em (r0,r1)). Dica: use a instrução ADC. Como determinar se a soma deu overflow? Utilize isto como parâmetro de saída da rotina.
  5. Escreva um programa para calcular o número de valores iguais a zero, negativos e positivos numa tabela de inteiros com sinal de 32 bits, definida na seção .data: a 1a entrada da tabela contem o número de valores na tabela. O número de valores positivos deve ser calculado em r1, iguais a zero em r2 e negativos em r3. Exiba esses valores no vídeo.
  6. Número de bits 1 numa palavra de 32 bits:
    Escreva uma subrotina que toma como parâmetro de entrada em r0 um valor de 32 bits e calcula em r1 o número de bits de r0 iguais a 1.
    Que mudança você faria para contar o número de bits iguais a 0?
  7. Escreva um programa para: (i) calcular o tamanho de uma cadeia de caracteres ASCII armazenada na área de dados e terminada por um 0 binário e (ii)suponha que a cadeia tem apenas dígitos decimais: substituia os caracteres '0' na frente da cadeia ("leading zeros") pelo caracter branco ' '
  8. Escreva uma subrotina para comparar lexicograficamente duas cadeias de caracteres 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.
  9. Escreva um programa para transformar um valor binário de 32 bits em R0 numa cadeia armazenada na área de dados, contendo a representação "ASCII hexadecimal" do valor em R0 (utilize a rotina que você escreveu no exercício 2)
  10. (*) 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
    
  11. (*) Um vetor de bytes no formato "bcd descompactado" ( "unpacked binary coded decimal)" tem em cada byte um valor binário entre 0 e 9. Escreva um programa para converter o número decimal armazenado no vetor num valor binário de 32 bits. Suponha que o tamanho do vetor é <= 10, o que garante (na maioria dos casos) que o valor convertido cabe em 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 (até 10 dígitos)). Use o seguinte algoritmo, exemplificado para um vetor de 4 dígitos bcd, d1 d2 d3 d4, onde d1 é o mais significativo (você deve estendê-lo para n<=10 dígitos):
    (((d1*10) +d2)*10+d3)*10 +d4= d1*1000 + d2*100 + d3*10 + d4 que é o valordo 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:
    (i) 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  @ e se em vez de "mov" usarmos "add", r1*10 pode ser somado a outro valor!
    
    (ii) o laço do algoritmo acima pode ser codificado com apenas 5 instruções!
  12. Conversão para binário de um vetor de bytes no formato "bcd compactado": esta é uma extensão simples do exercício anterior, só que desta vez cada byte do vetor contém 2 dígitos bcd, daí o nome "packed bcd".