Software Básico (INF1612) 2008.2 http://www.inf.puc-rio.br/~inf1612 Turma 3WA – Roberto Ierusalimschy ([email protected]) Turma 3WB – Markus Endler ([email protected]) Material básico de referência • Computer Systems, A Programmer's Perspective. Randal Bryant and David O'Hallaron. Prentice Hall. 2003. (CS:APP) • Resumos, slides e exercícios no site do curso http://www.inf.puc-rio.br/~inf1612 Critério de avaliação • Cada Grau é calculado como a média geométrica de uma prova (peso 2) e um trabalho (em dupla) – G1 = (P1^2 x T1)^{1/3} – G2 = (P2^2 x T2)^{1/3} • M = (G1 + G2)/2 – Se G1 e G2 ≥ 3.0 e M ≥ 6.0, M é a nota final (NF) – Caso contrário: • NF = (G1+G2+2xPF)/4 Objetivo do curso • Entender em profundidade como funciona um computador típico, como visto pelo nível de Linguagem de Montagem e pela Linguagem de Máquina. • Próximo do que seria um curso de “Arquitetura de Computadores”, mas focando no programador, e não no projetista de computadores – Conhecendo mais sobre o que está “por baixo” do programa, você pode escrever programas mais eficientes e confiáveis. Semanalmente: aula teórica (2ª) e aula de laboratório (4ª feira). Hierarquia de abstrações em um sistema de computação Programa “final” do usuário Aplicações: jogos, editores de texto, sistemas bancários, etc. Escritos geralmente em linguagem de alto nível (C, C++, Java, etc). hardware Programa Assembly Sistema Operacional Linguagem de máquina: binária (0’s e 1’s) – não muito legível por humanos. Linguagem Assembly • A linguagem de montagem (assembly language) é um mapeamento bastante direto da linguagem de máquina, mas que introduz várias facilidades para o programador. – Uso de mnemônicos* para representar as instruções • "apelidos" das instruções, mais fáceis de guardar na memória do que seu valor hexadecimal exigido pelo processador • cada linha do código fonte possui apenas uma instrução para o processador (CPU) – Ex.: MOV EAX, EDX mnemônico * Que facilmente se grava na memória (Diciionário Michaelis). Assembly e Assembler • Um programa assembly também fica acima da camada do sistema operacional, podendo fazer chamadas a ele para requisitar serviços, por exemplo de entrada e saída. • Um programa montador ou assembler faz a tradução da linguagem assembly para a linguagem de máquina (uma espécie de compilador, porém bastante restrito). • Esse curso lida com os aspectos de software da programação em assembly e da linguagem de máquina. O hardware só nos interessa na medida em que influencia essa programação. Processo geral de um executável • Hello world Processo geral de um executável (usaremos o compilador gcc do Linux no curso) • Modifica o programa em C de acordo com diretivas começadas com # – Ex.: #include <stdio.h> diz ao pré-processador para ler o arquivo stdio.h e inseri-lo no programa fonte (o resultado é um programa expandido em C, normalmente com extensão .i, em Unix) Processo geral de um executável • Compilador traduz o programa .i em programa assembly. É o formato de saída comum para os compiladores nas várias linguagens de programação de alto nível – I.e., programas em C, Java, Fortran, etc vão ser traduzidos para a mesma linguagem Assembly. Processo geral de um executável • Transforma o programa assembly em um programa binário em linguagem de máquina (chamado programa objeto – extensão .o). Processo geral de um executável • O ligador (linker) gera o programa executável a partir do .o gerado pelo assembler. Porém, pode haver funções padrão da linguagem (por ex., printf) que não estão definidas no programa, mas em outro arquivo .o précompilado (no caso, printf.o). – O ligador faz a junção dos programas objetos necessários para gerar o executável. Por que o curso? • Programando em linguagem de alto nível (C, C++, etc.) o programador não se preocupa com o gerenciamento de memória, e compilador ajuda a detectar vários erros relacionados a sintaxe e tipos de dados. Porém, é importante conhecer linguagem assembly e o que está por baixo do programa para: 1. Otimizar desempenho de programas – – Um switch é sempre mais eficiente que uma cadeia de ifelse? Por que loops funcionalmente equivalentes podem ter desempenhos significativamente diferentes na execução? 2. Entender erros de ligação – Costumam ser os erros mais “chatos” em programação: referências não resolvidas, etc. 3. Se tornar mais preparado para evitar bugs, por exemplo, devido às limitações das representações dos tipos e na manipulação da memória – Representações finitas de tipos: int’s não são inteiros e float’s não são reais e máquina arredonda ou trunca números. • • – x2 > 0 int: 50000 * 50000 = ??? (x + y) + z = x + (y + z) float: 1e20 + (-1e20 + 3.14) = ?? Memória não é confinada (bounded) em C. Exemplo de possível erro: main () { long int a[2]; double d = 3.14; a[2] = 1073741824; /* Referência “out of bounds” */ printf("d = %.15g\n", d); exit(0); } 4. Ser capaz de fazer engenharia reversa – entender como um compilador gera código, ou como (uma parte) de um executável funciona 5. Obter uma primeira noção de como programar sistemas embarcados – processadores específicos – controle de máquinas- para os quais não existe ainda linguagem de alto nível Arquitetura típica de uma máquina CPU – Central Processing Unit • Unidade de Controle • Unidade Aritméticae Lógica • Conjunto de registradores – Funcionam como uma memória de acesso extremamente rápido dado que não dependem da memória principal (cujo acesso requer uso do barramento) pois estão contidos na própria CPU • instruções de transferência de dados transferem dados entre memória e registradores – Em muitas máquinas os operandos de diversas instruções devem obrigatoriamente estar em registradores – Exemplos de registradores • PC (program counter): contém o endereço da próxima instrução a ser executada • IR (Instruction register): onde é copiada cada instrução a ser executada • Registradores de propósito geral CPU – Central Processing Unit • CPU seguidamente executa instruções requisitadas à memória. Ciclo fetchdecode-execute: 1. busca nova instrução na memória (e copia para IR) 2. atualiza PC Tipos de instruções: • aritméticas e lógicas 3. decodifica instrução • transf. Reg Mem • busca operandos da memória 4. executa instrução • • escreve resultado na memória seta flags de status • desvio de fluxo Barramentos e Dispositivos de E/S • Barramentos: – “conduítes” elétricos que carregam a informação entre os vários componentes da máquina – Projetados para transportar “pedaços” de tamanho fixo de bytes (chamados palavras). Ex.: Intel Pentium tem palavras de 4 bytes (32 bits), e mais recentemente, passou a ter 64. – Adotaremos a Intel Architecture 32 bits (IA32) • Dispositivos de E/S: – Conexão da máquina com o mundo externo – Conectados ao barramento de E/S por controladores (chipsets no próprio dispositivo ou na placa mãe) ou adaptadores (quando placa separada). Memória • Logicamente, a memória principal corresponde a um enorme array de bytes (conjuntos de 8 bits), cada um com seu endereço (o índice do array). Os endereços começam de 0. • Os registradores da CPU muitas vezes são usados para armazenar endereços de memória. Assim, o número de bits em cada registrador limita o número de posições de memória endereçáveis. • Na IA32, cada registrador tem a capacidade de 32 bits (4 bytes) – e esta será a unidade de acesso à memória Programa do curso Próximos assuntos: 1. Armazenamento e Representação de tipos básicos e tipos compostos 2. Linguagem de Montagem 3. Conjunto típico de instruções 4. Modelo de Execução de Uma Linguagem de Alto Nível (C) Implementação de instruções 5. Chamada de procedimentos, Pilha de execução e passagem de parâmetros 6. Representação de números em ponto flutuante e Processamento em Ponto Flutuante 7. Link-edição 8. Interação com o Sistema Operacional (interrupções)