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;
    }
    
    Traduza o programa para assembly usando as regras vistas em sala. "Cole" o início (prólogo) e o final (finalização) do programa visto no laboratório 6.

    Copie de lá também o trecho de código que imprime o valor de %eax. Esse código utiliza a uma string de formatação criada com endereço Sf. Você terá que criar duas strings de formatação parecidas no novo programa (uma string para imprimir um caractere com formato %c e outra para imprimir a quebra de linha.


  2. Atenção: Nos próximos exercícios, escreva PRIMEIRO o código C para resolver o que se pede, e em seguida traduza-o para assembly. (Os dois códigos são necessários na entrega.)


  3. Modifique o programa C anterior para imprimir somente as letras diferentes de 'a' (minúsculo). (Consulte a tabela ascii se necessário.) Teste-o em C e depois faça a mesma modificação no código assembly.

  4. Agora modifique o programa C para calcular (e imprimir) o comprimento da string S2. Traduza-o para assembly. (Lembre-se de usar a string de formatação correta para imprimir um inteiro.)
  5. Escreva em C um programa que imprima os quadrados dos números de 1 a 10 e depois traduza-o para assembly.

    Atenção: esse programa não deve utilizar um array de inteiros global! Para multiplicar um número por si mesmo em assembly, use a instrução imull (multiplicação de inteiros).

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

    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.

    #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;
    }
    

  7. Vamos voltar ao programa do exercício 4 do laboratório 6, com uma modificação: agora o programa imprime os elementos pares e maiores que zero do array:

    /*
    int nums[] = {10, -21, -30, 45};
    int main() {
      int i, *p;
      for (i = 0, p = nums; i != 4; i++, p++)
        if (((*p % 2) == 0) && (*p > 0))
          printf("%d\n", *p);
      return 0;
    }
    */
    
    Traduza essa modificação. 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.

    Isto pode ocorrer:

    • em uma operação && (and lógico), se a avaliação do primeiro operando resultar em false (0 em C), pois qualquer que seja o valor do segundo operando, a expressão resultará em false.
    • em uma operação || (or lógico), se a avaliação do primeiro operando resultar em true (diferente de 0 em C), pois qualquer que seja o valor do segundo operando, a expressão resultará em true.