Arquitectura de Computadores (2008/2009) Licenciatura em Engenharia Informática Prova Modelo 27 de Abril de 2009 Duração: 56 min. + 5 min. de tolerância Nome: Número: Isto trata-se de uma prova modelo para ilustrar o funcionamento da avaliação usando perguntas de escolha múltipla. Os examinadores reservam-se o direito de modificar o tipo de prova e usar outras modalidades de questionário nos exames e frequências. As perguntas 13 e 14 referem-se ao módulo 3 (esta matéria não é avaliada na frequência intercalar) Notas Importantes: A fraude denota uma grave falta de ética e constitui um comportamento não admissível num estudante do ensino superior. Não serão admitidas quaisquer tentativas de fraude, levando qualquer tentativa detectada à reprovação imediata, tanto do facilitador como do prevaricador. Durante a prova pode consultar a bibliografia da disciplina (slides, livros, enunciados e materiais de apoio aos trabalhos práticos). No entanto, não é permitido o uso de computadores/máquinas de calcular e a consulta de exercícios previamente resolvidos. Isto é um teste de escolha múltipla onde deverá assinalar claramente as respostas na folha de enunciado. Cada pergunta correctamente respondida vale cinco pontos; cada pergunta errada desconta dois pontos; cada pergunta não respondida, conta zero pontos. Um total abaixo de zero conta como zero valores. 1. Considere o programa em C em que a tabela tab começa no endereço 5000 e o endereço de ptr é 1000. Que valores são impressos no ecrã? int main(){ int tab[]={1,2,3}; int *ptr; ptr=tab; printf( %d,%d,%d,%d,%d,%d,&ptr,ptr,*ptr,&tab,tab,*tab); } 1000,5000,1,5000,5000,1 5000,1000,1,5000,1,1 1000,5000,1,desconhecido,5000,1 Nenhuma das anteriores.
2. Considere a codificação da instrução beq $8, $9, salto no pedaço de código abaixo indicado. Sabendo que o label salto representa o endereço 0x2000, indique a codificação em hexadecimal da instrução? salto: addu $8, $9, $0 beq $8, $9, salto 0x1109FFFE 0x11090002 0x04892000 0x11092000 3. Considere o código em C onde é feita a seguinte alocação e libertação de memória. Sabendo que o bloco alocado começa no endereço 0x5000, o que é que acha que acontece? int *ptr, *aux; ptr=(int *)malloc(6*sizeof(int)); aux=ptr+3; free(aux); Os 24 bytes a começar em 0x5000 são disponibilizados. Só a metade superior do bloco, ou seja os 12 bytes a começar em 0x500B, é que são libertados. O gestor de memória não encontra a entrada na tabela de alocações, podendo dar origem a erros. A memória é libertada mas não poderá voltar a ser alocada. 4. Indique qual das seguintes afirmações é VERDADEIRA. Se uma função utilizar o registo $t0 deve ter o cuidado de o devolver no estado em que o encontrou. O registo $at não deve ser utilizado pelo programador porque é necessário a algumas pseudo-instruções. Uma função quando começa a executar deve guardar sempre o conteúdo de $ra na pilha de forma a poder retornar mais tarde. Como o registo $v0 só tem 32 bits o MIPS não é capaz de implementar funções em C que retornem à saída double words (64 bits).
5. Considere o seguinte programa em C. Indique qual a declaração correcta das variáveis p e h. p = (int *)malloc(sizeof(int)); *p =10; h = &p; A declaração de p e de h é int *p,**h;. A declaração de p e de h é int *p,*h;. A declaração de p e de h é int *p,h;. A declaração de p e de h é int **p,*h;. 6. Relativamente à memória de um programa que está a executar, diga qual das afirmações está CORRECTA: Durante a execução, as zonas de pilha e memória dinâmica (heap) podem ficar contíguas. Durante a execução, a zona de memória dinâmica (heap) pode crescer e sobrepor-se à zona estática. A pilha é uma zona de memória que tem sempre o mesmo tamanho. Durante a execução a pilha e zona de memória dinâmica (heap) podem ficar sobrepostas. 7. A representação em complemento para dois do valor -93 (decimal) para uma palavra de 8 bits é: 1010 0011 0101 1100 0101 1101 1010 0010 8. Escolha a afirmação FALSA: Ao compilar um código C para um processador INTEL este correrá também num MIPS pois este último microprocessador interpreta o código. O código C é independente do processador, ao passo que o código Assembly do MIPS é específico para este microprocessador. Para usar funções escritas em C juntamente com funções escritas em Assembly do MIPS é necessário primeiro compilar o código C para Assembly do MIPS. Uma função escrita em Assembly do MIPS pode chamar uma função escrita em linguagem C e devidamente compilada, desde que respeite as convenções de passagem de parâmetros.
9. Qual dos seguintes pedaços de código em Assembly do MIPS conta o número de caracteres de uma string armazenada em str, sem contabilizar os espaços (caracter com código ASCII 32)? (Nota: o resultado deverá ficar em $s0) - lbu $t1,0($t0) beq $t1,$0,fim beq $t1,$t3,cont addiu $t0,$t0,1 - lbu $t1,0($t0) beq $t1,$0,fim beq $t1,$t3,cont addiu $t0,$t0,4 - lw $t1,0($t0) beq $t1,$0,fim beq $t1,$t3,cont addiu $t0,$t0,1 - lb $t1,0($t0) bne $t1,$0,fim bne $t1,$t3,cont addiu $t0,$t0,1
10. Alguns processadores, como o x86, têm instruções próprias para entradas e saídas. Os restantes: Têm de usar hardware adicional para simular essas instruções. Têm de simular as entradas/saídas como se fossem células de memória RAM normais. Não permitem a ligação de dispositivos externos. Têm acessos mais lentos aos dispositivos externos. 11. Indique qual das seguintes afirmações é FALSA O uso da pilha para armazenamento de variáveis locais: É indispensável para o uso de funções recursivas. Simplifica a chamada de funções de qualquer tipo. É perfeitamente desnecessário pois estas podem ser armazenadas na HEAP. Permite a partilha dessas variáveis entre várias funções. 12. Contrariamente a outros processadores CISC, o MIPS: Na chamada a uma função, guarda automaticamente o endereço de retorno na pilha. Permite apenas o acesso à memória através de instruções específicas. Permite que todos os registos sejam de uso geral, incluindo o PC. Permite mover dados entre endereços de memória RAM usando a instrução add. 13. O MIPS apresenta uma arquitectura que permite dividir a execução de instruções em 5 etapas, com a duração de 1 ciclo de relógio cada. A introdução do mecanismo de pipelining permite em teoria executar, do ponto de vista estatístico, 1 instrução por ciclo de relógio. No entanto, verifica-se que em média cada instrução demora mais ciclos. Isto deve-se a (ASSINALE A QUE NÃO É): Conflitos no acesso a recursos (ex. mesmo registo). Dependência ao nível dos dados, i.e. o resultado de uma instrução ser usado como operando da seguinte. Existência de saltos condicionais. Existência de saltos incondicionais.
14. No MIPS pode-se resolver os conflitos no pipeline de várias formas. Das que se seguem, diga qual não serve: Introdução de bolhas. Alteração da ordem de certas instruções. Usando instruções consecutivas que usem mais ou menos ciclos de relógio. Usando delayed branches. 15. Considere a matriz A, definida em C usando uma tabela de inteiros, e armazenada em memória em linhas sucessivas. # 128 256& $ "1 255' O endereço da matriz é passado como parâmetro para a função em Assembly func. Como é que fica a matriz depois da função executar? (tenha em conta o facto de o MIPS usar a convenção little-endian para guardar words nas células de memória). func: lbu $t3, 9($a0) lb $t2, 12($a0) lbu $t0, 0($a0) sll $t1, $t0, 1 sw $t0, 12($a0) sw $t1, 8($a0) sw $t2, 4($a0) sw $t3, 0($a0) jr $ra # 128 256& $ "1 255' # 255 "1& $ 256 128' # 254 254& $ 255 "1 ' " 128 256% A = $ ' # 255 255&