Prévia do material em texto
Arquitetura e Organização de Computadores Coordenadoria de Informática Bach. em Sistemas de Informação Prof. Flávio Giraldeli 2012/2 Introdução Nesta disciplina estudaremos a natureza e as características dos computadores dos dias modernos. Dificuldades: Variedade de produtos (de simples chips a supercomputadores); Rápido ritmo das mudanças na tecnologia. Apesar do variedade e do ritmo da mudança, certos conceitos fundamentais se aplicam de forma corrente. Organização e Arquitetura Arquitetura são os atributos visíveis ao programador. Conjunto de instruções, número de bits usados para representação de dados, mecanismos de E/S, técnicas de endereçamento. Por exemplo, existe uma instrução de multiplicação? Organização é como os recursos são implementados. Sinais de controle, interfaces, tecnologia de memória. Por exemplo, existe uma unidade de multiplicação no hardware ou ela é feita pela adição repetitiva? Organização e Arquitetura Muitos fabricantes oferecem uma família de modelos de computador, todos com a mesma arquitetura mas com diferenças na organização. Toda a família Intel x86 compartilha a mesma arquitetura básica. A família IBM System/370 compartilha a mesma arquitetura básica. Isso gera compatibilidade de código: Pelo menos, com a geração anterior. A organização é diferente entre diferentes versões. Estrutura e Função Computador: Sistema complexo! Natureza hierárquica é essencial para o projeto e a construção de computadores. Estrutura é o modo como os componentes são inter-relacionados. Função é a operação individual de cada componente como parte da estrutura. Abordagem top-down. Função Todas as funções do computador são: Processamento de dados. Armazenamento de dados. Movimentação de dados. Controle. Operações possíveis (a) Mov. de Dados (b) Armazenamento (c) Proc. de/para Armazenamento (d) Proc. de armazenamento para E/S Estrutura Representação mais simples possível de um computador: Estrutura Existem quatro componentes estruturais principais: Unidade Central de Processamento (CPU); Memória Principal; Entrada/Saída (E/S); Interconexão do Sistema. CPU: Unidade de controle; Unidade aritmética e lógica (ALU); Registradores; Interconexão da CPU. Estrutura (níveis) O que estudaremos? Capítulo a capítulo... O que estudaremos? Bases Numéricas e Sinais Digitais [mat. a parte] Evolução e desempenho do computador [cap. 2] Visão de alto nível da função e interconexão do computador [cap. 3] A memória do computador [caps. 4, 5 e 6] Entrada/Saída [cap. 7] Aritmética do computador [cap. 9] Conjuntos de instruções Características e funções [cap. 10] Modos e formatos de endereçamento [cap. 11] Linguagem de Montagem: Assembly [mat. a parte] Bases Numéricas e Sinais Digitais O Computador e a Informação Troca de informações entre os seres humanos e o universo a sua volta Vs. Troca de informações entre os dispositivos eletrônicos (câmeras, computadores, etc…) O Computador e a Informação Diferença principal: A forma em que a informação está representada. Informações para o ser humano: analógicas Som, imagens, ... Informações analógicas podem teoricamente assumir qualquer valor numérico real de -∞ a +∞. Ou seja, infinitos valores. Na verdade, lidamos sempre com valores aproximados. O Computador e a Informação Computadores não podem lidar com informações analógicas! Complexidade intratável. Pouco confiável. Solução? Uma “nova” forma de representar a informação, o que implicou diretamente em um novo sistema numérico. Estamos falando dos sistemas digitais e a representação numérica de base 2 (binária). Sinais Digitais e Números Binários Um sistema digital é um sistema no qual os sinais tem um número finito de valores discretos (bem definidos, enumeráveis). Exemplo 1: uma balança digital mede o peso através de sinais discretos que indicam a massa; por outro lado, uma balança analógica mede o peso através de um sinal contínuo correspondente a posição de um ponteiro sobre uma escala. Exemplo 2: Um sintonizador digital de rádio exibe a frequência da estação, digamos 100.1 MHz (exatamente). Já um sintonizador analógico, mostrará uma faixa contínua de frequências e a sintonia será, na verdade, algo aproximado. Benefícios dos sistemas digitais A representação digital é bem adequada tanto para processamento numérico como não- numérico (caracteres, por exemplo) de informação. O processamento da informação pode usar um sistema para propósitos gerais (um computador) que seja programado para uma tarefa de processamento particular (como o de imagens), eliminando a necessidade de haver um sistema diferente para cada tarefa. Benefícios dos sistemas digitais O número finito de valores num sinal digital pode ser representado por um vetor (conjunto de valores) de sinais com apenas dois valores (sinais binários). Por exemplo, os dez valores de um dígito decimal podem ser representados por um vetor de quatro sinais binários (ou bits), da seguinte maneira: Esta representação permite implementações nas quais todos os sinais são binários; em consequência, os dispositivos que processam esses sinais são muito simples (fundamentalmente, apenas chaves com dois estados: aberto e fechado). dígito 0 1 2 3 4 5 6 7 8 9 vetor 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 Benefícios dos sistemas digitais Os sinais digitais são bastante insensíveis a variações nos valores dos parâmetros dos componentes (por exemplo, temperatura de operação, ruído), de modo que pequenas variações na representação física não mudam o valor efetivo. Os sistemas digitais numéricos podem se tornar mais exatos simplesmente aumentando-se o número de dígitos usados na sua representação. Bases Numéricas 2 (Binária) 10 (Decimal) 16 (Hexadecimal) Números Binários Antes de compreender melhor como funciona a representação em base binária (base 2), observe como um número qualquer é formado na base em que estamos acostumados a lidar, a base 10. Tome por exemplo o número decimal 123. Veja só como o mesmo é formado: 12310 = 1 x 10 2 + 2 x 101 + 3 x 100 base posição relativa Números Binários Pense agora que ao invés de dispor de 10 algarismos diferentes, dispomos de apenas dois. Vamos chamar esses algarismos de 0 (zero) e 1 (um). De forma absolutamente análoga, pense no número 1111011 expresso na base 2. Desmembrando o mesmo temos: 11110112 = 1x2 6 + 1x25 + 1x24 + 1x23 + 0x22 + 1x21 + 1x20 = 12310 Números Binários E como ficam os números não inteiros (ou seja, aqueles com “vírgula”)? A ideia é acima é estendida para expoentes negativos na base 10. Observe: 456,7810 = 4x10 2 + 5x101 + 6x100 + 7x10-1 + 8x10-2 De maneira análoga, o raciocínio acima pode ser usado em qualquer base, por exemplo, a base 2: 101,1012 = 1x2 2 + 0x21 + 1x20 + 1x2-1 +0x2-2 + 1x2-3 = 5,62510 Números Binários Fato: Na base dez, para se multiplicar um número pela base, isto é, por dez, basta deslocar a vírgula uma casa para a direita. Na divisão por dez, basta deslocar a vírgula para a esquerda. O mesmo ocorre com qualquer base, em particular com a base dois. Para multiplicar um número por dois, basta deslocar a vírgula uma casa para a direita. Ao deslocar para a esquerda, estamos dividindo por dois. Números Binários Não é muito comum descrevermos quantidades binárias em bits. Costumamos expressar os valores em bytes, que são agrupamentos formados por 8 bits. Outros múltiplos também existem e são expressos em relação a byte, alguns deles são:1 Kilobyte (KB) 210 bytes 1.024 bytes 1 Megabyte (MB) 220 bytes 1.048.576 bytes 1 Gigabyte (GB) 230 bytes 1.073.741.824 bytes 1 Terabyte (TB) 240 bytes 1.099.511.627.776 bytes Números Binários Importante: No caso dos números binários, a faixa de valores possível de ser expressa numa dada quantidade de bits é relativamente pequena comparada aos números decimais. Por exemplo, na base dez, dispondo de uma sequência formada por oito algarismos, conseguimos representar 108 valores diferentes, ou seja, de 0 a 99.999.999. Já na base binária, com uma sequência de oito dígitos (8 bits), conseguimos representar 28 valores diferentes, ou seja, 256 valores distintos (0 a 255). De maneira geral, quanto menos algarismos uma base possui (quanto menor a base), menor é o intervalo representável para uma mesma quantidade de dígitos. Base Hexadecimal (16) Uma vez compreendida a base binária e decimal, fica fácil compreender a base hexadecimal, ou base 16. Essa base possui não apenas 2 ou 10 algarismos, mas 16 algarismos diferentes. Veja a correspondência entre decimais, binários e hexadecimais correspondentes: 010 = 00002 = 016 110 = 00012 = 116 210 = 00102 = 216 310 = 00112 = 316 410 = 01002 = 416 510 = 01012 = 516 610 = 01102 = 616 710 = 01112 = 716 810 = 10002 = 816 910 = 10012 = 916 1010 = 10102 = A16 1110 = 10112 = B16 1210 = 11002 = C16 1310 = 11012 = D16 1410 = 11102 = E16 1510 = 11112 = F16 Base Hexadecimal (16) Você pode estar pensando, por que motivo eu precisaria de mais uma base? Resposta, com um exemplo: Curiosidade: Cores são muitas vezes representadas por valores numéricos de 24 bits (16.777.216 cores possíveis). Imagine, perguntarmos para nosso colega que cor ele usou num determinado projeto e o ouvirmos dizer uma sequência de 24 zeros e uns! Obviamente será muito mais simples dizer uma simples sequência de 6 algarismos hexadecimais, por exemplo F7FF29 que é um tom de amarelo. Ou você prefere dizer: 1111 0111 1111 1111 0010 1001 ? Decimal Binário Hexadecimal 4.285.639.982 1111.1111.0111.0001.1010.1101.0010.1110 FF71AD2E Conversões entre Bases Numéricas Porque nenhuma base é ideal para todas as situações! Decimal Binário Números Inteiros Forma 1: Divisões sucessivas por 2 (a base binária). As divisões sucessivas acabam quando o quociente chega finalmente a zero. O número na forma binária é formado pelos restos das divisões, de baixo para cima, tal qual indicado pela seta. Assim: 5310 = 1101012 Decimal Binário Números Inteiros Forma 2: Método Direto. Imagine um número binário qualquer, de 6 dígitos. Vamos chamá-lo de b5b4b3b2b1b0 onde cada b é um dígito, que pode ser 0 ou 1, naturalmente. O valor desse número, na base decimal é: b5b4b3b2b1b0 = b5 x 2 5 + b4 x 2 4 + b3 x 2 3 + b2 x 2 2 + b1 x 2 1 + b0 x 2 0 = b5 x 32 + b4 x 16 + b3 x 8 + b2 x 4 + b1 x 2 + b0 x 1 Que valores cada dígito binário deve assumir para que a soma dê, por exemplo, 53? Resposta: 110101 (confira!) Decimal Binário Vamos pensar um pouco mais. Graficamente! Múltiplos da base 2 (números muito conhecidos na computação): 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096... Dependendo da posição relativa do dígito, ele possui um valor, dentre os acima. Qualquer número inteiro pode ser representado como uma soma dessas quantidades (desde que esteja dentro do intervalo representável, claro). Intervalo representável, se considerados apenas os números não negativos: 0 a 2nbits - 1 Decimal Binário Números não inteiros: Podemos tratar a parte inteira (já vista) e a parte fracionária de maneira independente. Vamos continuar com o raciocínio: ... 2-5 = 1/32 = 0,03125 2-4 = 1/16 = 0,0625 2-3 = 1/8 = 0,125 2-2 = 1/4 = 0,25 2-1 = 1/2 = 0,5 20 = 1 21 = 2 22 = 4 23 = 8 24 = 16 25 = 32 … Decimal Binário Números não inteiros: Assim, tudo o que precisamos fazer é continuar combinando os dígitos binários após a vírgula (expoentes negativos) de modo que a soma dê o valor (exato ou aproximado) desejado. Ex: 0,62510 = 0,1012 19,62510 = 10011,1012 Decimal Binário Números não inteiros: E o raciocínio gráfico (reta numérica) pode ser estendido para expoentes negativos ]0,1[: Decimal Binário Números não inteiros: Mas, existe um método “mecânico” de fazer a conversão da parte fracionária, tal qual existe na parte inteira (divisões sucessivas por 2)? SIM! Exemplo: 0,62510 = 0,?2 Logo, 0,62510 = 0,1012 Residual x 2 ≥ 1 ? 0,625 1,25 Sim = 1 0,25 0,5 Não = 0 0,5 1,0 Sim = 1 0 Decimal Binário Números não inteiros: Desafio: Tente! 0,810 = ?2 5,810 = ?2 11,610 = ?2 Binário/Decimal Hexadecimal A conversão de binário para hexadecimal é bastante simples. Basta agrupar os dígitos em grupos de 4, a partir da direta e completar o último grupo com zeros. O ponto, neste caso, é apenas para melhor visualização. Ex: 5310 = 0011.01012 = 3516 1297210 = 0011.0010.1010.11002 = 32AC16 1223751410 = 1011.1010.1011.1010.1100.10102 = BABACA16 Acima, a conversão Decimal Hexadecimal foi feita da forma Decimal Binário Hexadecimal. No entanto, ela pode ser feita diretamente usando quaisquer dos dois métodos usados de Binário Decimal (Divisões sucessivas por 16 ou de modo “Direto”). Binário/Hexadecimal Decimal As conversões de hexadecimal/binário para decimal podem ser facilmente executadas a partir da própria expressão do número na base correspondente, efetuando a soma de produtos, conforme extensamente mostrado anteriormente. Por exemplo: 1101012 = 1x2 5 + 1x24 + 0x23 + 1x22 + 0x21 + 1x20 = 5310 32AC16 = 3x16 3 + 2x162 + 10x161 + 12x160 = 1297210 Lógica Temporizada Tic, Toc, Tic, Toc, Tic, ... Lógica Temporizada Na comunicação digital, qualquer dado, sob a forma de bits, pode ser representado por sinais elétricos: uma tensão positiva alta (“high” - geralmente no em torno de 5 volts) significando 1 e… uma tensão baixa (“low” - próxima de zero) significando 0. O transmissor coloca o sinal no barramento, espera um tempo (na qual o sinal fica estável), para em seguida colocar um novo sinal. Lógica Temporizada Fica claro que, quanto menor for esse “tempo de espera”, mais bits serão transmitidos por unidade de tempo (logo, maior a velocidade da transmissão). Essa base de tempo, é um dos aspectos mais importantes do mundo da computação. Ela é dada por um sinal de sincronismo, cuja precisão é quase perfeita. Estamos falando do sinal de clock. Clock O pulso de clock nada mais é que uma referência de tempo para todas as atividades e permite o sincronismo das operações internas. O clock é um pulso alternado de sinais de tensão, gerado pelos circuitos de relógio (composto de um cristal oscilador e circuitos auxiliares). Cada um destes intervalos regulares de tempo é delimitado pelo início da descida do sinal, equivalendo um ciclo à excursão do sinal por um “low” e um “high” do pulso. Clock O tempo do ciclo equivale ao período da oscilação. A física diz que período é o inverso da frequência. Ou seja, P = 1 / f. A frequência f do clock é medida em hertz. Inversamente, a duração de cada ciclo é chamada de período, definido por P=1/f (o período é o inverso da frequência). Por exemplo, se f = 10 Hz logo P = 1/10 = 0,1 s. Clock 1 MHz (1 megahertz) = 1.000.000 ciclos/segundo. Sendo a frequência de um processador medida em megahertz, o período será então medido em nanosegundos, como vemos no exemplo abaixo: f = 10 MHz = 10 x 106 Hz P = 10 / 106 = 0,0000001 s (segundo) = 0,0001 ms (milissegundo) = 0,1 µs (microssegundo) = 100 ns (nanosegundo)Clock Se comparados dois processadores de uma mesma arquitetura, o que tiver maior clock, será mais rápido, pois o período em que cada ciclo ocorre é menor. Por exemplo: A = x Hz | B = 5x Hz Para casa Conversão de Sinais: Analógico Para Digital Computador PC: Componentes Básicos Exercícios. Evolução e desempenho do computador Evolução e desempenho do computador [Cap. 2] Um breve histórico dos Computadores [2.1] Projetando visando o desempenho [2.2] Evolução da arquitetura Intel x86 [2.3] Avaliação de desempenho [2.5] Principais pontos Evolução dos computadores: Aumento na velocidade do processador; Diminuição no tamanho do componente; Aumento no tamanho da memória; Aumento na capacidade e velocidade de E/S. Aumento na velocidade da CPU devido: ao encolhimento do tamanho dos componentes (melhoria das técnicas de fabricação) = permite que eles trabalhem a frequências mais altas sem sobreaquecimento; melhorias na organização do computador... Técnicas de pipeline; Execução paralela; Execução especulativa. Questão crítica: Equilibrar o desempenho dos diversos elementos do computador. Um breve histórico dos computadores 1ª Geração (1946-1957): Válvulas ENIAC Inicialmente projetado para a Guerra, mas chegou tarde, em 1946. Números: Decimal, 18 000 válvulas, 30 ton., 1 500 pés2, 140 kW, 5 000 adições por segundo. 2ª Geração (1958-1964): Transistores 3ª Geração (1965): Circuitos Integrados Integração em pequena escala: Até 100 dispositivos em um chip. Integração em média escala: 100-3.000 dispositivos em um chip. Gerações Posteriores (1971 - ?) 1971-1977: Integração em escala grande; 3.000 – 100.000 dispositivos em um chip 1978 -1991: Integração em escala muito grande; 100.000 – 100.000.000 dispositivos em um chip 1991: Integração em escala ultra grande. Mais de 100.000.000 dispositivos em um chip. 1ª Geração: A Máquina de Von Neumann Programar o ENIAC era extremamente enfadonho. Se o programa pudesse ser representado de uma forma adequada (ao invés das chaves que o programavam manualmente) tudo seria mais fácil. Instruções + Dados seriam armazenados na memória. Conceito de programa armazenado. ALU operando sobre dados binários. Unidade de controle interpretando e executando instruções da memória. Equipamento de entrada e saída operado por unidade de controle. Princeton Institute for Advanced Studies: IAS Concluído em 1952. Estrutura da máquina de von Neumann IAS – detalhes Com raras exceções, todos os computadores de hoje tem essa mesma estrutura e função geral, e são conhecidos como máquinas de von Neumann. 1000 “palavras” de 40 bits. Número binário. 2 instruções de 20 bits. Conjunto de registradores (armazenamento em CPU). Registrador de buffer de memória (MBR). Registrador de endereço de memória (MAR). Registrador de instrução (IR). Registrador de buffer de instrução (IBR). Contador de programa (PC). Acumulador (AC). Quociente multiplicador (MQ). IAS – Formato de Memória Estrutura do IAS detalhe Instruções do IAS Computadores Comerciais 1947 – Eckert-Mauchly Computer Corporation. UNIVAC I (Universal Automatic Computer). Birô do Censo dos EUA para cálculos de 1950. Tornou-se parte da Sperry-Rand Corporation. Final da década de 1950 – UNIVAC II. Mais rápido. Mais memória. IBM Equipamento de processamento de cartão perfurado. 1953: 701 Primeiro computador de programa armazenado da IBM. Cálculos científicos. 1955: 702 Aplicações comerciais. Levou à série 700/7000. 2ª Geração: Transistores Substituíram as válvulas. Menores. Mais baratos. Menos dissipação de calor. Dispositivo de estado sólido. Feito de silício (areia). Inventado em 1947 na Bell Labs. William Shockley e outros. Introdução de ALU’s e Unidades de Controle complexas. Linguagem de programação de alto nível. 3ª Geração: Circuitos Integrados Transistor isolado = componente discreto. Computador era construído usando componentes discretos. Processo dispendioso e complicado, especialmente porque a complexidade cresceu muito rapidamente (milhares de transistores). Surge então a microeletrônica. Microeletrônica Literalmente – “pequena eletrônica”. Um computador é composto de portas (AND, OR, NOT, ...), células de memória e interconexões. Microeletrônica Estas podem ser fabricadas em um semicondutor. Por exemplo, wafer de silício. Lei de Moore Maior densidade de componentes no chip. Gordon Moore – cofundador da Intel. Número de transistores em um chip dobrará a cada ano. Desde 1970, isso diminuiu um pouco. Número de transistores dobra a cada 18 meses. Consequências: Custo de um chip permaneceu quase inalterado. Maior densidade de empacotamento significa caminhos elétricos mais curtos, gerando maior desempenho. Menor tamanho oferece maior flexibilidade. Redução nos requisitos de potência e resfriamento. Menos interconexões aumenta a confiabilidade. Crescimento na contagem de transistores da CPU Gerações posteriores Difícil caracterização. Houve importantes resultados dos estudos iniciados desde a década de 70. Destacam-se: Memória Semicondutora. Microprocessador. Memória Semicondutora Tecnologia de circuito integrado aplicada às memórias. Anteriormente: memórias construídas com anéis ferromagnéticos. Era destrutiva. Fairchild (1970): Primeira memória semicondutora. Tamanho de um único core = 256 bits Ou seja, 1 bit de armazenamento do core magnético. Leitura não destrutiva. Muito mais rápida que o core. Capacidade dobra aproximadamente a cada ano. Gerações: 1K, 4K, 16K, 64K, 256K, 1M, 4M, 16M, 64M, 256M, 1G, 4G, 16Gbits por chip. Microprocessadores 1971: Intel 4004 Primeiro microprocessador. Todos os componentes da CPU em um único chip. 4 bits. Acompanhado em 1972 pelo 8008. 8 bits. Ambos projetados para aplicações específicas. 1974 : Intel 8080. 8 bits. Primeiro microprocessador de uso geral da Intel. Dobro da complexidade do 4004. Evolução dos proc. Intel Evolução dos proc. Intel Projetando visando ao desempenho Fatores mais fortes para se alcançar o máximo de desempenho: Velocidade do microprocessador Balanço do desempenho Melhorias na organização e na arquitetura do chip. Fator 1: Velocidade do microprocessador Princípio básico: Manter o processador ocupado a maior parte do tempo. Técnicas: Previsão de desvio: Tentar antecipar as próximas instruções. Análise do fluxo de dados: reordenação de instruções visando a otimização. Execução especulativa: baseado nas técnicas acima, executar antecipadamente instruções potencialmente necessárias. Fator 2: Balanço do desempenho Necessidade de procurar o equilíbrio do desempenho Ajustes na organização/arquitetura para compensar a diferença entre as capacidades dos diversos componentes (barramentos, memórias, etc.) Lugar crítico (gargalo): Interface processador- barramento-memória. Técnicas: Barramento de dados mais largo; Melhoria da interface da DRAM; Redução da frequência de acesso a memória usando caches; Aumento da largura de banda de interconexão CPU- DRAM. Diferença de desempenho entre lógica e memória Dispositivos de E/S Periféricos com demandas intensas de E/S. Grandes demandas de vazão de dados. Processadores podem tratar disso. Problema de movimentar dados. Soluções: Caching. Buffering. Barramentos de interconexão de maior velocidade. Estruturas de barramentos mais elaboradas. Configurações de processadormúltiplo. A chave é o balanço Componentes do processador. Memória principal. Dispositivos de E/S. Estrutura de interconexão. Fator 3: Melhorias na organização e na arquitetura do chip Técnicas para aumentar a velocidade do processador: Aumentar velocidade de hardware do processador. Deve-se fundamentalmente ao encolhimento do tamanho das portas lógicas no chip. Mais portas, reunidas mais de perto, aumentando a taxa de clock. Redução no tempo de propagação dos sinais. Aumentar tamanho e velocidade das caches. Dedicando parte do chip do processador . Tempos de acesso à cache caem significativamente. Mudar organização e arquitetura do processador. Aumenta velocidade de execução efetiva. Paralelismo. Fator 3: Melhorias na organização e na arquitetura do chip Fator 3: Melhorias na organização e na arquitetura do chip Problemas com velocidade do clock e densidade da lógica: Potência Densidade de potência aumenta com densidade da lógica e velocidade do clock. Dissipação de calor. Atraso de RC Velocidade em que os elétrons fluem pela resistência e capacitância dos fios de metal que os conecta. Aumentos de atraso à medida que o produto RC aumenta. Interconexões de fio mais finas, aumentando a resistência. Fios mais próximos, aumentando a capacitância. Latência da memória Velocidades de memória ficam atrás das velocidades de processador. Fator 3: Melhorias na organização e na arquitetura do chip Solução: Mais ênfase em abordagens de organização e arquitetura. O que vem sido feito neste sentido? Aumento da capacidade do cache; Lógica de execução mais complexa; Múltiplos cores (núcleos); Fator 3: Melhorias na organização e na arquitetura do chip Aumento da capacidade do cache Normalmente, dois ou três níveis de cache entre processador e memória principal. Densidade de chip aumentada. Mais memória cache no chip. Acesso mais rápido à cache. Chip Pentium dedicou cerca de 10% da área do chip à cache. Pentium 4 dedica cerca de 50%. Fator 3: Melhorias na organização e na arquitetura do chip Lógica de execução mais complexa Permite execução de instruções em paralelo. Pipeline funciona como linha de montagem. Diferentes estágios de execução de diferentes instruções ao mesmo tempo ao longo do pipeline. Superescalar permite múltiplos pipelines dentro de um único processador. Instruções que não dependem uma da outra podem ser executadas em paralelo. Fator 3: Melhorias na organização e na arquitetura do chip Fato: Retornos cada vez menores... Complexa organização interna dos processadores. Pode obter muito paralelismo. Aumentos mais significativos provavelmente serão relativamente modestos. Benefícios da cache estão chegando ao limite. Aumentar taxa de clock causa o problema da dissipação de potência. Alguns limites físicos fundamentais estão sendo atingidos. Fator 3: Melhorias na organização e na arquitetura do chip Tendência: Múltiplos cores. Múltiplos processadores em único chip. Grande cache compartilhada. Dentro de um processador, aumento no desempenho proporcional à raiz quadrada do aumento na complexidade. Se o software puder usar múltiplos processadores, dobrar o número de processadores quase dobra o desempenho. Assim, use dois processadores mais simples no chip ao invés de um processador mais complexo. Com dois processadores, caches maiores são justificadas. Consumo de potência da lógica de memória menor que lógica do processamento. Evolução da arquitetura Intel x86 8080 Primeiro microprocessador de uso geral. Caminho de dados de 8 bits. Usado no primeiro computador pessoal – Altair. 8086 – 5MHz – 29 000 transistores. Muito mais poderoso. 16 bits. Cache de instruções, pré-busca poucas instruções. 8088 (barramento externo de 8 bits) usado no primeiro IBM PC. 80286 16 MB de memória endereçável. A partir de 1MB. 80386 32 bits. Suporte para multitarefa. 80486 Cache sofisticada e poderosa, pipeline sofisticado de instrução. Coprocessador matemático embutido. Evolução da arquitetura Intel x86 Pentium Superescalar. Múltiplas instruções executadas em paralelo. Pentium Pro Organização superescalar aumentada. Renomeação de registrador agressiva. Previsão de desvio. Análise de fluxo de dados. Execução especulativa. Pentium II Tecnologia MMX. Processamento de gráficos, vídeo e áudio. Pentium III Instruções adicionais de ponto flutuante para gráficos 3D. Evolução da arquitetura Intel x86 Pentium 4 Números romanos para números arábicos. Melhorias adicionais de ponto flutuante e multimídia. Core Primeiro x86 com dual core. Core 2 Arquitetura de 64 bits. Core 2 Quad – 3GHz – 820 milhões de transistores Quatro processadores no chip. Arquitetura x86 dominante fora dos sistemas embarcados. Organização e tecnologia mudaram drasticamente. Arquitetura do conjunto de instruções evoluiu com compatibilidade. 500 instruções disponíveis. Avaliação de desempenho Principais parâmetros: Desempenho, custo, tamanho, segurança, confiabilidade, consumo de energia. Comparações de desempenho são difíceis. Desempenho depende de vários fatores: Velocidade bruta do processador; Conjunto de instruções; Escolha da linguagem de programação; Habilidade da programação. Há medidas tradicionais de desempenho, que serão analisadas. Clock do Sistema Velocidade do clock do sistema: Em Hz ou múltiplos Velocidade de clock, ciclo de clock, tempo de ciclo. Sinais na CPU levam tempo para se estabilizarem em 1 ou 0. Sinais podem mudar em diferentes velocidades. Operações precisam ser sincronizadas. Clock do Sistema Execução de instrução em etapas discretas. Busca, decodificação, load e store, aritmética ou lógica. Geralmente requer vários ciclos de clock por instrução. Pipelining gera execução simultânea de instruções. Assim, velocidade de clock não é tudo. Taxa de execução de instrução 𝜏 = 1 𝑓 , onde 𝜏 = tempo, 𝑓 = frequência 𝐼𝑐 = contagem de instruções (nº de inst. por período de tempo) 𝐶𝑃𝐼 = (𝐶𝑃𝐼𝑖 × 𝐼𝑖) 𝑛 𝑖=1 𝐼𝑐 = média de ciclos por instrução 𝑇 = 𝐼𝑐 × 𝐶𝑃𝐼 × 𝜏 = 𝐼𝑐 × [𝑝 + 𝑚 × 𝑘 ] × 𝜏 𝑝 = número de ciclos para dec. e exec. a instrução 𝑚 = número de referências de memória necessárias 𝑘 = razão entre tempo de ciclo de memória e tempo de ciclo de processador Taxa de execução de instrução Taxa 𝑀𝐼𝑃𝑆 = 𝐼𝑐 𝑇 × 106 = 𝑓 𝐶𝑃𝐼 × 106 Taxa 𝑀𝐹𝐿𝑂𝑃𝑆 = num. de inst. de PF exec. em um programa Tempo de execução × 106 𝐶𝑃𝐼 = 0,6 + 2 × 0,18 + 4 × 0,12 + 8 × 0,1 = 2,24 𝑀𝐼𝑃𝑆 = 400 × 106 2,24 × 106 ≈ 178 Exemplo: Benchmarks Programas elaborados para testar o desempenho. Escritos em linguagem de alto nível. Portáveis. Representa o estilo da tarefa. Sistemas, numérica, comercial. Facilmente medidos. Amplamente distribuídos. P.e., System Performance Evaluation Corporation (SPEC). CPU2006 para limite de cálculo. 17 programas de ponto flutuante em C, C++, Fortran. 12 programas de inteiros em C, C++. 3 milhões de linhas de código. Métrica de velocidade e de taxa. Única tarefa e vazão. Métrica de velocidade SPEC Única tarefa. Runtime básico para cada programa usando máquina de referência. Resultados são relatados como razão entre o tempo de referência e o tempo de execução do sistema. Tempo de execução Trefi para benchmark i na máquina de referência. Tempo de execução Tsuti do benchmark i na máquina de teste. Métrica de velocidade SPEC Desempenho geral calculado pela média dasrazões para todos os 12 benchmarks de inteiros. Usa média geométrica. Apropriado para números normalizados, como razões. Métrica de taxa SPEC Mede vazão ou taxa de uma máquina executando uma série de tarefas. Múltiplas cópias de benchmarks executadas simultaneamente. Normalmente, mesmo número de processadores. Razão calculada da seguinte forma: Tempo de execução de referência Trefi para benchmark i. N número de cópias executadas simultaneamente. Tsuti tempo decorrido desde início da execução do programa em todos os N processadores até o término de todas as cópias do programa. Novamente, uma média geométrica é calculada. Benchmarks Modernos SYSMark SYSmark 2012 is an application-based benchmark that reflects usage patterns of business users in the areas of office productivity, data/financial analysis, system management, media creation, 3D modeling and web development. SYSmark 2012 is a ground up development and features the latest and most popular applications from each of their respective fields. Benchmarks Modernos PCMark PCMark 7 is a complete PC benchmarking solution for Windows 7 and Windows 8. It includes 7 tests combining more than 25 individual workloads covering storage, computation, image and video manipulation, web browsing and gaming. Specifically designed for the full range of PC hardware from netbooks and tablets to notebooks and desktops, PCMark 7 offers complete Windows PC performance testing for home and business use. Benchmarks Modernos 3DMark SuperPi Games Programas comerciais pesados (Photoshop, 3D Studio, ...) Video Transcoding Lei de Amdahl Gene Amdahl [AMDA67]. Speedup em potencial do programa usando múltiplos processadores. Concluiu que: Código precisa ser paralelizável. Speedup é limitado, gerando retornos decrescentes para uso de mais processadores. Dependente da tarefa: Servidores ganham mantendo múltiplas conexões em múltiplos processadores. Bancos de dados podem ser divididos em tarefas paralelas. Fórmula da Lei de Amdahl Para programa rodando em único processador: Fração f do código paralelizável sem overhead no escalonamento. Fração (1-f) de código inerentemente serial. T é o tempo de execução total para o programa no único processador. N é o número de processadores que exploram totalmente as partes paralelas do código. Conclusões: f pequeno, processadores paralelos têm pouco efeito. N ->∞, speedup limitado por 1/(1 – f). Retornos decrescentes para o uso de mais processadores. Visão de alto nível da função e interconexão do computador Principais pontos O ciclo de instrução Busca de instrução, busca de operandos, armazenamento de operandos, verificação de interrupção. Os principais componentes do sistema de computação (CPU, RAM, E/S) precisam ser interconectados (dados e controle). Barramentos compartilhados Hierarquia de barramentos. Projeto de barramentos Arbitração; Temporização; Largura. Introdução Visão de alto nível de um computador CPU Memória Componentes de E/S Descrição de um sistema de computação: Comportamento externo de cada componente (sinais de dados e controle); Estrutura de interconexão e os controles exigidos para gerenciar o uso da estrutura de interconexão. Conhecimento da estrutura e função de alto nível: Identificação dos gargalos do sistema; Caminhos alternativos; Magnitude de falhas; Facilidade de melhorias de desempenho. Componentes do computador Arquitetura de Von Newmann Dados e instruções armazenados numa única memória de leitura/escrita. Memória endereçável por local, sem considerar seu conteúdo. Execução sequencial (a menos que modificado explicitamente) A Programação do Computador Possibilidade 1: Interconexão entre componentes lógicos básicos para armazenar dados binários e realizar operações lógicas/aritméticas. Cada cálculo em particular exige uma configuração de componentes lógicos específicos. Tais componentes interligados seriam o “programa” na forma de hardware. Programa “hardwired” Inflexíveis Hardware de uso geral pode fazer diferentes tarefas, dados sinais de controle corretos. Ao invés de religar o hardware, forneça um conjunto de sinais de controle. A Programação do Computador Possibilidade 2: Unidades que podem ter seu comportamento alterado dependendo dos sinais de controle aplicados. Ao invés de religar o hardware para cada novo programa, o programador simplesmente fornece novos sinais de controle. O que é um programa? Uma sequência de etapas. Para cada etapa, é feita uma operação aritmética ou lógica. Para cada operação, é necessário um conjunto diferente de sinais de controle. Software: Sequência de códigos ou instruções que, ao serem interpretadas, geram sinais de controle para os componentes. Abordagens de hardware e software Componentes... A Unidade de Controle e a Unidade Lógica e Aritmética constituem a Unidade Central de Processamento. Dados e instruções precisam entrar no sistema, e resultados saem dele. Entrada/saída. É necessário um armazenamento temporário de código e resultados. Memória principal. Componentes do computador: visão de alto nível Função do Computador Função básica Execução de um programa (instruções armazenadas na memória) Existem diversos elementos envolvidos na execução de um programa. Processo básico: Busca de instruções (ciclo de busca) Execução da instrução (ciclo de execução) Busca e execução de instruções Ciclo de Busca Contador de Programa (PC) mantém endereço da próxima instrução a buscar. Processador busca instrução do local de memória apontado pelo PC. Incrementar PC: A menos que seja informado de outra forma. Instrução carregada no Registrador de Instrução (IR). Processador interpreta instrução e realiza ações exigidas. Busca e execução de instruções Ciclo de Execução (Categorias) Processador-memória: Transferência de dados entre CPU e memória principal. E/S do processador: Transferência de dados entre CPU e módulo de E/S. Processamento de dados: Alguma operação aritmética ou lógica sobre dados. Controle: Alteração da sequência de operações. Ex: salto. Combinação dos itens anteriores. Exemplo (Características da máquina hipotética) Exemplo (Execução de um programa) No exemplo (somar 3 + 2): - 3 ciclos de instrução - cada um com um ciclo de busca/execução Diagrama de estado do ciclo de instrução Interrupções Mecanismo pelo qual outros módulos (p.e. E/S) podem interromper a sequência de processamento normal. Interrupções Ciclo de interrupção Adicionado ao ciclo de instrução. Processador verifica interrupção. Indicado por um sinal de interrupção. Se não houver interrupção, busca próxima instrução. Se houver interrupção pendente: Suspende execução do programa atual. Salva contexto. Define PC para endereço inicial da rotina de tratamento de interrupção. Interrupção de processo. Restaura contexto e continua programa interrompido. Transferência de controle via interrupções Ciclo de instrução com interrupções Interrupções Adicionam um overhead, pois instruções extras precisam ser executadas (no tratador de interrupções). Contudo, devido à quantidade de tempo relativamente grande que seria desperdiçada pela simples espera por uma operação de E/S, o processador pode ser empregado de modo muito mais eficiente com o uso de interrupções. Exemplo em 2 casos: Espera curta pela E/S. Espera longa pela E/S. Sincronização do programa – espera curta pela E/S Sincronizaçãodo programa – espera longa pela E/S Ciclo de instrução (com interrupções) Diagrama de estado Múltiplas interrupções A discussão até aqui ficou apenas na ocorrência de uma única interrupção. Suponha, porém, que ocorram múltiplas interrupções. Ex: Um programa pode estar recebendo dados de uma linha de comunicações e imprimindo resultados. A impressora gerará uma interrupção toda vez que completar uma operação de impressão; O controlador de linha de comunicação gerará uma interrupção toda vez que uma unidade de dados chegar (um caractere ou um bloco); Fato: É possível que uma interrupção de comunicações ocorra enquanto uma interrupção de impressora estiver sendo processada! Múltiplas interrupções Técnicas Desativar interrupções: Processador ignorará outras interrupções enquanto processa uma interrupção. Interrupções permanecem pendentes e são verificadas após primeira interrupção ter sido processada. Interrupções tratadas em sequência enquanto ocorrem. Definir prioridades: Interrupções de baixa prioridade podem ser interrompidas por interrupções de prioridade mais alta. Quando interrupção de maior prioridade tiver sido processada, processador retorna à interrupção anterior. Múltiplas interrupções Técnicas Sequência de tempo de múltiplas interrupções Estrutura de Interconexão Computador = 3 componentes/módulos básicos: Processador; Memória; E/S. Tais módulos precisam se interconectar e comunicar-se entre si. A coleção de caminhos conectando os diversos módulos é chamada de estrutura de interconexão. Módulos do computador Conexão de Memória Recebe e envia dados. Recebe endereços (de locais). Recebe sinais de controle: Leitura. Escrita. Temporização. Conexão de E/S Semelhante à memória do ponto de vista do computador. Saída: Recebe dados do computador. Envia dados a periféricos. Entrada: Recebe dados de periféricos. Envia dados ao computador. Recebe sinais de controle do computador. Envia sinais de controle aos periféricos. P.e., girar disco. Recebe endereços do computador. P.e., número de porta para identificar periférico. Envia sinais de interrupção (controle). Conexão da CPU Lê instruções e dados. Escreve dados (após processamento). Envia sinais de controle a outras unidades. Recebe (e atua sobre) interrupções. Interconexão de Barramento O que é um barramento? Um caminho de comunicação conectando dois ou mais dispositivos. Normalmente, broadcast. Frequentemente agrupado. Uma série de canais em um barramento. P.e., barramento de dados de 32 bits são 32 canais de bits separados. Linhas de potência podem não ser mostradas. Um barramento que conecta os principais componentes do computador (CPU, Memória e E/S) é chamado de barramento do sistema. Estrutura de barramento Um barramento do sistema consiste, normalmente, em cerca de 50 a centenas de linhas separadas, cada uma delas com um significado em particular. Embora existam muitos projetos de barramento diferentes, em qualquer barramento as linhas podem ser classificadas em três grupos funcionais: Linhas de dados (barramento de dados); Linhas de endereço (barramento de endereço); Linhas de controle (barramento de controle). Barramento de dados Transporta dados. Lembre-se de que não existe diferença entre “dados” e “instruções” neste nível. Largura é um determinante fundamental do desempenho. 8, 16, 32, 64 bits. Barramento de endereço Identifica origem ou destino dos dados. P.e., CPU precisa ler uma instrução (dados) de determinado local na memória. Largura do barramento determina capacidade máxima da memória do sistema. P.e., 8080 tem barramento de endereço de 16 bits gerando espaço de endereços de 64k. O barramento de endereços dos sistemas de 32 bits permite endereçar, no máximo, 4 GB de RAM. Barramento de controle Informação de controle e temporização: Sinal de leitura/escrita de memória. Sinal de leitura/escrita de E/S. ACK de transferência. Solicitação de barramento. Concessão de barramento. Requisição de interrupção. ACK de interrupção. Clock. Reset. Estrutura de barramento Se um módulo deseja enviar dados para outro, ele precisa fazer duas coisas: (1) obter o uso do barramento e (2) transferir dados por meio do barramento. Se um módulo quiser requisitar dados de outro módulo, ele precisa: (1) obter o uso do barramento e (2) transferir uma requisição ao outro módulo pelas linhas de controle e endereço apropriadas. (3) Esperar que esse segundo módulo envie os dados. Esquema de interconexão de barramento Como os barramentos se parecem? Linhas paralelas em placas de circuito. Cabos de fita. Conectores em tira nas placas mãe. P.e., PCI. Conjuntos de fios. Problemas do barramento único Muitos dispositivos em um barramento levam a: Atrasos de propagação Longos caminhos de dados significa que a coordenação do uso do barramento pode afetar contrariamente o desempenho. Se a demanda de transferência de dados agregada se aproxima da capacidade do barramento. A maioria dos sistemas utiliza múltiplos barramentos para contornar esses problemas. Arquitetura de barramento tradicional Arquitetura de alto desempenho Elementos do projeto de barramento Tipos de barramento Dedicado: Linhas separadas para dados e endereço. Multiplexado. Linhas compartilhadas. Linha de controle válidas de endereço ou dados. Vantagem Menos linhas Desvantagens: Controle mais complexo. Desempenho máximo. Método de arbitração Arbitração pode ser: Centralizada Existe um árbitro de barramento, responsável por alocar tempo no barramento. Módulo separado ou parte do processador. Distribuída Não existe controlador central. Cada módulo contém lógica de controle de acesso e os módulos atuam juntos para compartilhar o barramento. Finalidade: designar um dispositivo como mestre (inicia a transferência) e outro como escravo (receptor). Temporização Coordenação de eventos no barramento. Síncrona: Eventos determinados por sinais de clock. Barramento de controle inclui linha de clock. Uma única transmissão 1-0 é um ciclo do barramento. Todos os dispositivos podem ler linha de clock. Normalmente, sincronismo na borda inicial. Geralmente, um único ciclo para um evento. Diagrama de temporização síncrona Temporização Assíncrona: A ocorrência de um evento em um barramento segue e depende da ocorrência de um evento anterior. É flexível porém mais complexa de implementar e testar (em relação ao método síncrono) Pode-se misturar dispositivos lentos e rápidos, compartilhando o barramento. Temporização de operações de barramento assíncronas Outros elementos de projeto Largura do barramento Impacto sobre o desempenho do sistema (dados) ou sobre a capacidade máxima de memória endereçável (endereço). Quanto mais trilhas, mais caro. Tipo de transferência de dados Escrita (mestre para escravo). Leitura (escravo para mestre). Multiplexado (endereço e dados). Leitura-modificação-escrita. Leitura-após-escrita. Transferência de dados em bloco. Para casa... Estudar a seção 3.5 sobre o barramento PCI, onde todos os elementos de projeto são explicados na prática. Fazer exercícios. A Memória do Computador Visão geral Cache Interna/Externa A memória do computador Visão geral do sistema de memória do computador [4.1] Memória cache [4.2] Memória interna/principal [5.1] Memória externa/secundária Disco magnético [6.1] RAID [6.2] MemóriaFlash e SSD’s [não presente no livro] Memória óptica [6.3] Fita magnética [6.4] Principais Pontos A memória do computador é organizada em hierarquia. Registradores Cache(s) Memória principal (RAM) Memória externa/secundária HD, Discos Opticos, Fita, etc. Hierarquia Nível alto = alto custo, capacidade menor, alta velocidade (menor tempo de acesso). Nível baixo = baixo custo, capacidade maior, baixa velocidade (maior tempo de acesso). Principais Pontos Memória cache: Tentativa de manter os dados mais acessados pelo processador. Tipos de RAM Dinâmica (DRAM) = Memória Principal Estática (SRAM) = Memória Cache Discos magnéticos (HD’s): Componentes mais importantes da memória externa. RAID: Técnica com múltiplos discos a fim de atingir maior confiabilidade e/ou velocidade. Memória Flash e SSD’s Armazenamento Óptico CD, DVD, Blu-ray, etc... Visão geral do sistema de memória do computador Características dos sistemas de memória: Localização. Capacidade. Unidade de transferência. Método de acesso. Desempenho. Tipo físico. Características físicas. Organização. Localização Memória presente na CPU Registradores Cache (hoje, praticamente todos os processadores incluem a cache no próprio núcleo). Memória Interna/Principal RAM Memória Externa/Secundária Armazenamento periférico (acessado via E/S) Unidade Magnética (HD) Unidades Opticas (CD, DVD, Blu-ray) Unidades Semicondutora (Memória Flash) Capacidade Normalmente expressa em bytes (e seus múltiplos) Lembrando que alguns dispositivos podem ter os múltiplos do byte arredondados para baixo: 1 KB 1024 bytes (Real) | 1000 bytes (HDs, p.e.) 1 GB 1.073.741.824 bytes (Real) | 1.000.000.000 (HDs, p.e.) Unidade de transferência Memória Interna Número de linhas elétricas do módulo de memória Pode ser igual ao tamanho da palavra, porém frequentemente é maior (para compensar o fato da memória ser mais lenta que a CPU) Ex: PCs modernos = 64 bits Porém há dual channel: 2 x 64 bits = 128 bits por transferência. Conceitos Palavra: Unidade “natural” de organização da memória. Unidades endereçáveis: por palavra ou por byte. De qualquer forma, sempre haverá 2nbits endereços. Unidade de transferência: número de bits lidos/escritos na memória de uma só vez (memória principal). Não é, necessariamente, igual a uma palavra ou unidade endereçável (ex: transf. em blocos, nos HD’s) Método de acesso Sequencial Organização em unidades chamadas registros. Começa no início e lê em ordem. Tempo de acesso depende da localização dos dados e local anterior. Por exemplo, fita. Direto Blocos individuais possuem endereço exclusivo. Acesso saltando para vizinhança, mais busca sequencial. Tempo de acesso depende da localização e local anterior. Por exemplo, disco. Método de acesso Aleatório Endereços individuais identificam localizações com exatidão. Tempo de acesso é independente da localização ou acesso anterior. Por exemplo, RAM. Associativo Dados são localizados por uma comparação com conteúdo de uma parte do armazenamento (ao invés do seu endereço). Tempo de acesso é independente do local ou acesso anterior. Por exemplo, cache. Desempenho Tempo de acesso (latência): Tempo entre apresentar o endereço e obter os dados válidos. Tempo de ciclo de memória: Tempo que pode ser exigido para a memória se “recuperar” antes do próximo acesso. Tempo de ciclo é acesso + recuperação. Taxa de transferência: Taxa em que os dados podem ser movidos. Tecnologias Semicondutora RAM, Cache, Flash, ... Superfície magnética HD’s e fitas Ótica CD, DVD, Blu-ray, etc. Magneto-optica Outras Características físicas Deterioração. Volatilidade. Apagável. Consumo de energia. Organização Arranjo físico dos bits em palavras. Nem sempre óbvia. Por exemplo, intercalada. A hierarquia de memória Os pilares das restrições de projeto de memórias Quanto? (capacidade) Com que velocidade? Com que custo? Relações básicas: Tempo de acesso mais rápido Maior custo por bit. Maior capacidade Menor custo por bit. Maior capacidade Tempo de acesso mais lento. O dilema, é, portanto, claro: Não dá para atender a todos os requisitos ao mesmo tempo. É preciso encontrar um equilíbrio satisfatório. A hierarquia de memória Ao descer na hierarquia: Menor custo/bit Aumento da capacidade Aumento do tempo de acesso. Frequência de acesso é menor. Lista de hierarquia Registradores. Cache L1. Cache L2. Cache L3. Memória principal (RAM). Cache de disco (RAM ou módulo separado). Disco. Óptica. Fita. A hierarquia de memória É possível montar um computador que usa apenas RAM estática (conforme veremos adiante). Este seria muito rápido. Este não precisaria de cache. Isso sairia muito caro. Solução? Hierarquia de memória. Localidade de referência Durante o curso da execução de um programa, as referências à memória tendem a se agrupar. Por exemplo, loops. As cache são pequenas e rápidas, e se baseiam nesse princípio Memória cache Pequenas... porém velozes! Princípios da memória cache O uso da memória cache visa obter velocidade de memória próxima das memórias mais rápidas que existem e, ao mesmo tempo, disponibilizar uma memória de grande capacidade ao preço de memórias semicondutoras mais baratas. Pequena quantidade de memória rápida. Fica entre a memória principal normal e a CPU. Pode estar localizada no chip da CPU ou módulo. Cache e memória principal Estrutura de cache/memória principal Operação da cache Visão geral CPU requisita conteúdo do local de memória. Verifica se os dados estão em cache. Se estiverem, apanha da cache (rápido). Se não, lê bloco solicitado da memória principal para a cache e paralelamente entrega à CPU. Cache inclui tags para identificar qual bloco da memória principal está em cada slot da cache. Operação de leitura de cache Fluxograma Memória interna/principal (RAM) Nem tão rápidas, mas essenciais! Memória Interna Em termos práticos, a memória interna é principalmente a RAM. Esta é a memória “de trabalho” do computador, onde os programas e dados são armazenados enquanto são processados. É impossível executar um programa “direto do HD”. Quando se dá duplo-clique para se executar um programa, é preciso saber que, primariamente, ele é copiado para a RAM. Somente após isso, suas instruções começam a ser executadas. A RAM é feita com semicondutores. Memória principal semicondutora (MUITO) Antigamente a memória principal empregava uma matriz de loops ferromagnéticos em forma de anel, chamados de núcleos (cores, em inglês). Em seguida passaram para chips semicondutores. Examinaremos: Organização; DRAM e SRAM; Tipos de ROM; Lógica e empacotamento do chip; Organização do módulo; Memória intercalada; Memória principal semicondutora Organização Elemento principal: célula de memória. Princípios básicos são praticamente idênticos em qualquer tecnologia: Dois estados: 1 e 0; Podem ser escritas (ao menos uma vez); Podem ser lidas. Memória principal semicondutora DRAM e SRAM Memória principal semicondutora DRAM e SRAM RAM Random Access Memory. Nome incorreto, pois toda memória de semicondutor tem acesso aleatório. Leitura/escrita. Volátil. Armazenamento temporário. Estática ou dinâmica. Memória principal semicondutora DRAM e SRAM RAM Dinâmica Bits armazenados com carga em capacitores. As cargasvazam. Precisa de renovação mesmo se alimentada (refresh). Construção mais simples. Menor por bit. Mais barata. Mais lenta. Memória principal. Dispositivo basicamente analógico. Nível de carga determina o valor. Memória principal semicondutora DRAM e SRAM Operação da DRAM Linha de endereço ativa quando bit é lido ou escrito. Chave de transistor fechada (corrente flui). Escrita: Voltagem na linha de bit. Alta para 1 baixa para 0. Depois sinaliza linha de endereço. Transfere carga ao capacitor. Leitura: Linha de endereço selecionada. Transistor liga. Carga do capacitor alimentada por linha de bit para amplificador comparar. Compara com valor de referência para determinar 0 ou 1. Carga do capacitor deve ser restaurada. Memória principal semicondutora DRAM e SRAM RAM Estática Bits armazenados como chaves ligado/desligado. Sem carga para vazar. Não precisa de refresh quando alimentada. Construção mais complexa. Maior por bit. Mais cara. Mais rápida. Cache. Digital. Usa flip-flops. Memória principal semicondutora DRAM e SRAM Operação da SRAM Arranjo de transistores gera estado lógico estável. Estado 1: C1 alta, C2 baixa. T1 T4 desligados, T2 T3 ligados. Estado 0: C2 alto, C1 baixo. T2 T3 desligados, T1 T4 ligados. Linha de endereço controla dois transistores, T5 T6. Escrita – aplica valor a B e complemento a B. Leitura – valor está na linha B. Memória principal semicondutora DRAM e SRAM SRAM versus DRAM Ambas voláteis. É preciso energia para preservar os dados. Célula dinâmica: Mais simples de construir, menor. Mais densa. Mais barata. Precisa de refresh. Maiores unidades de memória. Célula estática: Mais rápida. Cache. Memória principal semicondutora ROM ROM: Read Only Memory Armazenamento permanente. Não volátil. Microprogramação (veja mais adiante). Sub-rotinas de biblioteca. Programas do sistema (BIOS). Tabelas de função. Gravada durante a fabricação: Muito cara para pequenas quantidades. Memória principal semicondutora ROM Programável (uma vez): PROM. Precisa de equipamento especial para programar. Lida “na maioria das vezes” (“principalmente de leitura”): Erasable Programmable (EPROM). Apagada por UV. Electrically Erasable (EEPROM): Leva muito mais tempo para escrever que para ler. Memória flash: Apaga memória inteira eletricamente. Memória principal semicondutora Memória intercalada Coleção de chips de DRAM. Agrupada em banco de memória. Bancos atendem a solicitações de leitura ou escrita independentemente. K bancos podem atender a k solicitações simultaneamente. Exemplo comercial: Dual-Channel (2 canais). Memória externa/secundária Relativamente lentas, porém... grande capacidade e não voláteis (não precisam de energia elétrica para manter os dados)! Memória Externa Disco magnético: RAID. Removível. Memória Flash Cartões de Memória SSD Óptica: CD-ROM. CD-Recordable (CD-R). CD-R/W. DVD. Fita magnética. Disco Magnético Substrato de disco coberto com material magnetizável (óxido de ferro... ferrugem) Substrato era alumínio. Agora é vidro. Maior uniformidade da superfície. Aumenta confiabilidade. Redução nos defeitos da superfície. Erros reduzidos de leitura/gravação. Alturas de voo mais baixas (veja adiante). Melhor rigidez. Maior resistência a choques e dados. Mecanismos de leitura e gravação Gravação e leitura por bobina condutora, chamada cabeça. Pode ser única cabeça de leitura/gravação ou separadas. Durante leitura/gravação, cabeça fica parada, placas giram. Gravação: Corrente pela bobina produz campo magnético. Pulsos enviados à cabeça. Padrão magnético gravado na superfície abaixo dela. Leitura (tradicional): Campo magnético movendo-se em relação à bobina produz corrente. Bobina é a mesma para leitura e gravação. Leitura (contemporânea): Cabeça de leitura separada e próxima da cabeça de gravação. Sensor magnetorresistivo (MR) parcialmente blindado. Resistência elétrica depende da direção do campo magnético. Operação em alta frequência. Densidade de armazenamento e velocidade mais altas. Cabeça de gravação indutora/leitura magnetorresistiva Organização e formatação de dados Anéis ou trilhas concêntricas. Lacunas entre as trilhas. Reduza a lacuna para aumentar a capacidade. Mesmo número de bits por trilha (densidade de compactação variável). Velocidade angular constante. Trilhas divididas em setores. Tamanho de bloco mínimo é de um setor (geralmente 521 bytes). Pode haver mais de um setor por bloco. Velocidade do disco Bit próximo do centro do disco girando passa por ponto fixo mais lento que o bit na borda do disco. Aumente espaçamento entre bits de diferentes trilhas. Gire disco em velocidade angular constante (CAV). Setores em forma de fatia de torta e trilhas concêntricas. Trilhas e setores individuais endereçáveis. Mova cabeça para determinada trilha e espere por determinado setor. Perda de espaço nas trilhas externas. Menor densidade de dados. Pode usar zonas para aumentar capacidade. Cada zona tem número fixo de bits por trilha. Circuito mais complexo. Diagrama de métodos de layout de disco Localizando setores Deve ser capaz de identificar início da trilha e setor. Formatar disco: Informações adicionais não disponíveis ao usuário. Marca trilhas e setores. Características físicas Cabeça fixa (rara) ou móvel. Removível ou fixo. Única ou dupla (mais comum) face. Prato único ou múltiplos. Mecanismo da cabeça: Contato (disquete). Lacuna fixa. Lacuna aerodinâmica (Winchester). Disco de cabeça fixa/móvel Cabeça fixa: Uma cabeça de leitura por trilha. Cabeças montadas sobre braço rígido fixo. Cabeça móvel: Uma cabeça de leitura e escrita por lado. Montada sobre um braço móvel. Removível ou não Disco removível: Pode ser removido da unidade e substituído por outro disco. Oferece capacidade de armazenamento ilimitada. Transferência de dados fácil entre sistemas. Disco não removível: Montado permanentemente na unidade. Múltiplas placas Uma cabeça por lado. Cabeças são unidas e alinhadas. Trilhas alinhadas em cada placa formam cilindros. Dados são espalhados pelo cilindro: Reduz movimento da cabeça. Aumenta velocidade (taxa de transferência). Trilhas e cilindros Parâmetros típicos da unidade de disco rígido (HD) Desempenho Tempo de busca: Movendo cabeça para trilha correta. Latência (rotacional): Esperando dados passarem sob a cabeça. Tempo de acesso= Busca + Latência. Taxa de transferência. Tempo de transferência 𝑇 = 𝑏 𝑟𝑁 onde: 𝑇 = 𝑡𝑒𝑚𝑝𝑜 𝑑𝑒 𝑡𝑟𝑎𝑛𝑠𝑓. 𝑏 = 𝑛𝑢𝑚. 𝑑𝑒 𝑏𝑦𝑡𝑒𝑠 𝑎 𝑠𝑒𝑟𝑒𝑚 𝑡𝑟𝑎𝑛𝑠𝑚𝑖𝑡𝑖𝑑𝑜𝑠 𝑁 = 𝑛ú𝑚. 𝑑𝑒 𝑏𝑦𝑡𝑒𝑠 𝑒𝑚 𝑢𝑚𝑎 𝑡𝑟𝑖𝑙ℎ𝑎 𝑟 = 𝑣𝑒𝑙𝑜𝑐𝑖𝑑𝑎𝑑𝑒 𝑑𝑒 𝑟𝑜𝑡𝑎çã𝑜 (𝑅𝑃𝑀) Total: 𝑇𝑎 = 𝑇𝑠 + 1 2 𝑟 + 𝑏 𝑟𝑁 RAID Redundant Array of Independent Disks. Redundant Array of Inexpensive Disks. 6 níveis de uso comum (Há outros não “oficiais”). Não é uma hierarquia. Conjunto dos principais discos vistos como uma única unidade lógica pelo S/O. Dados distribuídos pelas unidades físicas. Pode usar capacidade redundante. Pode usar capacidade redundante para armazenar informação de paridade. IMPORTANTE: RAID não é backup! RAID 0 Block-level striping without parity or mirroring. Não redundante. Dados espalhados por todos os discos. Mapeamento Round Robin. Maior velocidade. Múltiplas solicitações de dados provavelmente não no mesmo disco. Discos buscam em paralelo. Um conjunto de dados provavelmente será espalhado por múltiplos discos. RAID 1 Mirroring without parity or striping. Discos espelhados. Dados espalhados pelos discos. 2 cópias de cada stripe em discos separados. Leitura de qualquer um deles. Gravação em ambos. Recuperação é simples: Troca entre disco com defeito e espelho. Sem tempo de paralisação. Caro. RAID 2 Bit-level striping with dedicated Hamming-code parity. Discos são sincronizados. Stripes muito pequenos. Normalmente, único byte/palavra. Correção de erro calculada pelos bits correspondentes nos discos. Múltiplos discos de paridade armazenam correção de erro via código de Hamming em posições correspondentes. Muita redundância. Caro. Não usado. RAID 3 Byte-level striping with dedicated parity. Semelhante a RAID 2. Somente um disco redundante, não importa o tamanho do array. Bit de paridade simples para cada conjunto de bits correspondentes. Dados sobre unidade com defeito podem ser reconstruídos a partir de dados sobreviventes e informação de paridade. Taxas de transferência muito altas. RAID 4 Block-level striping with dedicated parity. Cada disco opera independentemente. Bom para taxa de solicitação de E/S alta. Grandes stripes. Paridade bit a bit calculada por stripes em cada disco. Paridade armazenada no disco de paridade. RAID 5 Block-level striping with distributed parity. Como RAID 4. Paridade espalhada por todos os discos. Alocação round-robin para stripe de paridade. Evita gargalo do RAID 4 no disco de paridade. Normalmente usado em servidores de rede. RAID 6 Block-level striping with double distributed parity. Dois cálculos de paridade. Armazenado em blocos separados em discos diferentes. Requisito do usuário de N discos precisa de N+2. Alta disponibilidade de dados. Três discos precisam falhar para haver perda de dados. Penalidade de gravação significativa. RAID: Mais informações Nível Mín. # de Drives Eficiência Espacial Tolerância a falhas Benefício Leitura Benefício Escrita 0 2 1 0 nX nX 1 2 1/n n-1 nX 1X 2 3 1 − 1/n ⋅ log2(n-1) 1 ? ? 3 3 1 − 1/n 1 (n−1)X (n−1)X 4 3 1 − 1/n 1 (n−1)X (n−1)X 5 3 1 − 1/n 1 (n−1)X (n−1)X 6 4 1 − 2/n 2 (n−2)X (n−2)X Memória Flash Diferentemente da memória RAM e também das SRAM, a memória Flash permite armazenar dados por longos períodos, sem precisar de alimentação elétrica. É muito usada em dispositivos portáteis, como pendrives, mp3 players, etc. Tipos: NOR: Mais antigos e fora de uso. NAND: Mais baratas e mais rápidas. Em uso atualmente. Do ponto de vista do sistema, um cartão de memória Flash NAND está mais para um HD do que para uma unidade de memória. Você pode usá-lo para guardar dados, mas na hora que o sistema precisa rodar um programa, precisa primeiro copiá-lo para a memória RAM, da mesma forma que faria ao usar um HD. Memória Flash O grande boom da memória Flash aconteceu entre 2004 e 2005, quando uma combinação de dois fatores fez com que os preços por MB caíssem rapidamente: Aumento brutal na produção e concorrência; Introdução da tecnologia MLC (Mult-Level Cell), onde cada célula passa a armazenar dois ou mais bits em vez de apenas um. Isso é possível graças ao uso de tensões intermediárias. Com 4 tensões diferentes, a célula pode armazenar 2 bits, com 8 pode armazenar 3 bits e assim por diante. Memória Flash Os chips "tradicionais", que armazenam um único bit por célula passaram a ser chamados de "SLC" (Single-Level Cell). São usados em SSDs de alto desempenho e por serem mais duráveis. Outra tecnologia usada pelos fabricantes para cortar custos e ao mesmo tempo permitir a criação de chips de maior densidade é o "Die- Stacking", onde dois ou mais chips são "empilhados", conectados entre si e selados dentro de um único encapsulamento, que possui o mesmo formato e contatos que um chip tradicional. Die-Stacking Cartões de memória flash Formatos: CompactFlash [CF] SmartMedia [SM] xD (Olympus e Fujifilm) MMC Memory Stick (Sony) Memory Stick Duo, Pro, Pro Duo, Micro e Pro-HG SD (Secure Digital), miniSD e microSD. SD: até 2 GB SDHC: até 32 GB SDXC: até 2 TB Estado sólido: Os SSDs Os SSDs ou "Solid State Drive" (discos de estado sólido) são possivelmente a maior revolução dentro do ramo dos HDs desde o IBM 350, já que eles utilizam um princípio de armazenamento completamente diferente, com os discos magnéticos dando lugar aos chips de memória Flash. Vantagens: Baixo tempo de acesso; Excelentes taxas de leitura e gravação em setores aleatórios; Consumo elétrico mais baixo; Silenciosos, resistentes a impactos e oferecem uma melhor segurança contra perda de dados devido a defeitos de hardware, já que não possuem partes móveis. Estado sólido: Os SSDs A grande desvantagem por outro lado é o custo por megabyte, já que em vez de combinar 4 discos magnéticos de 500 GB cada um para criar um HD de 2 TB, você precisa juntar 20 chips de memória Flash de 8 GB cada para criar um SSD de apenas 160 GB. Quanto mais gigabytes, mais chips, o que leva os preços dos drives de maior capacidade para as alturas. A grande maioria dos SSDs domésticos utilizam módulos de memória Flash MLC, assim como nos cartões e pendrives. Entretanto, eles oferecem um diferencial importante, que é o uso de múltiplos canais de acesso. Estado sólido: Os SSDs A maioria dos drives atuais utilizam 10 ou 20 chips de memória Flash (o que permite que os fabricantes produzam drives de baixa e alta capacidade usando as mesmas placas) e 10 canais de acesso simultâneo. Ao escrever um arquivo de 4 MB, por exemplo, o controlador o dividirá em 10 blocos de 400 KB cada um, que serão escritos simultaneamente em 10 chips diferentes, ocupando um total de 100 páginas de 4 KB em cada um. Ao ler o arquivo posteriormente, a leitura é novamente dividida entre os 10 chips, o que multiplica tanto a taxa de escrita quanto a de leitura, sem que exista penalidade com relação aos tempos de acesso. SSD’s Ciclos de Gravação e a Questão da Longevidade Um dos grandes problemas com as células de memória Flash é a longevidade. As células de memória Flash têm uma vida útil estimada em 100.000 regravações no caso dos chips SLC e apenas 10.000 regravações no caso dos MLC. Em um cartão de memória ou mesmo em um pendrive, este número não parece tão preocupante, já que, mesmo que enchesse o cartão da sua câmera todos os dias, você demoraria 30 anos para atingir as 10.000 regravações. Em um SSD, por outro lado, a coisa é um pouco mais séria, já que não apenas o volume de operações é muito maior (principalmente se for usada memória swap) mas também a importância dos dados armazenados é muito maior. Ciclos de Gravação e a Questão da Longevidade Para evitar que algumas áreas falhem prematuramente, inutilizando o disco, os fabricantes utilizam sistemas de wear leveling (distribuição de uso), que alteram os setores usados cada vez que arquivos são criados ou alterados. Com 10.000 operações de escrita por bloco, um SSD de 80 GB teria uma vida útil estimada em 800 TB de gravações, o que é um número difícil de atingir em situações normais, já que você precisaria gravar 40 GB de dados todos os dias por 60 anos para atingir a marca. Em resumo, a vida útil do SSD é especificada pelo fabricante como de 5 a 10 anos de uso intenso, o que é, de qualquer forma, bem mais que a média dos HDs magnéticos. Memória óptica Memória óptica CD-ROM Originalmente para áudio. 650 MB gerando mais de 74minutos de áudio. Posteriormente, 700 MB (80 minutos). Policarbonato com cobertura altamente reflexiva, normalmente alumínio. Dados armazenados como sulcos. Lidos pela reflexão do laser. Densidade de empacotamento constante. Velocidade linear constante. Operação do CD Velocidade do CD-ROM Áudio tem velocidade única: Velocidade linear constante. 1,2 m/s. Trilha (espiral) tem 5,27 km de extensão. Oferece 4391 segundos= 73,2 minutos. Outras velocidades indicadas por múltiplos. 1x = 150 KB/s 2x = 300 KB/s 56x = 8400 KB/s Valor indicado é o máximo que a unidade pode conseguir. Formato do CD-ROM Modo 0 =campo de dados em branco. Modo 1 =2048 bytes de dados + correção de erro. Modo 2 =2336 bytes de dados. Acesso aleatório no CD-ROM Difícil. Move cabeça para posição aproximada. Define velocidade correta. Lê endereço. Ajusta para local solicitado. (Boceja!) CD-ROM – prós e contras Grande capacidade (?). Fácil de produzir em massa. Removível. Robusto. Caro para pequenas quantidades. Lento. Somente de leitura. Outro armazenamento óptico CD-Recordable (CD-R): WORM (Write Once Read Many). Agora com preço acessível. Compatível com unidades de CD-ROM. CD-RW: Apagável. Ficando mais barato. Em grande parte compatível com unidade de CD- ROM. Mudança de fase: Material tem duas refletividades diferentes em diferentes estados de fase. DVD Digital Video Disk: Usado para indicar um player para filmes. Só toca discos de vídeo. Digital Versatile Disk: Usado para indicar uma unidade de computador. Lerá discos de computador e tocará discos de vídeo. Multicamadas. Capacidade “muito alta” (4,7 G por camada). Filme de tamanho completo em único disco. Usando compactação MPEG. Finalmente padronizado. Filmes transportam codificação regional. Players só tocam filmes da região correta. DVD – gravável Muito trabalho com padrões. Unidades de DVD de primeira geração podem não ler discos DVD-W de primeira geração. Unidades de DVD de primeira geração podem não ler discos CD-RW. Hoje: Versões oficiais DVD-Forum DVD-R DVD-RW DVD+RW Alliance DVD+R DVD+RW Discos ópticos de alta definição Projetados para vídeos de alta definição. Capacidade muito mais alta que DVD. Laser com comprimento de onda mais curto. Faixa do azul violeta. Sulcos menores. HD-DVD (Mórreu!): 15 GB de único lado, única camada. Blu-ray: Camada de dados mais próxima do laser. Foco mais estreito, menos distorção, sulcos menores. 25 GB em única camada. Disponível para apenas leitura (BD-ROM), gravável uma vez (BR-R) e regravável (BR-RE). Características da memória óptica Fita magnética Acesso serial. Lenta. Muito barata. Backup e arquivamento. Unidades de fita Linear Tape Open (LTO). Desenvolvida no final da década de 1990. Alternativa de fonte aberto para os diversos sistemas de fita patenteados. Unidades de fita Linear Tape Open (LTO) Entrada/Saída Aspectos básicos Principais pontos A arquitetura de E/S do sistema de computação é a sua interface com o mundo exterior. Esta arquitetura fornece um meio sistemático de controlar a interação com o mundo exterior e fornece ao sistema operacional as informações de que precisa para gerenciar a atividade de E/S de modo eficaz. Principais pontos Três técnicas principais: E/S programada: a E/S ocorre sob o controle direto e contínuo do programa solicitando a operação; E/S controlada por interrupção: programa emite um comando de E/S e depois continua a executar, até que seja interrompido pelo hardware de E/S para sinalizar o final da operação de E/S. Acesso direto à memória (DMA): processador de E/S especializado assume o controle de uma operação de E/S para mover um grande bloco de dados. Introdução O conjunto de módulos de E/S é o terceiro elemento chave de um sistema de computação, depois do processador e memória. Cada módulo se conecta ao barramento do sistema ou comutador central e controla um ou mais dispositivos periféricos. Um módulo de E/S não é simplesmente um conjunto de conectores mecânicos que conectam um dispositivo fisicamente ao barramento do sistema. O módulo de E/S contém uma lógica para realizar uma função de comunicação entre o periférico e o barramento. Problemas de entrada/saída Grande variedade de periféricos: Entregando diferentes quantidades de dados. Em velocidades diferentes. Em formatos diferentes. Todos mais lentos que CPU e RAM. Precisa de módulos de E/S. Módulo de entrada/saída Interface com CPU e memória. Interface com um ou mais periféricos. Dispositivos externos Legíveis ao ser humano: Monitor, impressora, teclado. Legíveis à máquina: Monitoração e controle. Comunicação: Modem. Placa de interface de rede (NIC). Diagrama em blocos de um dispositivo externo Função do módulo de E/S Controle e temporização. Comunicação com CPU. Comunicação com dispositivo. Buffering de dados. Detecção de erro. Etapas da E/S CPU verifica estado do dispositivo do módulo de E/S. Módulo de E/S retorna o estado. Se estiver pronto, CPU solicita transferência de dados. Módulo de E/S recebe dados do dispositivo. Módulo de E/S transfere dados à CPU. Variações para saída, DMA etc. Diagrama do módulo de E/S Técnicas de E/S Programada. Controlada por interface. Acesso direto à memória (DMA). Três técnicas para entrada de um bloco de dados E/S Programada CPU tem controle direto sobre E/S: Conhecendo o estado. Comandos de leitura/escrita. Transferindo dados. CPU espera que módulo de E/S termine a operação. Desperdiça tempo de CPU. E/S programada – detalhe CPU solicita operação de E/S. Módulo de E/S realiza operação. Módulo de E/S define bits de estado. CPU verifica bits de estado periodicamente. Módulo de E/S não informa à CPU diretamente. Módulo de E/S não interrompe CPU. CPU pode esperar ou voltar mais tarde. Comandos de E/S CPU emite endereço: Identifica módulo (& disp. se >1 por módulo). CPU emite comando: Controle – dizendo ao módulo o que fazer. P.e., girar disco Teste – verifica estado: P.e., alimentado? Erro? Leitura/escrita: Módulo transfere dados via buffer de/para dispositivo. E/S controlada por interrupção Contorna problema de espera da CPU. Sem verificação de dispositivo repetida da CPU. Módulo de E/S interrompe quando estiver pronto. Operação básica: CPU emite comando de leitura. Módulo de E/S recebe dados do periférico enquanto CPU faz outro trabalho. Módulo de E/S interrompe CPU. CPU solicita dados. Módulo de E/S transfere dados. Processamento de interrupção simples Acesso direto à memória (DMA) E/S controlada por interrupção e programada exige intervenção ativa da CPU. Taxa de transferência é limitada. CPU fica amarrada. DMA é a resposta. Função do DMA: Módulo adicional (hardware) no barramento. Controlador de DMA toma o comando da CPU para E/S. Diagrama típico do módulo de DMA Operação do DMA CPU diz ao controlador de DMA: Leitura/escrita. Endereço do dispositivo. Endereço inicial do bloco de memória para dados. Quantidade de dados a serem transferidos. CPU prossegue com outro trabalho. Controlador de DMA lida com transferência. Controlador de DMA envia interrupção quando terminar. Transferência de DMA Roubo de ciclo Controlador de DMA assume o barramento por um ciclo. Transferência de uma palavra de dados. Não uma interrupção. CPU nãotroca de contexto. CPU suspensa logo antes de acessar o barramento. Ou seja, antes de uma busca de operando ou dados ou uma escrita de dados. Atrasa a CPU, mas não tanto quanto a CPU fazendo transferência. DMA e pontos de interrupção durante um ciclo de instrução Aritmética do Computador Inteiros Ponto Flutuante Principais pontos Duas principais questões para a aritmética (inteiro e ponto flutuante) do computador: Modo como os números são representados (o formato binário); Algoritmos usados para as operações aritméticas básicas (adição, subtração, multiplicação e divisão); Números de ponto flutuante são expressos como um número (significando) multiplicado por uma constante (base) elevada a alguma potência inteira (expoente). IEEE 754 32 e 64 bits. Unidade Lógica e Aritmética (ULA) Aritmetic and Logic Unit (ALU) Faz os cálculos. Tudo o mais no computador existe para atender a essa unidade. Trata de inteiros. Pode tratar de números de ponto flutuante (reais). Pode ser FPU separada (coprocessador matemático). A partir do Intel 486DX, é integrada a CPU. Entradas e saídas da ALU Aritmética de Inteiros Um mundo “ideal”... Representação de inteiros No sistema numérico binário, números quaisquer podem ser representados apenas com os algarismos 0 e 1, o sinal de menos e a vírgula, ou vírgula fracionada. -1101,01012 = -13,312510 Para finalidades de armazenamento e processamento no computador, porém, não temos o benefício dos sinais de menos e vírgula (que, como veremos, podem ser representados de outras formas) Se nos limitarmos a não negativos, a representação é direta. 00000000 = 0 00000001 = 1 00101001 = 41 10000000 = 128 11111111 = 255 De modo geral, se temos uma sequencia de n bits an-1an-2a1a0 como um inteiro sem sinal, seu valor A será: 𝐴 = 2𝑖𝑎𝑖 𝑛−1 𝑖=0 Sinal-Magnitude Bit mais à esquerda é bit de sinal. 0 significa positivo. 1 significa negativo. Exemplos: +18 = 00010010. -18 = 10010010. Problemas: Precisa considerar sinal e magnitude na aritmética. Duas representações de zero (+0 e -0). Mais difícil de testar se um resultado é zero (operação muito comum em computação) Por isso, raramente é usada na prática. Complemento a dois +127 = 01111111 +3 = 00000011 +2 = 00000010 +1 = 00000001 +0 = 00000000 -1 = 11111111 -2 = 11111110 -3 = 11111101 -128 = 10000000 Benefícios do complemento a dois Uma representação de zero. Aritmética funciona com facilidade (ver mais adiante). Negação é muito fácil. +3 00000011 Complemento Booleano gera 11111100 Some 1 ao LSB e tem-se -3 11111101 Negação especial Caso 1: 0 = 00000000 Not bit a bit 11111111 Some 1 ao LSB +1 Resultado 1 00000000 Estouro ignorado, portanto, - 0 = + 0 Caso 2: -128 = 10000000 Not bit a bit 01111111 Some 1 ao LSB +1 Resultado 10000000 Portanto: -(-128) = -128 (ERRO!) Monitore MSB (bit de sinal). Ele deve mudar durante a negação. Intervalo de números Complemento a 2 com 8 bits: +127 = 01111111 = 27 -1 -128 = 10000000 = -27 Complemento a 2 com 16 bits: +32767 = 011111111 11111111 = 215 - 1 -32768 = 100000000 00000000 = -215 Complemento a dois Resumo... Representação de inteiros Conversão entre tamanhos Pacote de número positivo com zeros iniciais. +18 = 00010010 +18 = 00000000 00010010 Pacote de números negativos com uns iniciais. -18 = 10010010 -18 = 11111111 10010010 Ou seja, pacote com MSB (bit de sinal). Aritmética com inteiros Adição Adição binária normal. Monitore estouro no bit de sinal. Exemplos: Aritmética com inteiros Subtração Pegue o complemento a dois do subtraendo e some ao minuendo. a - b = a + (-b). Exemplos: Hardware para adição e subtração Multiplicação Se comparada a adição e subtração, a multiplicação é uma operação complexa. Dois casos a se considerar: Inteiros sem sinal Inteiros com sinal Multiplicação de inteiros sem sinal É realizada tal qual todos nós já aprendemos com lápis e papel aplicada aos números decimais. No entanto é até mais simples! Exemplo: Multiplicação de inteiros com sinal O método estudado não funciona! Solução 1: Converta para positivo, se for preciso. Multiplique como antes. Se sinais diferentes, negue a resposta. Solução 2: Algoritmo de Booth É computacionalmente mais leve, porém, por ser bem mais complexo de entender, não será estudado. É preciso simplificar o capítulo para que possamos cumprir com a ementa. Divisão Ainda mais complexa que a multiplicação. Números negativos são realmente maus! Baseada na divisão longa. Logo... Aritmética de Ponto Flutuante Um mundo “nem tão ideal”... Representação de Ponto Flutuante Com a notação de ponto fixo é possível representar um intervalo de inteiros positivos e negativos centrados em 0. Assumindo um binário fixo e ponto fracionário, esse formato permite a representação de números também com componente fracionário. Limitações: Números muito grandes não podem ser representados, nem frações muito pequenas. A parte fracionária do quociente em uma divisão de dois números grandes poderia ser perdida. Solução? Representação em ponto flutuante (ideia derivada da notação científica). Ponto Flutuante Formato: ±𝑆 × 𝐵±𝐸 Três campos: Sinal: mais (0) ou menos (1). Significando S. Expoente E. A base B é implicita e não precisa ser armazenada. Formato típico de ponto flutuante de 32 bits Ponto Flutuante Mantissa é armazenada em complemento a dois. Expoente usa a chamada representação polarizada. Um valor fixo, chamado de polarização, é subtraído do campo para obter o valor verdadeiro do expoente. Normalmente é igual a 2k-1-1. Exemplo: k = 8 (bits) Polarização = 127 (27-1) Intervalo de valor puro 0-255. Subtraia 127 para obter valor correto. Intervalo de -127 a +128. Ponto Flutuante: Normalização Números de PF geralmente são normalizados, ou seja, expoente é ajustado de modo que bit inicial (MSB) do significando seja 1. Por ser sempre 1, não é preciso armazená-lo. Ponto flutuante normalizado: ±1. 𝑏𝑏𝑏…𝑏 × 2±𝐸 Campo de 23 bits é usado para armazenar um significando de 24 bits com um valor no intervalo meio aberto [1,2) Ponto Flutuante: Intervalos Padrão IEEE para representação binária de ponto flutuante (IEEE 754) Formato: Convertendo... Decimal ↔ IEEE 754 (32 bits) −26,5 𝑏𝑖𝑛á𝑟𝑖𝑜 − 11010,1 × 20 𝑛𝑜𝑟𝑚𝑎𝑙𝑖𝑧𝑎çã𝑜 − 1, 10101 × 24 1.10000011.10101000000000000000000 4 + 127 = 131 −7,1875 𝑏𝑖𝑛á𝑟𝑖𝑜 − 111,0011 × 20 𝑛𝑜𝑟𝑚𝑎𝑙𝑖𝑧𝑎çã𝑜 − 1, 110011 × 22 1.10000001.11001100000000000000000 2 + 127 = 129 +20,8 𝑏𝑖𝑛á𝑟𝑖𝑜 + 10100, 1100 × 20 𝑛𝑜𝑟𝑚𝑎𝑙𝑖𝑧𝑎çã𝑜 + 1, 0[1001] × 24 0.10000011.01001100110011001100110 4 + 127 = 131 Parâmetros de formato IEEE 754 Ponto Flutuante: Densidade Números Inteiros (ponto fixo) = Espaçamento linear (uniforme) ao longo de todo intervalo. Números de Ponto Flutuante = Espaçamento não uniforme. Mais próximo da origem (zero) = maior densidade (ou seja, os números possíveis de serem representados ficam mais próximos). Mais afastado da origem = menor densidade. Ponto Flutuante: intervalo ou precisão? Ponto flutuante de 32 bits: 1 bit de sinal 8 bits de expoente 23 bits de significando Se aumentarmos o número de bits no expoente, expandimos o intervalo de números representáveis. Mas como apenas um número fixo de valores diferentes podem ser representados,reduzimos a densidade desses números e, portanto, a precisão. O único modo de aumentar esses dois fatores é usar mais bits. Comumente usados: 32 bits (precisão simples) 64 bits (precisão dupla) Aritmética de Ponto Flutuante Anomalias possíveis: Overflow de expoente: expoente positivo maior que o máximo possível. Underflow de expoente: expoente negativo menor que o mínimo possível (ex: -200 é menor que -127). Ou seja, o número é muito pequeno para ser representado. Underflow de significando: no alinhamento dos significandos, os dígitos podem sair pela extremidade direita do significando. Overflow de significando: adição de dois significandos com o mesmo sinal pode resultar em um carry pelo bit mais significativo. Adição e Subtração de PF Passo-a-passo: 0. É uma operação de subtração? Troque o sinal do subtraendo. 1. Verificação de zero. 2. Alinhamento do significando. 3. Adição. 4. Normalização Adição e Subtração de PF Multiplicação e Divisão de PF Passo-a-passo Verifique zero. Soma/subtraia expoentes . Multiplique/divida significandos (observe sinal). Normalize. Arredonde. Todos os resultados intermediários devem ser em armazenamento de tamanho duplo. Multiplicação de PF Divisão de PF Introdução à Programação em Baixo Nível Linguagem de Montagem Assembly x86 (16 bits) Introdução Linguagens de Computadores são geralmente divididas em 2 ou 3 níveis. Cada nível o quão abstrada (alto nível) ou quão próxima do hardware (baixo nível) esta se encontra. Alto nível Médio nível Baixo nível Introdução Alto nível Alto nível de abstração. Usam elementos da linguagem natural. Ocultam detalhes do hardware. Concentram-se na solução do problema e não nas características da máquina. Portabilidade. Alta produtividade. Ex: Java, C#, C/C++. Médio nível Classificação as vezes atribuída a linguagem C, por possuir características que englobam diferentes níveis. Baixo nível Baixíssimo nível de abstração. Dá acesso direto ao inteiro conjunto de instruções da máquina. Altamente específica para uma família de máquinas. Baixa produtividade. Ex: Assembly. (Linguagem de Montagem) Introdução O processador é somente capaz de processar instruções em nível de máquina (binário). Programas escritos em linguagem de alto nível precisam ser convertidos para linguagem de máquina usando tradutores ou compiladores. Compilador = Traduz de uma linguagem de alto nível para uma de baixo nível. Montador = “Traduz” de baixo nível para binário. Por que usar linguagem de montagem? Programar em linguagem de montagem é muito difícil. Além da produtividade ser baixa, manutenção dificultada, depuração mais ainda. Atualmente, é possível afirmar com segurança que os compiladores estão muito evoluídos e que, mesmo para programadores Assembly, é improvável que eles produzam um código muito melhor que um compilador. Então, por que alguém programaria em linguagem de montagem? Desempenho em trechos críticos. Otimizando trechos cruciais ao desempenho de um programa, principalmente com instruções especiais (SSE, AVX, AES, ...). Ex: sistemas de tempo real. Otimizando o tamanho do código em cenários de memória escassa (como em sistemas embarcados) Acesso direto à máquina. Útil no desenvolvimento de drivers, por exemplo. Aprofundamento nos conhecimentos da arquitetura de uma máquina. É o motivo de estarmos estudando agora. Alguns cenários de uso do Assembly Sistemas embarcados (memória reduzida); Drivers; Uso de instruções específicas da CPU; Otimização extrema (jogos e codecs por exemplo); Sistemas onde não existem compiladores; Sistemas de tempo real e processamento preciso (aviação, medicina, etc.); Vírus de computador; Engenharia reversa; Algoritmos criptográficos específicos. Linguagem de Montagem Alguns conceitos O que é? Fato: O computador (CPU) só entende instruções em binário. Estas estão armazenas na RAM. Se pudessemos “ver” um executável, ele seria simplesmente uma sequência de 0’s e 1’s, ou, melhor visto em hexadecimal: 8B542408 83FA0077 06B80000 0000C383 FA027706 B8010000 00C353BB 01000000 B9010000 008D0419 83FA0376 078BD98B C84AEBF1 5BC3 Uma função em código de máquina (x86-32) para calcular o n-ézimo numero de Fibonacci. O que é? No entanto, é muito mais fácil lembrar de abreviaturas: ADD (soma), SUB (Subtração), ... do que valores numéricos. Facilidades se comparada a linguagem de máquina: Nomes simbólicos ao invés de números. Endereços simbólicos ao invés de endereços reais. Vantagem: Acesso direto a todos os aspectos e instruções disponíveis na máquina-alvo (ao contrário de uma linguagem de alto nível) mas sem ter que lembrar dos códigos númericos das operações e manipular endereços numéricos das posições de memória. Linguagem de Montagem Um processador pode entender e executar instruções de máquina. Essas instruções são simples números binários armazenados no computador. Ex: N = I + J + K inicializa I=2, J=3, K=4. Programa começa no local 101. Dados começam em 201. Código: Carrega conteúdo de 201 em AC. Soma conteúdo de 202 a AC. Soma conteúdo de 203 a AC. Armazena conteúdo de AC em 204. Evolução: Dos binários à Linguagem de Montagem 101 0010 0010 0000 0001 102 0001 0010 0000 0010 103 0001 0010 0000 0011 104 0011 0010 0000 0100 201 0000 0000 0000 0010 202 0000 0000 0000 0011 203 0000 0000 0000 0100 204 0000 0000 0000 0000 Tr a d u ç ã o f e it a p e lo A ss e m b le r (M o n ta d o r) O que é um conjunto de instruções? A coleção completa de instruções que são entendidas por uma CPU. Processadores são implementados visando o conjunto de instruções da máquina. Em outras palavras, ao projetá-lo os engenheiros já tem em mente como ele será programado, desde sua concepção. Ex: Muitos programadores especializados em programar jogos reclamaram que o Emotion Engine (CPU do PS2) era difícil de programar. Detalhe: O EE é um processador incrível (para a época, claro). Instruções de computador Os elementos essenciais de uma instrução de computador são: Opcode (código de operação): especifica a operação a ser realizada; Referências de operando de origem e destino: especificam os locais de entrada e saída para a operação; Referência da próxima instrução: normalmente implícita. Exemplo: OBS: Na prática, o formato da instrução é muito mais complexo, com diferentes tamanhos e campos. Instruções de computador Categorias de opcodes: Operações aritméticas e lógicas; Movimentação de dados entre dois registradores, registrador e memória, ou dois locais de memória; E/S; Controle; Operandos fonte e destino podem estar em uma dessas áreas: Memória principal ou virtual; Registrador do processador; Imediato; Dispositivo de E/S. Número de endereços 3 endereços: Operando 1, Operando 2, Resultado. a = b + c. Não é comum. Precisa de palavras muito longas para manter tudo. 2 endereços: Um endereço servindo como operando e resultado. a = a + b. Reduz tamanho da instrução. Requer algum trabalho extra. Armazenamento temporário para manter alguns resultados. Número de endereços 1 endereço: Segundo endereço implícito. Normalmente, um registrador (acumulador). Comum nas primeiras máquinas. 0 (zero) endereços: Todos os endereços implícitos. Usa uma pilha. Ex: c = a + b push a push b add pop c. Exemplo Quantos endereços? Mais endereços: Instruções mais complexas (poderosas?). Mais registradores. Operações entre registradores são mais rápidas. Menos instruções por programa. Menos endereços: Instruções menos complexas (poderosas?). Mais instruções por programa. Busca/execução de instruções mais rápida. Modos de endereçamento A = Conteúdos de um campo de endereço dentro da instrução R = Conteúdos de um campo de endereço dentro da instrução que se refere a um registrador EA = Endereço real (efetivo) do local que contém o operando referenciado. (X) = Conteúdos do local de memória X ou do registrador X. Modos de endereçamento Tipos de operando As instruções de máquina operam sobre dados. Categorias gerais de dados mais importantes: Endereços Números Inteiro/ponto flutuante. Caracteres ASCII, etc. Dados lógicos Bits ou flags OBS: Existe diferença entre números e caracteres? Pergunte a um programador C! Projeto do conjunto de instruções Repertório de operações: Quantas operações? O que elas podem fazer? Qual a complexidade delas? Tipos de dados. Formatos de instrução: Tamanho do campo de código de operação. Número de endereços. Registradores: Número de registradores da CPU disponíveis. Quais operações podem ser realizadas sobre quais registradores? Modos de endereçamento (a seguir…). Discussão: RISC vs. CISC. Introdução à Programação em Assembly x86 (16 bits) CPU Intel 8086 Introdução Nosso estudo se dará baseado na consagrada arquitetura original desenvolvida pela Intel, denominada x86. Por que “original”? Arquitetura 16 bits (Original) 8086 até 80286 Arquitetura 32 bits (Extendida) [x86] 80386 até Pentium 4 Arquitetura 64 bits (Long mode) [x64] Pentium 4/Athlon 64 até hoje Introdução Nos três casos citados, a arquitetura posterior incorpora praticamente toda a arquitetura anterior (compatibilidade). A CPU Intel 8086 Registradores do 8086 General Purpose Registers (GPR) AX - the accumulator register (divided into AH / AL). BX - the base address register (divided into BH / BL). CX - the count register (divided into CH / CL). DX - the data register (divided into DH / DL). SI - source index register. DI - destination index register. BP - base pointer. SP - stack pointer. Segment Registers (SR) CS - points at the segment containing the current program. DS - generally points at segment where variables are defined. ES - extra segment register, it's up to a coder to define its usage. SS - points at the segment containing the stack. Special Purpose Registers (SPR) IP - the instruction pointer. flags register - determines the current state of the microprocessor. Registradores de Propósito Geral 4 registradores de propósito geral (AX, BX, CX, DX) são compostos por dois registradores de 8 bits separados. Por exemplo, se AX= 0011000000111001b, então AH=00110000b and AL=00111001b. Assim, quando você modifica quaisquer dos registradores de 8 bits, os de 16 bits relacionados também são atualizados, e vice-versa. "H" indica parte alta (high) e "L" a parte baixa (low). Segment Registers Apesar de ser possível armazenar qualquer tipo de dados em registradores de segmento, isto não é uma boa ideia. Os SR tem um propósito muito especial – apontar para blocos acessíveis de memória. Registradores de segmento trabalham juntos com os de propósito geral para acessar qualquer valor de memória. Ex: Para o endereço físico 12345h (hexadecimal), nós deveríamos setar DS = 1230h e SI = 0045h. Isto é bom uma vez que podemos acessar uma quantidade bem maior de memória (se comparado a um único registrador de 16 bits). A CPU calcula o endereço físico multiplicando o registrador de segmento por 10h e somando com o registrador de propósito geral (1230h * 10h + 45h = 12345h). Segment Registers O endereço formado com dois registradores é chamado de endereço efetivo. Por padrão, os registradores BX, SI e DI trabalham com o registrador de segmento DS. BP e SP trabalham junto com SS (segment register). Outros registradores de propósito geral não podem formar endereços efetivos. Por fim, apesar de BX poder formar um endereço efetivo, BH e BL não podem. Special Purpose Registers IP (Instruction Pointer) sempre trabalha junto com CS (Segment Register) e aponta para a instrução atualmente em execução. Flags Register são modificadas automaticamente pela CPU depois de operações matemáticas. Isso permite determinar o tipo de resultado e as condições de transferência de controle para outras partes do programa. Acesso à Memória Técnicas Acesso à Memória Para acessar a memória, nós podemos usar quatro registradores: BX, SI, DI, BP. Combinando esses registradores dentro de [ ], podemos acessar diferentes localizações de memória. As seguintes combinações são suportadas: [BX + SI] [BX + DI] [BP + SI] [BP + DI] [SI] [DI] d16 (variable offset only) [BX] [BX + SI + d8] [BX + DI + d8] [BP + SI + d8] [BP + DI + d8] [SI + d8] [DI + d8] [BP + d8] [BX + d8] [BX + SI + d16] [BX + DI + d16] [BP + SI + d16] [BP + DI + d16] [SI + d16] [DI + d16] [BP + d16] [BX + d16] Acesso à Memória d8 – indica um deslocamento imediato de 8 bits (signed), por exemplo: 22, 55h, -1, etc… d16 – indica um deslocamento imediato de 16 bits (signed), por exemplo: 300, 5517h, -259, etc... O deslocamento: Pode ser um valor imediato ou um offset de uma variável, ou ambos. Se existem vários valores, o montador “resolve” a expressão e calcula um único valor imediato. Pode estar dentro ou fora de [ ], dá no mesmo. É um valor com sinal (signed), assim, ele pode +/-. Acesso à Memória Por exemplo, vamos assumir que DS = 100, BX = 30, SI = 70. O seguinte modo de endereçamento: [BX + SI] + 25 é calculado pela CPU para o seguinte endereço físico: 100 * 16 + 30 + 70 + 25 = 1725. Por padrão, o registrador de segmento DS é usado em todos os modos, exceto aqueles com o registrador BP. Para esses, o registrador de segmento SS é usado. Em resumo, são válidas as combinações: Exemplo: [BX+5], [BX+SI], [DI+BX-4] BX SI + deslocamento BP DI Acesso à Memória O valor no registrador de segmento(CS, DS, SS, ES) é chamado de segmento, e o valor no registrador de propósito geral (BX, SI, DI, BP) é chamdo de offset. Quando DS contem o valor 1234h e SI contem o valor 7890h ele pode também ser gravador como 1234:7890. O endereço físico será 1234h * 10h + 7890h = 19BD0h. OBS: Se zero é “adicionado” a um número decimal, ele é multiplicado por 10. Entretanto, 10h = 16, assim, se zero é “adicionado”a um valor hexadecimal, ele é multiplicado por 16, por exemplo: 7h = 7 70h = 112 Acesso à Memória Observe que, quando você referencia um endereço, através de um registrador, como em [BX] muitas vezes o montador não sabe se você está lendo um byte ou uma word (2 bytes). Assim, deve-se usar os prefixos byte ptr ou b. – para byte. Ex: byte ptr [BX] ou b.[BX] word ptr ou w. – para word (2 bytes) Ex: word ptr [BX] ou w.[BX] A instrução MOV Copia o segundo operando (source/fonte) para o primeiro operando (destination/destino). O operando fonte pode ser um valor imediato, um GPR ou uma localização de memória. O operando de destino pode ser um GPR ou uma localização de memória. Ambos os operandos devem ser do mesmo tamanho, o qual pode ser um byte ou uma word. A instrução MOV Os seguintes tipos de operandos são suportados: MOV REG, memoryMOV memory, REG MOV REG, REG MOV memory, immediate MOV REG, immediate REG: AX, BX, CX, DX, AH, AL, BL, BH, CH, CL, DH, DL, DI, SI, BP, SP. memory: [BX], [BX+SI+7], variável, etc... immediate: 5, -24, 3Fh, 10001101b, etc... A instrução MOV Para registradores de segmento somente os tipos de MOV abaixo são suportados: MOV SREG, memory MOV memory, SREG MOV REG, SREG MOV SREG, REG SREG: DS, ES, SS, CS (este ultimo, somente como segundo operando) REG: AX, BX, CX, DX, AH, AL, BL, BH, CH, CL, DH, DL, DI, SI, BP, SP. memory: [BX], [BX+SI+7], variável, etc... A instrução MOV não pode ser usada para setar o valor dos registradores CS e IP. Variáveis Reservando espaço em memória Variáveis Uma variável é um local de memória. Para um programador, é muito mais fácil manter algum valor em uma variável chamada “var1” que no endereço 5A73:235B, especialmente quando você tem 10 ou mais variáveis. Dois tipos de variáveis são suportadas pelo emu8086, byte e word. Sintaxe: nome DB valor ; DB significa Define Byte. nome DW valor ; DW significa Define Word. nome: qualquer letra/digito, desde que comece com letra valor: hexadecimal/decimal/binário “?” (para variável não inicializada) Variáveis Exemplo: ORG 100h é uma diretiva de compilação (ela diz ao assembler como lidar com o código fonte). Ela é muito importante quando você trabalha com variáveis. Ela diz ao assembler que o executável será carregado no offset de 100h (256 bytes). Assim o assembler deveria calcular o endereço correto de todas as variáveis quando ele substitui os nomes de variáveis com seus offsets. Diretivas nunca são convertidas em qualquer código de máquina real. VAR1 = var1 (não é case-sentive). Variáveis (Exemplo de Execução) Observe que os nomes das variáveis foram substituidos por posições de memória. Por padrão, o segmento é carregado no registrador DS (quando arquivos .com são carregados, o valor de DS é o mesmo que CS – ou seja, dados e instruções ficam no mesmo segmento). O offset de VAR1 é 0108h, e o endereço completo é 0B56:0108. O offset de var2 é 0109h , e o endereço completo é 0B56:0109 word = 2 bytes. little-endian. offset: hex decimal ASCII Exemplo interessante Arrays Arrays podem ser visto como cadeias de variáveis. Uma string de texto, por exemplo, é um array de valores inteiros (ASCII). Exemplos de arrays: a DB 48h, 65h, 6Ch, 6Ch, 6Fh, 00h b DB 'Hello', 0 b é uma copia exata do array a. Quando o assembler vê uma string entre aspas, ele automaticamente converte-a para um conjunto de bytes. Arrays É possível acessar o valor de qualquer elemento em um array usando [ ], por exemplo, MOV AL, a[3]. É possível também usar um registrador de índice: BX, SI, DI, BP, por exemplo: MOV SI, 3 MOV AL, a[SI] Se for necessário declarar um array grande, pode-se usar o operador DUP: number DUP ( value(s) ) number: número de duplicatas a serem feitas. value: expressão que DUP vai duplicar. Ex: c DB 5 DUP(9) c DB 9, 9, 9, 9, 9 d DB 5 DUP(1, 2) d DB 1, 2, 1, 2, 1, 2, 1, 2, 1, 2 É claro que pode-se usar DB ou DW. Obtendo o endereço de uma variável Existem duas instruções que permitem obter o endereço (offset) de uma variável: LEA (Load Effective Address) OFFSET Exemplo: OBS: Lembre-se... Apenas BX, SI, DI, BP podem ser usados entre colchetes (apontadores de memória) Constantes Constantes são como variáveis, mas elas existem somente até que seu programa seja compilado (montado). Depois da definição de uma constante, seu valor não pode ser mudado. Para definir uma constante, a diretiva EQU é usada: name EQU < any expression > Exemplo: k EQU 5 MOV AX, k Interrupções Por que a roda não precisa ser reinventada... Interrupções Interrupções podem ser vistas como “funções”. Funções estas que tornam a programação muito mais fácil. Ao invés de escrever o código para imprimir um caractere, você pode simplesmente chamar a interrupção e ela fará isso por você. Apesar de existirem as chamadas interrupções de hardware, estamos interessados neste momento nas chamadas interrupções de software. Interrupções Para realizar uma interrupção de software, existe uma instrução chamada INT, que tem a sintexe: INT valor valor = qualquer número entre 0 a 255 (0 a FFh) Cada interrupção pode ter sub-funções. Para especificar uma sub-função, basta usar o registrador AH adequadamente antes de chamar a interrupção. Cada interrupção pode ter até 256 sub-funções (temos, assim até 256 * 256 = 65536 funções). Em geral, o registrador AH é usado. Mas algumas vezes outros registradores podem ser usados (geralmente para passar parametros ou dados para a sub-função) Interrupções (Exemplo) Instruções Aritméticas/Lógicas Para isso que uma CPU essencialmente existe! Instruções Aritméticas/Lógicas Muitas instruções aritméticas e lógicas afetam as flags de status do processador. São elas: Carry Flag (CF) – esta flag é setada para 1 quando ocorre um unsigned overflow. Ex: adicionar 2 bytes: 255 + 1 (resultado > 255). Quando não existe overflow, esta flag é setada para 0. Zero Flag (ZF) – setada para 1 quando o resultado é zero. Caso controário, é setada para 0. Sign Flag (SF) – setada para 1 quando o resultado é negativo. Quando o resultado é positivo é setada para 0. (Ou seja, é o bit mais significante) Overflow Flag (OF) – setada para 1 quando ocorre um signed overflow. Ex: adicionar 2 bytes 100 + 50 (resultado não está no intervalo -128...127). Parity Flag (PF) – setada para 1 quando existe um número par de bits 1 no resultado. Vale 0 caso contrário. Apenas os 8 bits menos significativos são analisados. Auxiliary Flag (AF) – setada para 1 quando ocorre um unsigned overflow pra nibble mais baixo (4 bits). Interrupt enable Flag (IF) – Quando esta flag é setada para 1 a CPU reage as interrupções de dispositivos externos. Direction Flag (DF) – Esta flag é usada por algumas instruções para processar dados. Instruções Aritméticas/Lógicas Existem, basicamente, três grupos de instruções: Primeiro grupo: ADD, SUB,CMP, AND, TEST, OR, XOR Segundo grupo: MUL, IMUL, DIV, IDIV Terceiro grupo: INC, DEC, NOT, NEG Lógicas Operações bit a bit. NOT, AND, OR e XOR. Lógicas Utilidade do AND: Usado como máscara que seleciona certo bits em uma palavra e zera o restante. Ex: 10100101 AND 00001111 = 00000101 Utilidade do XOR: Inversão de bits. Ex: 10100101 XOR 11111111 = 01011010 Utilidade do OR: “Setar” bits num determinado conjunto, mantendo o restante intacto. Ex: 10100101 OR 01100000 = 11100101 EQUAL também é um teste útil. Além das operações lógicas bit a bit, existe o deslocamento lógico. Primeiro grupo: ADD, SUB,CMP, AND, TEST, OR, XOR Tipos de operandos suportados: REG, memory memory, REG REG, REG memory, immediate REG, immediate REG: AX, BX, CX, DX, AH, AL, BL, BH, CH, CL, DH, DL, DI, SI, BP, SP. memory: [BX], [BX+SI+7], variable, etc... immediate: 5, -24, 3Fh, 10001101b, etc... Afetam as flags: CF, ZF, SF, OF, PF, AF. Depois da operação, o resultado é armazenado sempre no primeiro operando. CMP e TEST somente afetam as flags e não armazenam um resultado (são usadas para tomar decisões durante a execução do programa). Primeiro grupo: ADD, SUB,CMP, AND, TEST, OR, XOR ADD – Soma o primeiro com o segundo operando. SUB – Subtrai o segundo operando do primeiro operando. CMP – Faz o mesmo que SUB, mas afeta apenas as flags. AND – Operação lógica AND bit-a-bit entre os dois operandos. TEST – O mesmo que AND, mas afeta apenas as flags. OR – Operação lógica OR bit-a-bit. XOR – Operação lógicaXOR (OR exclusivo) bit-a-bit. Segundo grupo: MUL, IMUL, DIV, IDIV Tipos de operandos suportados: REG memory REG: AX, BX, CX, DX, AH, AL, BL, BH, CH, CL, DH, DL, DI, SI, BP, SP. memory: [BX], [BX+SI+7], variable, etc... MUL e IMUL afetam apenas as flags: CF, OF Quando o resultado é maior que o tamanho do operando, essas flags são setadas para 1, ou 0 caso contrário. Para DIV e IDIV as flags são indefinidas. Segundo grupo: MUL, IMUL, DIV, IDIV Multiplicação sem sinal (MUL) e com sinal (IMUL) Quando operando é um byte: AX = AL * operando. Quando operando é um word: (DX AX) = AX * operando. Divisão sem sinal (DIV) e com sinal (IDIV) Quando operando é um byte: AL = AX / operando AH = resto (módulo) Quando operando é um word: AX = (DX AX) / operando DX = resto (módulo) Terceiro grupo: INC, DEC, NOT, NEG Tipos de operandos suportados: REG memory REG: AX, BX, CX, DX, AH, AL, BL, BH, CH, CL, DH, DL, DI, SI, BP, SP. memory: [BX], [BX+SI+7], variable, etc... INC, DEC afetam as flags: ZF, SF, OF, PF, AF. NOT não afeta qulquer flag. NEG afeta as flags: CF, ZF, SF, OF, PF, AF. Terceiro grupo: INC, DEC, NOT, NEG INC – Incrementa o operando de 1. DEC – Decrementa o operando de 1. NOT – Nega (inverte) o operando, bit-a-bit. NEG – Torna o operando negativo (complemento de dois). Ou seja, nega bit-a-bit e soma 1. Operações de deslocamento e rotação a) SHR = Shift op. Right • MOV AL, 00000111b SHR AL, 1 ; AL = 00000011b, CF=1. b) SHL = Shift op. Left • MOV AL, 11100000b SHL AL, 1 ; AL = 11000000b, CF=1. c) SAR = Shift Arithmetic Op. Right • MOV AL, 0E0h ; AL = 11100000b SAR AL, 1 ; AL = 11110000b, CF=0. • MOV BL, 4Ch ; BL = 01001100b SAR BL, 1 ; BL = 00100110b, CF=0. d) SAL = Shift Arithmetic Op. Left • MOV AL, 0E0h ; AL = 11100000b SAL AL, 1 ; AL = 11000000b, CF=1. e) ROR = Rotate Op. Right • MOV AL, 1Ch ; AL = 00011100b ROR AL, 1 ; AL = 00001110b, CF=0. f) ROR = Rotate Op. Left • MOV AL, 1Ch ; AL = 00011100b ROL AL, 1 ; AL = 00111000b, CF=0. Controle do fluxo de execução Saltando de um ponto a outro do programa... Controle do fluxo de execução Controlar o fluxo de execução do programa é algo muito importante. É o momento em que seu programa pode tomar decisões de acordo com certas condições. Nem sempre desejamos que a próxima instrução a ser executada é aquela que, na RAM, vem imediatamente após a instrução atual (PC++). Assim, é preciso haver instruções que fazem transferência de controle, ou seja, mudam a sequência de execução de instruções. Motivações práticas: Repetição de instruções (loop); Tomada de decisão (if); Modularização (sub-rotinas); Tipos: Unconditional Jumps (saltos incondicionais) Short Conditional Jumps (saltos condicionais curtos) Unconditional Jumps A instrução básica que transfere o controle para outro ponto do programa é a JMP. Sintaxe básica: JMP label Onde label é um “rótulo” (nome) terminado com : declarado em algum ponto do programa. A instrução JMP pode saltar tanto para frente quando para trás, desde que esteja dentro do segmento de código atual (64 KB) Unconditional Jumps Exemplo: Short Conditional Jumps Diferente da instrução JMP que faz um salto incondicional, existem instruções que fazem saltos condicionais (salta somente se algumas condições forem satisfeitas). São divididas em três grupos: Jump que simplesmente testa uma flag. Jump para números com sinal. Jump para números sem sinal Jump instructions that test single flag Instrução Descrição Condição Instrução Oposta JZ , JE Jump if Zero (Equal). ZF = 1 JNZ, JNE JC , JB, JNAE Jump if Carry (Below, Not Above Equal). CF = 1 JNC, JNB, JAE JS Jump if Sign. SF = 1 JNS JO Jump if Overflow. OF = 1 JNO JPE, JP Jump if Parity Even. PF = 1 JPO JNZ , JNE Jump if Not Zero (Not Equal). ZF = 0 JZ, JE JNC , JNB, JAE Jump if Not Carry (Not Below, Above Equal). CF = 0 JC, JB, JNAE JNS Jump if Not Sign. SF = 0 JS JNO Jump if Not Overflow. OF = 0 JO JPO, JNP Jump if Parity Odd (No Parity). PF = 0 JPE, JP Jump instructions for signed numbers Instrução Descrição Condição Instrução Oposta JE , JZ Jump if Equal (=). Jump if Zero. ZF = 1 JNE, JNZ JNE , JNZ Jump if Not Equal (<>). Jump if Not Zero. ZF = 0 JE, JZ JG , JNLE Jump if Greater (>). Jump if Not Less or Equal (not <=). ZF = 0 and SF = OF JNG, JLE JL , JNGE Jump if Less (<). Jump if Not Greater or Equal (not >=). SF <> OF JNL, JGE JGE , JNL Jump if Greater or Equal (>=). Jump if Not Less (not <). SF = OF JNGE, JL JLE , JNG Jump if Less or Equal (<=). Jump if Not Greater (not >). ZF = 1 or SF <> OF JNLE, JG Jump instructions for unsigned numbers Instrução Descrição Condição Instrução Oposta JE , JZ Jump if Equal (=). Jump if Zero. ZF = 1 JNE, JNZ JNE , JNZ Jump if Not Equal (<>). Jump if Not Zero. ZF = 0 JE, JZ JA , JNBE Jump if Above (>). Jump if Not Below or Equal (not <=). CF = 0 and ZF = 0 JNA, JBE JB , JNAE, JC Jump if Below (<). Jump if Not Above or Equal (not >=). Jump if Carry. CF = 1 JNB, JAE, JNC JAE , JNB, JNC Jump if Above or Equal (>=). Jump if Not Below (not <). Jump if Not Carry. CF = 0 JNAE, JB JBE , JNA Jump if Below or Equal (<=). Jump if Not Above (not >). CF = 1 or ZF = 1 JNBE, JA Jumps condicionais Geralmente, quando se deseja comparar valores numéricos, a instrução CMP é usada (ela faz o mesmo que SUB, mas não gera resultado, afeta apenas as flags) A lógica é muito simples. Por exemplo: Comparar 5 e 2 5 – 2 = 3 O resultado é diferente de zero (ZF é setada para 0). Comparar 7 e 7 7 – 7 = 0 O resultado é igual a zero (ZF é setada para 1 e JZ ou JE irão executar o salto) Jumps condicionais Exemplo: Loops Loops são basicamente o mesmo que jumps, tanto que é possível codificar loops sem usar a instrução loop, usando simplesmente saltos condicionais e comparação. Mas, é exatamente isso que as instruções de loop fazem, usando o registrador CS para contar as iterações. Loops Instrução Operação e condição de salto Instrução Oposta LOOP decrease cx, jump to label if cx not zero. DEC CX and JCXZ LOOPE decrease cx, jump to label if cx not zero and equal (zf = 1). LOOPNE LOOPNE decrease cx, jump to label if cx not zero and not equal (zf = 0). LOOPE LOOPNZ decrease cx, jump to label if cx not zero and zf = 0. LOOPZ LOOPZ decrease cx, jump to label if cx not zero and zf = 1. LOOPNZ JCXZ jump to label if cx is zero. OR CX, CX and JNZ Loops (Exemplo) Jumps condicionais e loops Suas restrições Todos os jumps condicionais têm uma grande limitação: Diferente da instrução JMP, eles podem saltar apenas 127 bytes a frente ou 128 bytes atrás. Felizmente, é possível superar facilmente essa limitação usando um “truque” na lógica: Tome a instrução condicional oposta a desejada e faça ela saltar para label_x. Use a instrução JMP para saltar para o local desejado. Defina label_x: logo após a instrução JMP. Jumps condicionais e loops Suas restrições Procedimentos Modularizando e reaproveitando código... Procedimentos Um procedimento é um porção de código que pode ser chamada do seu programa a fim de fazer alguma tarefa específica. É semelhante a uma função no mundo Assembly. Muito mais rudimentar que numa função de alto nível, como o C, é claro. Eles tornam o programa mais estruturado e fácil de entender. Geralmente um procedimento retorna para o mesmo ponto de onde ele chamado. Procedimentos Chamada de Procedimento Permite economia de código (menos código) e modularidade (mais facilidade em programar). Envolve duas instruçõesbásicas: Instrução de salto para a região de memória do procedimento (CALL) Instrução de retorno do procedimento para o local em que foi chamado (RET). Técnicas para salvar o endereço de retorno: Registrador (limitada) Início do procedimento chamado (limitada) Topo da pilha (técnica mais geral) Chamada de procedimento Procedimentos Sintaxe nome PROC ;; código do procedimento RET name ENDP nome = nome do procedimento, também repetido no final a fim de “fechar” o código do procedimento. RET = volta para o ponto de onde o procedimento foi chamado. PROC e ENDP são diretivas de compilação, assim elas não são convertidas em qualquer código de máquina real. Servem apenas para que o compilador demarque o endereço do procedimento corretamente. CALL é a instrução usada para chamar o procedimento. Procedimentos (Exemplo) Procedimentos Existem várias formas de passar parâmetros para um procedimento. A forma mais fácil é usando registradores. Procedimentos (Exemplo) Procedimentos No entanto, conforme visto nos estudos teóricos, essa forma é limitada (pelo número de registradores). A forma mais geral (e nem tão complicada) é usando a pilha, com as operações PUSH e POP. Como? Antes de chamar o procedimento, dê um PUSH em cada parâmetro, um a um. Chame o procedimento. Como primeiras instruções dentro do procedimento, vá dando POP a fim de capturar os parametros. Lembrando que os mesmos “saem” da pilha na ordem inversa que “entraram”. A Pilha (The Stack) Importante estrutura de armazenamento temporário... A Pilha (The Stack) A pilha é uma área de memória usada para manter dados temporários. Ela é usada pela instrução CALL para manter o endereço de retorno do procedimento. A instrução RET restaura este valor da pilha e retorna para o offset de origem. Exatamente a mesma coisa ocorre quando a instrução INT chama uma interrupção. Ela armazena na pilha o registrador de flag, segmento de código e offset. A instrução IRET é usada para retornar ao ponto onde a interrupção foi chamada. Podemos também usar a pilha para manter qualquer outro tipo de dados. Existem duas instruções para trabalhar com a pilha: PUSH – Armazena um valor de 16 bits na pilha. POP – Lê um valor de 16 bits da pilha. A Pilha (The Stack) Sintaxe da instrução PUSH: PUSH REG PUSH SREG PUSH memory PUSH immediate REG: AX, BX, CX, DX, DI, SI, BP, SP. SREG: DS, ES, SS, CS. memory: [BX], [BX+SI+7], 16 bit variable, etc... immediate: 5, -24, 3Fh, 10001101b, etc... Sintaxe da instrução POP: POP REG POP SREG POP memory REG: AX, BX, CX, DX, DI, SI, BP, SP. SREG: DS, ES, SS, (except CS). memory: [BX], [BX+SI+7], 16 bit variable, etc... A Pilha (The Stack) A pilha usa o algoritmo LIFO (Last In First Out). Isto significa que… Se nós empilharmos com a instrução PUSH esses valores, um a um na pilha: 1, 2, 3, 4, 5 O primeiro valor que iremos desempilhar com a instrução POP será 5, depois 4, 3, 2, 1. A Pilha (The Stack) É muito importante fazer o mesmo número de PUSHs e POPs. Caso contrário, a pilha pode ser corrompida e será impossível retornar para o sistema operacional. Como sabemos, nós usamos a instrução RET para retornar ao sistema operacional. Assim, quando o programa começa, existe um endereço de retorno na pilha. PUSH e POP são especialmente úteis porque não temos tantos registradores disponíveis para operar. Assim, existe um truque útil (e necessário): Armazene o valor original do registrdor na pilha (usando PUSH). Use o registrador para algum propósito. Restaure o valor original do registrador da pilha (usando POP). Existem, inclusive, duas instruções interessantes: PUSHA e POPA. Advinha o que fazem! A Pilha (The Stack) – Exemplos A Pilha (The Stack) A área de memória da pilha é setada pelos registradores SS (Stack Segment) e SP (Stack Pointer). Geralmente, o S.O. seta esses valores no começo do programa. A instrução "PUSH source" faz o seguinte: Subtrai 2 do registrador SP. Escreve o valor de source no endereço SS:SP. A instrução "POP destination" faz o seguinte: Escreve o valor no endereço SS:SP para destination. Soma 2 ao registrador SP. O endereço atual apontado por SS:SP é chamado de topo da pilha. Macros Parecem procedimentos, mas não são... Macros Macros são como procedimentos, mas eles só existem até que seu código seja compilado (montado). Depois disso, todas as macros são substituidas por instruções reais. Se uma macro for declarada, mas nunca for usada, o montador irá simplesmente ignorá-la. O arquivo inc\emu8086.inc é um bom exemplo de como macros podem ser usadas. Alias, esta será uma das tarefas de vocês. Estudar e compreender cada coisa que é feita dentro desse arquivo. Se desejar usar quaisquer das macros presentes nele, não faça simplesmente um “include” e use. Você deverá copiar o código da macro desejada e inserir no seu trabalho. Isso o forçará a entender melhor o que está sendo feito. Agora não é hora de usar o princípio da “Caixa Preta”. ;-) Macros Definindo uma macro: nome MACRO [parameters,...] <instructions> ENDM Macros Macros são expandidos diretamente em código. Assim, se existem labels dentro da definição da macro, poderá ocorrer um erro de "Duplicate declaration" quando a macro é usada duas vezes ou mais. Para evitar esse tipo de problema, use a diretiva LOCAL seguida do nome das variáveis, labels ou nomes de procedimentos. Macros vs. Procedimentos Quando você usa… Um procedimento, você deveria usar a instrução CALL. Ex: CALL MyProc Uma macro, você pode simplesmente digitar o nome da macro. Ex: MyMacro Para passar parâmetros… para um procedimento, use a pilha ou qualquer GPR. para uma macro, simplesmente digite-os depois do nome da macro. Ex: MyMacro 1, 2, 3 Para marcar o final de… uma macro, use a diretiva ENDM. um procedimento, use o nome do procedimento seguido da diretiva ENDP. Macros vs. Procedimentos Um procedimento é localizado num determinado endereço de memória, e se você usar o mesmo procedimento 100x, a CPU vai sempre transferir o controle para esse trecho de memória. O controle será retornado para o programa usando a instrução RET. A pilha é usada para manter o endereço de retorno. A instrução CALL ocupa 3 bytes. Assim, o tamanho do arquivo executável cresce quase insignificativamente, não importa quantas vezes o procedimento é usado. Em outras palavras, não há replicação de código! Já as macros são expandidas diretamente em código de programa. Assim, se você usar uma mesma macro 100x, o montador irá expandir a macro 100x, tornando o executável consideravelmente grande. Em outras palavras, o código é replicado a cada chamada da macro!