INF1018 - Software Básico

Assembly: Tradução de estruturas de controle

  1. Considere o programa abaixo:

    #include <stdio.h>
    
    char S2[] = {65, 108, 111, 32, 123, 103, 97, 108, 101, 114, 97, 125, 33, 0};
    
    int main (void) {
      char *pc = S2;
      while (*pc)
        printf ("%c", *pc++);
      printf("\n");
      return 0;
    }
    
    Uma tradução deste programa para assembly está aqui.

    Compare o código assembly com o código C, e veja se você consegue entender a correspondência entre eles.


  2. Modifique o programa C anterior para imprimir somente os caracteres diferentes de '{' e diferentes de '}' (o código ASCII do caractere '{' é 123, e do caractere '}' é 125).

    Teste sua modificação em C e depois faça a mesma modificação no código assembly.

    Repare que, depois de testar uma das condições, dependendo do resultado desse teste, não é necessário testar a segunda condição.

    Este tipo de avaliação de expressões com operadores lógicos é chamada curto-circuito, e ocorre quando a avaliação do segundo operando da expressão somente é realizada se o resultado da avaliação do primeiro operando não é suficiente para determinar o valor da expressão.


  3. Escreva em C um programa que imprima os quadrados dos números de 1 a 10. Para calcular o quadrado de um valor, você pode multiplicá-lo por si mesmo.

    Esse programa não deve utilizar um array de inteiros global! Utilize uma variável (local) inteira para obter os valores de 1 a 10.

    Teste seu programa em C e depois traduza-o para assembly. Em assembly, para calcular o quadrado de um valor, use a instrução imull, por exemplo:

    imull  %eax, %eax
    

    Note que agora você vai precisar de uma string de formatação para imprimir um valor inteiro:

    Sf:  .string "%d\n"
    


  4. Traduza agora para assembly o programa abaixo, lembrando o que foi visto em sala sobre o cálculo do endereço de cada elemento de um array:

      end(a[i]) = end(a) + i * sizeof(T),  onde T é o tipo dos elementos de a
    

    Atenção: esse programa não é igual ao visto no laboratório 6! No laboratório 6, percorremos os arrays com o uso de ponteiros. Você deve, agora, traduzir a operação de indexação do array usada no código C (o que envolve calcular os endereços dos elementos do array, conforme acima).

    #include <stdio.h>
    
    int nums[4] = {65, -105, 111, 34};
    
    int main (void) {
      int i;
      int s = 0;
    
      for (i=0;i<4;i++)
        s = s+nums[i];
    
      printf ("soma = %d\n", s);
    
      return 0;
    }
    

    Dica: Você pode usar um registrador auxiliar, por exemplo %rcx, para fazer o cálculo do endereço do elemento do array. Lembre-se que ele deve ser um registrador de 64 bits, para que você possa fazer a soma com o endereço do início do array.