Você está na página 1de 2

ULA de 1 bit: realiza operações lógicas e aritméticas em dois bits de entrada, A e B.

É possível forçar A ou B para negar ENA e ENB, respectivamente. Além disso, é possível obter A invertido ativando INVA. A ULA de 1 bit pode
calcular qualquer uma das quatro funções - A and B, A or B, A xor B ou A + B, dependendo das linhas de entrada de seleção de função F0 e F1 conterem 00, 01, 10 ou 11 (binário). CLOCK: circuito que emite uma série de pulsos
com uma largura de pulso precisa e intervalos precisos entre pulsos consecutivos. Ele é usado em muitos circuitos digitais para prover sincronização e garantir que os eventos ocorram na ordem correta. Durante um ciclo de
clock, diversos eventos podem ocorrer e, se esses eventos devem ocorrer em ordem específica, o ciclo deve ser dividido em subciclos. As frequências de pulso geralmente variam entre 100 MHz e 4 GHz, correspondendo a
ciclos de clock de 10 nanossegundos a 250 picossegundos. LATCH SR: circuito de memória de 1 bit que possui duas entradas, S e R, para ativar (setting) e restaurar (resetting) o latch, respectivamente. Ele também possui duas
saídas, Q e Q̅. Quando S é 1 e R é 0, a saída Q é 1 e Q̅ é 0, e quando S é 0 e R é 1, a saída Q é 0 e Q̅ é 1. No entanto, quando S e R são ambos 1, ocorre uma instabilidade no circuito, que pode ser resolvida com a utilização de um
latch SR com clock ou um latch D com clock. O papel do clock no latch SR com clock é controlar o momento em que o valor de entrada é lido e armazenado no latch. Quando o clock é acionado, o valor corrente de D é lido e
armazenado no latch, evitando assim a instabilidade que ocorre quando S = R = 1 no latch SR convencional.O Latch D com clock é um tipo de circuito de memória de 1 bit que armazena um único bit de informação. O circuito é
disparado pelo clock, que é um sinal que controla quando os dados são lidos e escritos no latch. Quando o clock é 1, o valor atual de D é lido e armazenado no latch. Quando o clock é 0, o valor armazenado no latch é mantido.
Isso permite que o circuito armazene um valor de dados até que seja atualizado pelo próximo sinal de clock. RAMs e ROMs: as RAMs são memórias voláteis que armazenam temporariamente dados e programas em uso pelo
processador. Existem duas variedades de RAM: estáticas, que utilizam circuitos semelhantes aos flip-flops D básicos, e dinâmicas, que consistem em células com transistores e capacitores. Por outro lado, as ROMs são memórias
não voláteis que mantêm permanentemente dados e programas que não precisam ser alterados. Elas são utilizadas em dispositivos como brinquedos, eletrodomésticos e carros, onde a preservação de programas e dados é
crucial mesmo durante a falta de energia. As ROMs não podem ser modificadas ou apagadas intencionalmente ou acidentalmente após a instalação. Flip-Flops: circuitos digitais que armazenam um bit de informação. Na
variante denominada flip-flop, a transição de estado não ocorre quando o clock é 1, mas durante a transição de 0 para 1 (borda ascendente), ou de 1 para 0 (borda descendente). REGISTRADORES: existe um tipo de flip-flop do
tipo D dual que é utilizado em registradores. Oito flip-flops podem ser ligados para formar um registrador armazenador de 8 bits. São componentes importantes em circuitos lógicos que armazenam informações em forma de
bits.

PINAGEM: os pinos de endereço são usados para identificar a localização de memória ou de dispositivos de entrada/saída que o processador precisa acessar. Já os pinos de dados são usados para transmitir informações entre o
processador e a memória ou dispositivos de entrada/saída. Por fim, os pinos de controle regulam o fluxo e a temporização dos dados que entram e saem do processador, e podem ser divididos em várias categorias, como
controle do barramento, interrupções, arbitragem do barramento, sinalização para o coprocessador, status e outros. BARRAMENTOS: são caminhos pelos quais os dispositivos se comunicam, enviando sinais digitais (dígito 0 ou
1) frequentemente agrupados em 8, 16, 32 ou 64 linhas. Cada barramento tem uma banda passante (BW) expressa em capacidade de transações (bytes/seg). Alguns dos principais aspectos de projetos de barramento que
afetam a BW e o custo de um barramento incluem a largura do barramento, a metodologia de temporização, a arbitragem de barramento e as operações que podem ser realizadas sobre o barramento. BARRAMENTO DE
ENDEREÇOS: responsável por identificar a fonte ou o destino dos dados em um sistema de computador. Por exemplo, quando a CPU precisa ler uma instrução ou dados de uma determinada localização na memória, o
barramento de endereços é utilizado para identificar o endereço de memória correspondente. A largura do barramento de endereços determina a capacidade máxima de memória do sistema, ou seja, quanto maior o número
de linhas de endereço no barramento, mais memória poderá ser diretamente endereçada pelo processador [Exemplo: 8080 tem barramento de endereço de 16 bit dado 64k endereços (2^16/1024=64)]. BARRAMENTO DE
CONTROLE: responsável por controlar o fluxo de informações entre os dispositivos conectados a ele. Ele pode ser usado para enviar sinais de controle, como sinais de interrupção, sinais de reset e sinais de sincronização. Além
disso, pode ser usado para transferir informações de controle entre a CPU e outros dispositivos, como memória e dispositivos de entrada/saída. MESTRE E ESCRAVO: o mestre é o dispositivo ativo que comanda a transferência
de dados sobre o barramento, enquanto o escravo é o dispositivo passivo que aguarda solicitações de serviços. TEMPORIZAÇÃO DO BARRAMENTO: o barramento síncrono é controlado por um sinal de clock, que sincroniza as
operações de leitura e escrita de todos os dispositivos conectados a ele. Já o barramento assíncrono não é controlado por um sinal de clock, o que significa que a velocidade de um par mestre-escravo não afeta a velocidade de
outros pares que podem ser mais rápidos ou mais lentos que o outro par. Isso pode trazer vantagens de desempenho em relação ao barramento síncrono, mas em geral, um sistema assíncrono é mais complicado e mais custoso
de se construir do que um sistema síncrono. Barramento Síncrono: mais simples de se trabalhar, mas tem problemas de desempenho se os dispositivos tiverem velocidades heterogêneas. Barramento Assíncrono: vantagens de
desempenho em relação ao síncrono, mas é mais complicado e custoso de se construir. ARBITRAGEM DO BARRAMENTO: processo de determinar qual dispositivo conectado a um barramento terá acesso ao mesmo em um
determinado momento. ABORDAGEM CENTRALIZADA: consiste em um único árbitro que determina quem será o próximo mestre do barramento. Esse árbitro é capaz de distinguir entre ausência e presença de requisição de
uso do barramento (bus request). O árbitro pode ser o processador ou um chip separado. Quando o árbitro enxerga a requisição do barramento, ele envia um sinal de garantia de uso do barramento (bus grant) por meio de
uma linha dedicada. DAISY CHAINING: esquema de arbitragem do barramento que estabelece implicitamente uma prioridade para uso do barramento. Quanto mais perto fisicamente do árbitro estiver um dispositivo, mais
prioridade ele terá para usar o barramento. ABORDAGEM DESCENTRALIZADA: Mecanismo 1: há várias linhas de requisição de barramento, cada uma com uma prioridade diferente. Quando um dispositivo precisa do
barramento, ele ativa uma das linhas. Todos os dispositivos monitoram todas as linhas e, ao final do ciclo de requisição, cada dispositivo sabe se foi ou não ele que requisitou a linha de maior prioridade. Apresenta muitas linhas
de requisição de barramento, mas não possui o custo de se ter um árbitro. Mecanismo 2: há três linhas: Bus Request, Busy (ativada pelo mestre atual do barramento) e a linha de arbitragem (arbitration line). A linha de
arbitragem é conectada a todos os dispositivos no modo daisy chaining e permanece ativa enquanto nenhum dispositivo precisar do barramento. Quando um dispositivo precisa do barramento, ele ativa a linha Bus Request e
espera até que a linha Busy seja desativada pelo mestre atual do barramento. Em seguida, o dispositivo ativa a linha de arbitragem e espera até que ela seja desativada pelo mestre atual do barramento. O dispositivo que
desativar a linha de arbitragem primeiro se torna o próximo mestre do barramento. CANAIS DE COMUNICAÇÃO: utilizados para transferir dados de maneira serial, ou seja, um bit de cada vez. Existem três tipos de canais de
comunicação: simplex, half-duplex e full-duplex. O simplex permite a transmissão de dados em uma única direção, enquanto o half-duplex permite a comunicação em ambas as direções, mas não simultaneamente. Já o
full-duplex permite a comunicação em ambas as direções ao mesmo tempo.

MICROPROGRAMA: interpretador que busca, decodifica e executa instruções de máquina do nível ISA. É composto por um conjunto de microinstruções armazenadas em uma memória ROM do processador, chamada control
store ou memória de controle. Cada instrução de máquina é interpretada e pode dar origem à execução de muitas microinstruções. O microprograma tem um conjunto de variáveis que representam o estado do computador,
onde cada função (que corresponde a uma instrução ISA) muda no mínimo uma das variáveis que formam o estado. Na prática, essas variáveis correspondem aos registradores do sistema, e o contador de programa (Program
Counter - PC) é parte do estado. Uma Microarquitetura é dividida em Parte Operativa (Caminho de Dados) e Parte de Controle (Parte de Controle). A Parte Operativa é composta por todos os componentes responsáveis pela
execução de operações elementares sobre os dados, enquanto a Parte de Controle é composta por circuitos sequenciais e/ou memória de microprogramas que geram o controle ciclo a ciclo da parte operacional. A Parte de
Controle envolve microprogramação, que inclui memória para armazenar o microprograma, o código do microprograma, sequenciamento de microinstruções e um registrador de controle contendo a microinstrução atual a ser
executada. Os bits do registrador de controle alimentam os sinais de controle que operam o caminho de dados. REGISTRADORES: MAR: Memory Address Register. MDR: Memory Data Register. PC: Program Counter. MBR:
Memory Buffer Register. SP: Stack pointer (aponta para o topo da pilha). LV: Local Variables (Quadro de variáveis Locais). CPP: Constants Pool Pointer. TOS: Top Of Stack (Guarda o conteúdo de memória apontado por SP). OPC:
OPeration Code (Registrador temporário em algumas instruções). H (holder). OPERAÇÃO DA MEMÓRIA: uma microarquitetura executa instruções que são armazenadas na memória e precisa saber qual instrução executar em
seguida. Isso requer um registrador de contador de programa (PC) para acompanhar a próxima instrução a ser executada. A transferência de dados entre a CPU e a memória é feita usando dois registradores especiais: o
Registrador de Endereço de Memória (MAR) e o Registrador de Dados de Memória (MDR). O MAR armazena o endereço de memória onde uma palavra será lida ou gravada, enquanto o MDR armazena os dados reais a serem
transferidos. RESUMO: O caminho de dados é o coração de um processador. Nele estão alguns registradores, dois barramentos e uma ou mais unidades funcionais (ULAs e deslocadores). O principal loop de execução é
composto pela busca de alguns operandos dos registradores e pelo envio desses operandos para a ULA, com o intuito de executar uma operação sobre eles. Os resultados dessa operação são armazenados de volta nos
registradores. O sequenciador exerce o controle sobre o caminho de dados, buscando as microinstruções em uma memória de controle. Cada microinstrução tem um conjunto de bits que controla o caminho de dados durante
um ciclo. Esses bits especificam os operandos a serem selecionados, as operações a serem executadas e o que fazer com os resultados dessas operações. Além disso, cada microinstrução especifica a sua sucessora potencial
(em geral em um campo da própria microinstrução).
IJVM: O modelo de memória IJVM é composto por três áreas principais: o Pool de Constantes, o Quadro de Variáveis Locais e a Área do Procedimento. O Pool de Constantes contém constantes, strings e ponteiros para
endereços de memória, e não pode ser escrito pelos programas IJVM. O registrador CPP (Constant Pool Pointer) aponta para a primeira palavra do pool de constantes. O Quadro de Variáveis Locais é onde são armazenados os
valores dos parâmetros (argumentos) do procedimento chamado. O registrador LV contém o endereço da primeira posição do quadro de variáveis locais. A Área do Procedimento é a região de memória que armazena o
programa. O registrador PC (Program Counter) aponta para o endereço da instrução que deve ser buscada em seguida. Além disso, o modelo de memória IJVM também inclui a Pilha de Operandos, que fica imediatamente
acima do quadro de variáveis locais e é parte das variáveis locais. O registrador SP armazena o endereço do topo da pilha e muda de valor durante a execução do procedimento.

MODOS DE EXECUÇÃO: o Modo Kernel é usado para executar o sistema operacional e permite que qualquer instrução da máquina seja executada nele. Já o Modo Usuário é usado para executar programas de aplicação e não
permite que certas instruções mais sensíveis executem nele. Instruções de manipulação de cache não podem ser executadas no modo usuário. COMPATIBILIDADE: é uma grande preocupação na definição do nível ISA. Novas
máquinas devem ser compatíveis com as anteriores, suportando os mesmos sistemas operacionais e programas de aplicação. Isso é importante para garantir que os programas escritos para uma determinada arquitetura
possam ser executados em outras máquinas com a mesma arquitetura, sem a necessidade de modificação ou recompilação do código-fonte. A compatibilidade também permite que as empresas continuem a usar o mesmo
software em novas máquinas, economizando tempo e dinheiro em desenvolvimento e treinamento. GERANDO CÒDIGO: o projetista de compiladores utiliza as informações do nível ISA para gerar código, pois as instruções do
nível ISA são aquelas para as quais o compilador deve gerar código. O nível ISA define quais instruções estão disponíveis e o que cada uma executa, além de especificar o modelo de memória da máquina, o conjunto de
registradores e os tipos de dados utilizados. O compilador usa essas informações para gerar código de máquina que possa ser executado pela CPU. O conhecimento do conjunto de instruções disponíveis também permite que o
compilador otimize o código gerado para melhorar o desempenho e a eficiência do programa. ISA no MIPS: é uma arquitetura RISC, possui um modelo de memória simples, com acesso apenas por palavras de 32 bits, possui 32
registradores de propósito geral de 32 bits cada, suporta instruções de carregamento e armazenamento de dados, operações aritméticas e lógicas, desvios condicionais e incondicionais, e chamadas e retornos de sub-rotinas,
usa o conceito de pipeline para melhorar o desempenho, dividindo a execução de cada instrução em várias etapas que podem ser executadas em paralelo e possui dois modos de execução. ENDEREÇAMENTO: é o processo de
especificar a localização de um dado na memória de um computador. O endereço é um número que identifica unicamente a posição de um dado na memória. Endereçamento imediato: o endereço do dado é especificado
diretamente na instrução de máquina. Endereçamento direto: o endereço do dado é especificado como um deslocamento a partir do início de uma região de memória. Endereçamento de registrador: o endereço do dado é
especificado em um registrador da CPU. Endereçamento indireto de registrador: o endereço do dado é especificado em um registrador, mas o valor contido nesse registrador é o endereço real do dado. Endereçamento
indexado: o endereço do dado é especificado como um deslocamento a partir do valor contido em um registrador. O modo de endereçamento utilizado em uma instrução de máquina depende do tipo de dado que está sendo
acessado e da arquitetura do processador. O conhecimento dos diferentes modos de endereçamento é importante para o desenvolvimento de compiladores e para a otimização de código de máquina. NOTAÇÃO POLONESA
INVERTIDA: é uma forma de escrever expressões matemáticas sem a necessidade de parênteses para indicar a ordem de avaliação das operações. Na NPI, os operadores aparecem após os operandos, em vez de entre eles,
como na notação infixa convencional. Por exemplo, a expressão infixa "3 + 4" seria escrita em NPI como "3 4 +". A ordem dos operadores na NPI é determinada pela ordem em que as operações devem ser executadas. Por
exemplo, a expressão "3 + 4 * 5" seria escrita em NPI como "3 4 5 * +", indicando que a multiplicação deve ser realizada antes da adição. A avaliação de uma expressão em NPI é feita usando uma pilha. Cada operando é
empilhado na pilha, e quando um operador é encontrado, os operandos necessários são desempilhados, a operação é realizada e o resultado é empilhado novamente. Esse processo continua até que a expressão seja
completamente avaliada. A NPI é usada em algumas calculadoras e linguagens de programação, pois permite uma avaliação mais simples e eficiente de expressões matemáticas.
PROCESSOS: o modelo de processos é uma forma de organizar a execução de programas em um sistema operacional. Um processo é uma instância de um programa em execução, que possui seu próprio espaço de memória,
registradores, pilha e outras estruturas de dados. O modelo de processos permite que vários programas sejam executados simultaneamente em um sistema operacional, compartilhando os recursos do sistema, como a CPU, a
memória e os dispositivos de entrada e saída. O sistema operacional é responsável por gerenciar os processos, escalonando a execução dos programas e garantindo que cada processo tenha acesso aos recursos necessários.
Cada processo é identificado por um número único, chamado de identificador de processo (PID). O PID é usado pelo sistema operacional para gerenciar o processo, permitindo que ele seja interrompido, suspenso ou terminado
quando necessário. O modelo de processos também inclui mecanismos de comunicação entre processos, como pipes, sockets e sinais, que permitem que os processos troquem informações e coordenem suas atividades.
MEMÓRIA VIRTUAL: é uma técnica utilizada pelos sistemas operacionais para permitir que programas possam acessar mais memória do que a disponível fisicamente na máquina. Isso é possível através da utilização de um
espaço de endereçamento virtual, que é mapeado para a memória física disponível no sistema. A paginação é uma técnica utilizada para implementar a memória virtual. Ela consiste em dividir a memória física em blocos de
tamanho fixo, chamados de páginas, e dividir o espaço de endereçamento virtual dos programas em blocos de tamanho igual, chamados de páginas virtuais. Cada página virtual é mapeada para uma página física, permitindo
que o programa acesse a memória física de forma transparente. A tabela de páginas é utilizada para realizar o mapeamento entre os endereços virtuais e físicos. Ela contém uma entrada para cada página virtual, que indica o
endereço físico correspondente. Quando um programa tenta acessar uma página virtual que não está presente na memória física, ocorre um erro de página e o sistema operacional é responsável por carregar a página
necessária da memória secundária para a memória física. A paginação permite que os programas acessem mais memória do que a disponível fisicamente na máquina, além de permitir que a memória física seja compartilhada
entre vários programas. No entanto, ela também pode levar a um desempenho inferior, devido ao tempo necessário para carregar as páginas da memória secundária para a memória física. LRU: é um algoritmo de substituição
de páginas utilizado em sistemas operacionais para gerenciar a memória virtual. Ele consiste em substituir a página que foi utilizada menos recentemente, ou seja, a página que não foi acessada por mais tempo. O objetivo do
algoritmo LRU é minimizar o número de faltas de página, que ocorrem quando um programa tenta acessar uma página que não está presente na memória física. Quando isso acontece, o sistema operacional precisa carregar a
página necessária da memória secundária para a memória física, o que pode levar a um atraso na execução do programa. O algoritmo LRU é considerado eficiente em sistemas em que a memória principal é menor do que o
conjunto de trabalho, ou seja, o conjunto de páginas que um programa utiliza durante sua execução. No entanto, em situações específicas, o algoritmo LRU pode falhar desastrosamente, como quando há um acesso repetido
em laço a uma sequência de páginas virtuais. Quando o conjunto de trabalho é maior do que o número de molduras disponíveis na memória física, ocorre uma situação chamada de trashing, em que o sistema operacional gasta
a maior parte do tempo trocando páginas entre a memória física e a memória secundária, em vez de executar o programa. FIFO: é um algoritmo de substituição de páginas utilizado em sistemas operacionais para gerenciar a
memória virtual. Ele consiste em substituir a página que foi carregada menos recentemente, ou seja, a primeira página a entrar é a primeira a sair. A substituição independe da última referência feita à página. Cada moldura de
páginas tem um contador associado, inicialmente zerado. A cada falta de página, os contadores são incrementados. O contador associado a uma moldura na qual foi carregada uma nova página é zerado. Quando a memória
enche (todos os bits de presença/ausência iguais a 1), ao ocorrer uma falta, a página com maior contador é expurgada da sua moldura atual. O algoritmo FIFO é considerado simples e fácil de implementar, mas pode não ser
eficiente em sistemas em que o conjunto de trabalho é maior do que o número de molduras disponíveis na memória física. Isso ocorre porque o algoritmo não leva em consideração a frequência de uso das páginas, o que pode
levar à expulsão de páginas frequentemente utilizadas. Em geral, o algoritmo FIFO é utilizado em sistemas com pouca memória física disponível, em que a substituição de páginas é necessária com frequência. Em sistemas com
mais memória física disponível, outros algoritmos de substituição de páginas, como o LRU, podem ser mais eficientes. FRAGMENTAÇÃO E SEGMENTAÇÃO: A fragmentação é um problema que pode ocorrer em sistemas de
gerenciamento de memória, em que a memória disponível é dividida em blocos de tamanho fixo para alocar processos ou dados. A fragmentação pode ser interna ou externa. A fragmentação interna ocorre quando um bloco
de memória é alocado para um processo ou dado, mas o tamanho do bloco é maior do que o necessário. Isso pode ocorrer quando os blocos de memória são de tamanho fixo e o processo ou dado a ser alocado não ocupa
todo o bloco. A fragmentação interna pode levar a um desperdício de memória. A fragmentação externa ocorre quando há blocos de memória livres, mas eles não são grandes o suficiente para alocar um processo ou dado. Isso
pode ocorrer quando há muitas alocações e desalocações de memória, o que pode levar a uma fragmentação do espaço livre. A fragmentação externa pode levar a uma falta de memória, mesmo que haja memória livre
disponível. A segmentação é uma técnica utilizada em sistemas de gerenciamento de memória para evitar a fragmentação interna. Ela consiste em dividir a memória disponível em segmentos de tamanho variável, que
correspondem a partes lógicas do programa ou dados. Cada segmento é alocado separadamente, o que permite que o tamanho do bloco de memória alocado seja igual ao tamanho do segmento. A tabela de segmentos é
utilizada para realizar o mapeamento entre os endereços lógicos do programa ou dados e os endereços físicos correspondentes. Cada entrada na tabela de segmentos contém o endereço base e o tamanho do segmento
correspondente. A segmentação pode levar a uma fragmentação externa, se houver muitas alocações e desalocações de segmentos de tamanho variável. No entanto, ela é considerada uma técnica eficiente para gerenciar a
memória em sistemas em que os programas ou dados têm tamanhos variáveis. COMO OS SISTEMA OPERACIONAL INTERPRETA AS INSTRUÇÕES ADICIONAIS DO NÍVEL DE SISTEMA OPERACIONAL: são interpretadas pelo
próprio sistema operacional, ou seja, pelo programa de nível 2 que interpreta o nível 3. Essas instruções são específicas do sistema operacional e não são interpretadas diretamente pelo hardware ou pelo microprograma. O
sistema operacional é responsável por gerenciar os recursos do sistema, como memória, processador e dispositivos de entrada e saída. Para isso, ele utiliza instruções adicionais que não estão presentes na linguagem de
máquina do hardware. Essas instruções são interpretadas pelo sistema operacional para realizar tarefas como alocação de memória, escalonamento de processos e gerenciamento de arquivos. O sistema operacional é
executado em modo privilegiado, o que significa que ele tem acesso a recursos que não estão disponíveis para os programas de usuário. Isso permite que o sistema operacional execute tarefas críticas para o funcionamento do
sistema, como gerenciamento de interrupções e acesso direto à memória. COMO A MULTIPROGRAMAÇÃO PODE SER ÚTIL EM SISTEMAS DE PROCESSAMENTO PARALELO E TEMPO COMPARTILHADO: em sistemas de
processamento paralelo, a multiprogramação permite que vários processos sejam executados simultaneamente em diferentes processadores. Isso pode aumentar significativamente o desempenho do sistema, já que vários
processos podem ser executados em paralelo, em vez de esperar que um processo termine para que outro comece. Em sistemas de tempo compartilhado, a multiprogramação permite que vários usuários compartilhem os
recursos do sistema, como processador, memória e dispositivos de entrada e saída. Cada usuário pode executar seu próprio processo, como se fosse o único usuário do sistema. O sistema operacional é responsável por
gerenciar a execução dos processos, alternando entre eles em intervalos de tempo muito curtos, geralmente na ordem de milissegundos. Isso dá a impressão de que vários processos estão sendo executados simultaneamente,
mesmo que apenas um processador esteja sendo usado. A multiprogramação é uma técnica eficiente para aproveitar ao máximo os recursos do sistema, permitindo que vários processos sejam executados simultaneamente. No
entanto, é importante que o sistema operacional seja capaz de gerenciar adequadamente a execução dos processos, evitando conflitos e garantindo que cada processo tenha acesso aos recursos necessários.

Você também pode gostar