Periféricos e Interfaces had 2 A unidade central de processamento 2.1 Generalidades A unidade central de processamento ou Central Processing Unit, é o componente mais importante de um computador. Podem existir vários processadores num computador mas um será o central – a CPU. A CPU é um processador porque processa (calcula e move) dados. No caso geral, o processador lê os dados da memória, efectua alguma operação com estes, e escreve os resultados de novo na memória, possivelmente noutro endereço. Fig. 2-1: Estrutura geral de um microprocessador (in Messmer, 2002) Acima está representado o diagrama blocos genérico de um microprocessador. A unidade de execução (EU) é responsável pelo processamento dos dados e é composta por uma unidade de controlo (CU), uma unidade aritmética e lógica (ALU), e vários registos para operar os dados. Estes são posições de memória dentro do núcleo do CPU, cujo acesso é muito mais rápido que o acesso à memória principal e onde são executadas operações lógicas e aritméticas. A unidade de bus (BU) estabelece a comunicação com o system bus (bus de dados, endereços controlo), e deste modo com o exterior. A unidade de endereçamento (AU), calcula o endereço de memória a aceder pela unidade de bus. Este endereço é colocado no bus de endereços. A unidade de bus acede às posições de memória, através do bus de dados, e coloca-as no prefetch queue. A unidade de instrução (IU) lê a instrução do prefetch queue, descodifica-a e transfere-a para a unidade de execução, onde é executada. Para ser executada uma instrução poderão ser necessários operandos. Para os obter poderá ser necessário aceder a dados na memória e colocá-los nos registos da unidade de execução. Estes são acedidos também pela unidade de bus. Assim não existe distinção entre memória de instruções e de dados. Ambos podem estar guardados no mesmo conjunto de chips de memória, embora em endereços diferentes. 2.2 Evolução dos processadores Quanto mais rápido o processador, mais rápido pode efectuar cálculo e movimentação de dados, de modo que mais rápida será a execução de um programa. Existem várias meios de aumentar o desempenho de um processador: a) Aumentar a frequência de relógio Deste modo mais instruções podem ser executadas por unidade de tempo. No entanto aumentar a frequência implica uma maior dissipação de calor. http://w3.ualg.pt/~hdaniel/pin PIN 2005-6 T02 - 1/12 Periféricos e Interfaces had b) Aumentar a largura dos barramentos Barramentos com um maior número de linhas permitem comunicar um maior número de bits num ciclo. Um barramento de dados de 64 bits permite transferir o dobro dos dados que um barramento de 32 bits na mesma unidade de tempo. c) Optimização do desenho do processador Pretende-se que possa ser efectuado um máximo de processamento num ciclo. Para isso poderá ser necessário uma maior complexidade de desenho, o que implica mais transístores por unidade de área. A escala de integração actual permite a inclusão num só chip de mais que uma ALU e FPU. De facto alguns chips incluem várias unidades de execução. 2.2.1 A lei de Moore Em 1965, Gordon Moore, co-fundador da Intel, estimou que o número de transistores possíveis de serem incluídos no chip do processador dobraria em cada 18 meses, dobrando assim a velocidade. Moore esperava que esta regra se aplicasse até 1975, no entanto ainda hoje se mantém válida 2.3 A familia de microprocessadores INTEL x86 e compatíveis Na tabela seguinte têm-se uma breve descrição da evolução dos CPUs usados em PCs. As gerações referem-se a gerações de PCs. Esta classificação não é única. De qualquer forma primeira geração de PCs data de 1978. No entanto o protótipo do primeiro chip da Intel, o 4004, data 1971. A Intel desenvolveu também o 80186/88 como uma evolução do 8086/88 que não foram no entanto utilizados em PCs. Aliás não foi desenvolvido um coprocessador matemático para este processador sendo usado o 8087. Já para os processadores 80286 e 80386 foram desenvolvidos coprocessadores matemáticos o 80287 e o 80387. A partir do 80486 a unidade de virgula flutuante (Floating Point Unit) foi incluída no chip do processador. Geração de PC 1ª 2ª 3ª 4ª 5ª 5ª melhorada 6ª 6ª melhorada 7ª 8ª Processadores Ano Nº de transistores Intel 8088 e 8086 Intel 80286 Intel 80386 Intel 80486 Intel Pentium, Cyrix 6x86 e AMD K5 Intel Pentium MMX, IBM/Cyrix 6x86MX Intel Pentium Pro, AMD K6, Intel Pentium II, AMD K6-2 Intel Pentium III, AMD K6-3 Intel Pentium 4, AMD original Athlon, Athlon Thunderbird, Athlon XP Intel Itanium, AMD Athlon 64, Intel Petium 5, AMD Opteron 78-81 1984 87-88 90-92 93-95 29 K 134 K 275 K 1200 K 3100 K http://w3.ualg.pt/~hdaniel/pin 97 4500 K – 6000 K 95-98 5500 K – 9300 K 99 99-2001 9300 K 22000K – 42000k > 2002 PIN 2005-6 T02 - 2/12 Periféricos e Interfaces had Fig. 2-2: Intel 8086 e AMD Athlon 2.3.1 Arquitectura do 8086/8 O 8086 e o 8088 são dois processadores muito idênticos. Ambos tem uma arquitectura interna de 16 bits, isto é os registos da unidade de execução são de 16 bits. O prefetch queue é de 6 bytes no 8086 e de 5 no 8088. O bus de endereços é de 20 bits de modo que pode endereçar 220 = 1 MByte = 1024 KBytes = 1,048,576 bytes de memória. Processadores mais recentes que mantêm compatibilidade com o funcionamento do 8086 usam o chamado modo real. 2.3.1.1 Endereçamento de memória Endereçamento de memória é segmentado em blocos de 64 KBytes. Um segmento começa sempre num endereço de memória múltiplo de 16. Para se aceder a uma posição de memória dentro do segmento é utilizado um valor de offset. Este representa a distância em bytes que vai do endereço de base do segmento, isto é o início do segmento, a uma outra localização de memória dentro do limite de 64KBytes. Assim todas as posições de memória dentro de um segmento podem ser endereçados por 16 bits, de modo que o offset varia entre 0000H a FFFFH (0 a 65,355 em decimal). Nesta arquitectura segmentada, o endereço de memória lógico é composto por um par segmento:offset, ambos de 16 bits: 0000H-FFFFH : 0000H-FFFFH segmento offset O endereço físico, é obtido deslocando o valor do segmento 4 bits para a esquerda e adicionando o offset. Repare-se que o valor do segmento é assim multiplicado por 16, daí que o inicio do segmento coincida com um endereço físico múltiplo de 16. Exemplo: endereço lógico: 1234H:0234H + 12340H 0234H 12574H http://w3.ualg.pt/~hdaniel/pin (segmento deslocado 4 bits para a esquerda = x16) (endereço físico de 20 bits) PIN 2005-6 T02 - 3/12 Periféricos e Interfaces had 2.3.1.2 Registos do processador O 8086/88 tem 14 registos de 16 bits, como mostra a figura abaixo. Fig. 2-3: Registos do 8086/88 (in Tischer and Jennrich 1996) 2.3.1.2.1 Registos de uso geral Os registos AX, BX, CX e DX são usados para armazenamento de dados e servem de operandos para passagem de parâmetros para as funções da BIOS ou do sistema operativo. AX – também chamado de acumulador, normalmente acumula os resultados de um cálculo. É necessário quando se fazem multiplicações e divisões BX – também chamado base, pode ser usado para guardar um endereço base de um conjunto de dados contíguos para acesso indexado a posições de memória, como por exemplo um array. Pode também ser usado como operando. CX – também chamado de contador. Pode ser usado na implementação de ciclos e como operando. DX – também chamado dados, guarda dados de uso geral. Como mostra a figura acima, estes quatro registos podem ser acedidos como dois registos de 8 bits. A parte alta, isto é os 8 bits mais significativos identificados por *H e a parte baixa, os 8 bits menos significativos por *L. Assim em assembler segundo a sintaxe AT&T: mov mov mov $0, %ax $0, %ah $0, %al ; coloca um zero no registo de 16 bits ax ; coloca um zero no parte alta de ax ; coloca um zero no parte baixa de ax http://w3.ualg.pt/~hdaniel/pin PIN 2005-6 T02 - 4/12 Periféricos e Interfaces had Abaixo apresenta-se um exemplo de acesso indexado a um espaço de memória contíguo, por exemplo um array. Este segmento de código coloca zeros num conjunto de 10 posições de memória. São apresentadas duas versões de acordo com a sintaxe AT&T e a sintaxe INTEL: AT&T syntax INTEL syntax mov mov $10, %cx $address, %bx mov inc dec jnz $0, (%bx) %bx %cx loop loop: mov mov cx, 10 bx, address mov inc dec jnz 0, [bx] bx cx loop ; offset of array loop: Nota: Para se embeber código assembler no código fonte C, compilado com gcc, deve ser usada a sintaxe AT&T. 2.3.1.2.2 Registos de segmento e de offset Os registos CS, DS, SS e ES. Endereçam o inicio de um segmento de memória de 64 KBytes. Como já visto o endereço fisico é obtido multiplicado o valor nestes endereços por 16. CS – também chamado de segmento de código. Em conjunto com o registo de offset IP ou instruction pointer, indica o endereço da próxima instrução a ser executada: CS:IP = CS*16+IP DS – também chamado de segmento de dados. Associado ao registo de offset SI ou source index é usado para acesso dados. DS:SI SS – também chamado de segmento do stack ou da pilha. Associado ao registo de offset SP ou stack pointer, indica o topo do stack. DS:0000H DS:SP base do stack topo do stack ES – também chamado de segmento extra. Permite acesso a posições de memória num segmento normalmente de dados, quando associado ao registo de offset DI ou destination index: ES:SI É assim comum organizar um programa em 3 segmentos de dados. Uma para o código, outro para os dados e outro para a pilha. No entanto deste modo só se acede um máximo de 3*64KBytes de memória. Pode-se ainda usar o segmento extra de modo a aceder a 4*64KBytes de memória, isto é 256 KBytes de memória de um total de 1024 KBytes endereçáveis. http://w3.ualg.pt/~hdaniel/pin PIN 2005-6 T02 - 5/12 Periféricos e Interfaces had Para aceder à restante memória pode-se manipular por exemplo o segmento de dados. Supondo que é necessário guardar dados na memória numa quantidade superior à capacidade de um segmento, por exemplo 32+64 KBytes, tem de se usar dois segmentos, por exemplo: FFFFFH Segmento da pilha Memória disponível 38000H 30000H Segmento de dados B (32 Kbytes) Memória disponível 1FFFFH Segmento de dados A (64 KBytes) 10000H Segmento de código 00000H Se DS = 1000H para aceder ao segmento de dados A, então deverá ter o valor DS = 3000H para que se possa aceder aos dados no segmento B. (Repare-se que os endereços físicos são obtidos multiplicado o conteudo do registo de segmento por 16, isto é 10H.) No entanto o conjunto de instruções do 8086 não permite que manipulação directa dos registos de segmentos, tal como: mov $3000H, %ds ; erro É no entanto possível colocar o valor dos registos na pilha e recuperá-los. Tal é efectuado pelo scheduler de um sistema operativo multi-tarefa quando troca o processo que vai usar o CPU. deste modo é possível alterar DS para apontar o segmento de dados B do seguinte modo: mov push pop $3000H, %ax %ax %ds 2.3.1.2.3 Registo de flag Consiste numa colecção de bits (flags) de estado e controlo do sistema: 6 flags de estado e 3 de controlo. 7 bits não são usados. Algumas flags de uso comum são a carry flag (CF) e a zero flag (ZF). A principal uso da primeira é assinalar quando o resultado de uma operação excedeu a gama de valores dos dados. A segunda quando o resultado de uma operação foi zero. 2.3.1.3 Armazenamento de dados na memória A contrário dos registos, os valores de 16 bits, também chamados words, são guardados na memória segundo segundo uma organização chamada little endian, onde o byte menos significativo é colocado na posição de memória mais baixa. A mesma organização é usada para valores de 32 bits, as double words. Oposto a esta têm-se a organização big endian onde o armazenamento é efectuado ao contrário. http://w3.ualg.pt/~hdaniel/pin PIN 2005-6 T02 - 6/12 Periféricos e Interfaces had Assim o número A02BH será guardado na memória como: Endereço de memória valor 00F05H A0H 00F04H 2BH 00F03H ?? 00000H ?? A02BH Embora os compiladores e interpretadores tornem a organização de memória transparente para o programador, quando se programa em assembler é preciso tomar tal em atenção. 2.3.2 Evolução do 8086 Os processadores apresentados a seguir são evoluções do 8086. Cada novo processador acrescenta inovações tecnológicas em relação ao seu predecessor, mantendo a compatibilidade com todos os anteriores. A seguir apresenta-se um resumo das principais inovações relativamente ao modelo anterior: 2.3.2.1 80186/88 O 80186 e 80188 diferem no mesmo que o 8086 para o 8088: o 80186 tem um bus de dados de 16 bits e o 80188 tem um bus de dados de 8 bits. No chip deste processador foi no entanto adicionado, em relação ao 8086/88: - um controlador de interrupções - um controlador DMA - um timer. O conjunto de instruções é maior e foi optimizado para melhorar o desempenho. 2.3.2.2 80286 O bus de endereços é de 24 bits o que permite endereçar 16 MBytes de memória (224 bytes). Foi o primeiro processador da Intel a funcionar em modo protegido, isto é o acesso à memória pode ser protegido como será descrito mais adiante. Esta característica é bastante utilizada nos sistemas operativos actuais para impedir que programas em modo de utilizador possam aceder à memória do kernel (ou núcleo do sistema operativo) garantindo assim a integridade do sistema. Para operar em modo protegido tem mais 5 registos. Em modo real, funciona como o 8086, acedendo apenas a 1 MByte de memória. 2.3.2.3 80386 O 80386 foi o primeiro microprocessador de 32 bits a ser usado nos PC’s em finais dos anos 80 do século passado. As principais inovações são: http://w3.ualg.pt/~hdaniel/pin PIN 2005-6 T02 - 7/12 Periféricos e Interfaces had - Registos de 32 bits - Bus de dados de 32 bits - Bus de endereços de 32 bits, o que permite endereçar 4 GBytes de memória (232 bytes). - Prefetch queue de 16 bytes. - Unidade de gestão de memória com suporte para segmentação e paginação. - Tem mais 4 registos de controlo para o modo protegido e 8 registos de debug no modo protegido e modo virtual 8086. - Arquitectura em pipeline As diferentes unidades do 386 podem, de certa forma operar em paralelo, uma vez que as instruções são passadas por uma espécie de linha de montagem e tratadas por partes. Assim durante a execução de uma instrução, a próxima instrução a ser executada é descodificada e a instrução seguinte é colocada no prefetch queue. Consegue-se assim um paralelismo que optimiza o desempenho. - Modo virtual 8086 O modo virtual 8086, permite emular múltiplas máquinas virtuais 8086 com 1 MByte de memória cada, sendo os endereços físicos de 1 MByte mapeados para qualquer zona dos 4 GBytes. Assim um sistema operativo multitarefa pode executar vários programas feitos para o 8086, cada um com o seu 1 MBytes independente. O modo virtual 8086 surgiu porque na altura do aparecimento do 80386, ainda havia muitos programas a correr sobre o MS-DOS, que é um sistema operativo que necessita de se executar em modo real. O modo virtual 8086 é usado, por exemplo, por uma janela de MSDOS a correr sobre o Windows, de modo que múltiplas janelas MSDOS emulam múltiplos sistemas 8086 concorrentes. No linux é usado no emulador de DOS: DOSEMU. - Modo protegido Foi originalmente implementado no 80286 para proteger de acessos inválidos e incorrectos as diferentes tarefas num sistema operativo multitarefa (OS/2, Linux, Windows NT, Windows 2000). Para conseguir isso, o hardware do processador verifica todos os acessos aos dados e ao código feitos por um programa e utiliza 4 níveis de privilégios para fornecer direitos de acesso. De um modo simplificado, o cálculo do endereço de memória físico a partir do endereço lógico, no modo protegido, segue o diagrama seguinte: Fig. 2-4: Cálculo do endereço físico no modo protegido (segmentos) http://w3.ualg.pt/~hdaniel/pin PIN 2005-6 T02 - 8/12 Periféricos e Interfaces had O endereço lógico é formado por um selector guardado num registo de segmento, DS para o segmento de dados, e um offset. O selector indica o descriptor de segmento na tabela de descriptores. Esta normalmente reside na memória baixa e pode ser inicializada pelo sistema operativo no boot. No descriptor seleccionado existe informação sobre o endereço de base do segmento, bem como a protecção deste. O offset é então somado ao endereço de base para se obter o endereço físico. O 80386 permite ainda indexar a memória através de páginas. Neste caso o endereço lógico é transformado num endereço linear, composto por 3 campos: DIR PÁGINA OFFSET Directório de páginas Tabela de páginas Página de memória entrada entrada endereço fisíco Fig. 2-5: Cálculo do endereço físico no modo protegido (páginas) O campo DIR indica uma entrada no directório de páginas. Essa entrada indica uma tabela de páginas. Usando o campo Página acede-se a uma outra entrada, agora na tabela de página, que indica a posição da página na memória física. Somando o OFFSET ao endereço base da página têm-se o endereço físico. De um modo geral, os registos de 32 bits mantém o nome dos anteriores precedidos por um e de extended. Assim para colocar valores de 32 bits no acumulador pode-se usar a seguinte sintaxe: mov $F000A000H, %eax O programa seguinte exemplifica uma chamada ao sistema operativo Linux para imprimir uma string na consola, em código assembler de 32, embebido em código ANSI C. Neste simples exemplo, as variáveis partilhadas pelo código C e assembler são globais. Se não fôr esse o caso ter-se-á de usar outra técnica para partilhar variáveis entre o código C e assembler: /* Global variables*/ char msg[]="Hello, world!\n"; int len=15; int main() { asm ( http://w3.ualg.pt/~hdaniel/pin PIN 2005-6 T02 - 9/12 Periféricos e Interfaces had "movl "movl "movl "movl "int ); return 0; } len, %edx $msg, %ecx $1, %ebx $4, %eax $0x80 #message length\n" #pointer to message to write\n" #file handle (stdout)\n" #system call number (write)\n" #call kernel\n" 2.3.2.4 80486 O 80486 consiste num processador 386 melhorado, tendo sido o primeiro processador da Intel a incluir um coprocessador matemático no próprio chip. Os processadores anteriores podiam utilizar um coprocessador matemático, que consistia noutro chip colocado num slot especifico da motherboard. CPU coprocessador 8086/88 8087 80186/88 8087 80286 80287 80386 80387 Incluí ainda memória cache de 8 KBytes, para código e dados, no chip. 2.3.2.5 Pentium É um processador de 32 bits, superescalar, o que significa que pode executar mais de uma instrução por ciclo de relógio. Para isso contém: - Dois pipelines de inteiros e um pipeline floating-point, que em determinadas circunstâncias conseguem executar duas instruções no mesmo ciclo de relógio. - Duas caches separadas (uma para código e outra para dados) com 8 KBytes cada uma. - Bus de dados externo de 64 bits. 2.3.2.6 Pentium Pro - Cache adicional para código montada na motherboard (L2), e ligada directamente ao CPU, com capacidade de 256 ou 512 KBytes. - Bus de endereços de 36 bits, para um espaço físico de endereçamento de 64 GBytes. - Permite multiprocessamento com 2 ou 4 processadores Pentium Pro, sem lógica adicional. 2.3.2.7 Pentium II Basicamente consiste num Pentium PRO com suporte para a tecnologia MMX já existente no Pentium MMX. MMX significa multimedia extensions, e consiste num conjunto de instruções dedicado para implementação de aplicações multimedia e 3D. A principal característica deste tipo de aplicações é que operam sobre uma grande de pequenos pacotes de dados, por exemplo a manipulação de bits numa imagem 3D. A arquitectura MMX permite recolher uma série de pacotes de dados e processar uma mesma instrução em todos esses dados ao mesmo tempo (SIMD – single instruction multiple data). http://w3.ualg.pt/~hdaniel/pin PIN 2005-6 T02 - 10/12 Periféricos e Interfaces had 2.3.2.8 Pentium III Consiste num desenvolvimento do Pentium II com um maiot conjunto de instruções, que incluem uma versão estendida das instruções MMX presentes no Pentium II. Foi também optimizado desempenho da FPU. Os registos passam a ter u comprimento de 128 bits. Dispõe também de um pipeline com 10 estágios 2.3.2.9 AMD Athlon (K7) Normalmente é mais rápido que um Pentium III para a mesma frequência de relógio. Dispõe de 3 pipelines de inteiros independentes. O Cache no chip do processador tem uma capacidade de 128 KBytes 2.3.2.10 Pentium IV Este processador é baseado na tecnologia Hyper-Threading, onde thread refere-se a uma série de instruções. Dispõe de um pipeline com 20 estágios. Em alguns casos esta tecnologia permite processar duas threads em simultâneo, de modo que o processador actua como dois processadores virtuais. Deste modo num sistema operativo multitarefa é possível executar dois processos em simultâneo. O desenvolvimento seguinte consiste num chip com dois núcleos de modo que cada um pode actuar como dois processadores virtuais sendo possível processar 4 threads em simultâneo. Exemplo de processadores dual core são o AMD Opteron e o Intel Pentium ”Smithfield”. Fig. 2-6: Processador dual core com Hyper Threading http://w3.ualg.pt/~hdaniel/pin PIN 2005-6 T02 - 11/12 Periféricos e Interfaces had 2.4 Bibliografia Costa, Ana Paula e José Bastos (2004, 2005) “Resumos das aulas teóricas de Periféricos e Interfaces 2004-2005 “, http://www.deei.fct.ualg.pt/PIn_2005/Anuncios/ Karbo, Michael (2005). “PC Architecture”, http://www.karbosguide.com Messmer, Hans-Peter (2002). “The Indispensable PC Hardware Book 4th edition”, AddisonWesley Tischer, Michael e Bruno Jennrich, (1996). “PC Intern - The Encyclopedia of System Programming 6th edition”, Abacus http://w3.ualg.pt/~hdaniel/pin PIN 2005-6 T02 - 12/12