Questão: Qual a relação entre a organização interna do processador e o conjunto de instruções?
Podemos classificar as instruções pela forma que elas endereçam os argumentos que serão utilizados em suas operações. Ou seja, o tipo de endereçamento utilizado.
De uma forma muito simplificada, podemos dizer que os argumentos podem ser:
Constantes embutidas na própria instrução: chamado de valor imediato;
Variáveis armazenadas em registradores ou na memória RAM:
Representação das instruções dentro do computador
Para entender melhor a maneira como as instruções funcionam, e são representadas, vamos primeiro entender o funcionamento do processador.
Para executar uma instrução, o processador deve fazer uma sequência de passos que se repetirá continuamente. Como visto anteriormente, essa sequência tem cinco etapas:
Buscar a instrução na memória (Fetch);
Decodificar a instrução (Decode);
Ler os operandos (Read);
Executar a instrução (Execute);
Escrever o resultado (Write-Back);
Voltar ao primeiro passo (Fetch).
Cada etapa possuí os seus pontos de controle, que são definidos durante o projeto do fluxo de dados do processador.
Essas alternativas de localização dos argumentos, na memória, em um banco de registradores ou no acumulador, são definidas pela topologia (ou arquitetura) do processador.
A topologia (ou arquitetura) do processador está vinculada com:
O tipo das instruções:
O formato e/ou comprimento da instrução:
Fixo: simplifica a implementação do processador ao custo de uma baixa densidade de código. Por exemplo, a instrução de incremento utilizará uma palavra inteira.
Variável: a implementação é mais complexa. A densidade de código pode ser ajustada para cada instrução – incremento pode ser feito com uma instrução de 8 bits.
Estudaremos as seguintes arquiteturas:
Baseada em Acumulador;
Baseada em Registradores e Memória;
Baseada em Registradores de Uso Geral;
Baseada em Pilha.
O resultado, de qualquer operação, sempre é armazenado no acumulador (AC ou A), ou seja, está implicito o uso desse registrador.
As instruções possuem apenas um endereço, que sempre será uma posição da memória ou valor imediato.
Exemplos de possíveis instruções, onde:
AC é o único registrador, ou seja, o acumulador;
Mem[y] é o conteúdo da posição de memória número “y”.
Soma o conteúdo do acumulador com o conteúdo do endereço de memória definido na instrução:
Funcionamento (execução):
Carrega conteúdo da memória para o acumulador:
Funcionamento (execução):
Armazena conteúdo do acumulador na memória:
Funcionamento (execução):
Como a instrução possui apenas um endereço de operando (da memória), a implementação (organização) do processador necessita somente de um barramento:
A organização do código da instrução pode ser feito utilizando um campo para a codificação da instrução e outro para o endereço / valor imediato (escolhendo o maior número de bits entre o tamanho desses dois).
opcode | Endereço/Imediato |
---|---|
X bits | Y bits |
MSB bit(X+Y-1) | LSB bit 0 |
MSB: Bit mais significativo (Most Significant Bit).
LSB: Bit menos significativo (Least Significant Bit).
Exemplo: Processador com 16 instruções e endereçamento de 1024 posições de memória.
Se tivermos um total de 16 instruções ou menos, precisaremos de 4 bits (16 = 2^4) para codificar as instruções.
Para endereçar todas as 1024 posições de memória, precisaremos de 10 bits (1024 = 2^10).
O formato das instruções terá 14 bits, divididos em 4 bits para o opcode da instrução e 10 bits para o endereço de memória utilizado.
opcode | Endereço/Imediato |
---|---|
4 bits | 10 bits |
MSB bit 13 | LSB bit 0 |
Complexidade Hardware | Acessos RAM | |
---|---|---|
Acumulador | Baixa | Muitos |
O processador possui uma quantidade “N” de registradores, onde N > 1.
As operações ocorrem entre um registrador e uma posição de memória ou um valor imediato.
O resultado é armazenado no mesmo registrador utilizado como um dos argumentos. Essa é a arquitetura do x86.
Os exemplos abaixo são de possíveis instruções, onde:
Rx é o registrador número “x”;
R[x] é o conteúdo do registrador número “x”;
Mem[y] é o conteúdo da posição de memória número “y”
Soma o conteúdo de um registrador com o conteúdo do endereço de memória definido na instrução:
Funcionamento (execução):
Carrega conteúdo da memória para um registrador:
Funcionamento (execução):
Armazena conteúdo de um registrador na memória:
Funcionamento (execução):
Questão:
Quantos barramentos seriam necessários para implementar essa arquitetura?
Como a instrução possui um endereço para o registrador e outro para o operando (da memória), a implementação (organização) do processador necessita de dois barramentos:
O barramento de endereços da RAM, constituído pelos bits 11 até 0 do imediato.
O barramento de endereços do banco de registradores, constituído pelos bits 13 e 12 da instrução.
Como visto anteriormente, precisamos de um campo para a codificação da instrução.
E, como temos dois argumentos, o registrador e a posição de memória (ou um valor imediato), precisamos de dois campos para definí-los.
opcode | Registrador | Endereço/Imediato |
---|---|---|
X bits | Y bits | Z bits |
MSB bit(X+Y+Z-1) | LSB bit 0 |
MSB: Bit mais significativo (Most Significant Bit).
LSB: Bit menos significativo (Least Significant Bit).
Exemplo:
Temos um processador com 32 instruções, 8 registradores e endereçamento de 2048 posições de memória.
Se tivermos um total de 32 instruções ou menos, precisaremos de 5 bits (32 = 2^5) para codificar as 32 instruções.
Para definir qual registrador utilizar, precisaremos de 3 bits (8 = 2^3).
Para endereçar todas as 2048 posições de memória, precisaremos de 11 bits (2048 = 2^11).
O formato das instruções terá 19 bits, divididos em:
5 bits para o opcode da instrução;
3 bits para o endereço do registrador;
11 bits para o endereço de memória utilizado (ou 8 bits para o valor imediato).
A codificação poderia ser:
opcode | Registrador | Endereço/Imediato |
---|---|---|
5 bits | 3 bits | 11 bits |
MSB bit 18 | LSB bit 0 |
Porém, nada impede que a codificação seja:
opcode | Endereço/Imediato | Registrador |
---|---|---|
5 bits | 11 bits | 3 bits |
MSB bit 18 | LSB bit 0 |
Ou mesmo:
Registrador | Endereço/Imediato | opcode |
---|---|---|
3 bits | 11 bits | 5 bits |
MSB bit 18 | LSB bit 0 |
Ou qualquer outra possível combinação.
Complexidade Hardware | Acessos RAM | |
---|---|---|
Registrador-Memória | Média | Médio |
Essa arquitetura é chamada de registrador-registrador ou load-store.
As operações só ocorrem entre registradores e os valores para esses registradores devem ser carregados da memória (ou imediato) através de uma instrução específica.
O resultado é armazenado em um registrador definido e pode ser guardado na memória usando uma instrução específica.
Exemplos:
Os exemplos abaixo são de possíveis instruções, onde:
Rx é o registrador número “x”;
R[x] é o conteúdo do registrador número “x”;
Mem[y] é o conteúdo da posição de memória número “y”
Soma o conteúdo de dois registradores e o resultado armazenado em um terceiro registrador:
Note que podemos usar para os três registradores o mesmo registrador: R1 = R1 + R1
Funcionamento (execução):
Carrega conteúdo da memória para um registrador:
Funcionamento (execução):
Armazena conteúdo de um registrador na memória:
Funcionamento (execução):
Temos, nessa arquitetura, dois tipos de instruções diferentes:
As instruções de acesso à memória (carga e armazenamento):
As instruções que executam uma operação lógica ou aritmética:
Como as instruções que executam operações utilizam três endereços (dos registradores), a implementação (organização) do processador necessita de três barramentos.
Precisamos de um campo para a codificação da instrução.
E, como temos dois ou três argumentos, precisaremos de dois formatos para as instruções.
Precisamos do opcode da instrução e três endereços para os registradores. Portanto, precisamos de quatro campos para definí-los.
opcode | Registrador A | Registrador B | Registrador C |
---|---|---|---|
X bits | Y bits | Y bits | Y bits |
MSB bit (X+3Y-1) | LSB bit 0 |
MSB: Bit mais significativo (Most Significant Bit).
LSB: Bit menos significativo (Least Significant Bit).
Exemplo:
Temos um processador com 64 instruções, 32 registradores e endereçamento de 4096 posições de memória.
Se tivermos um total de 64 instruções ou menos, precisaremos de 6 bits (64 = 2^6) para codificar as 64 instruções.
Para definir quais registradores utilizar, precisaremos de 5 bits (32 = 2^5) para cada registrador.
O formato das instruções terá, no mínimo, 21 bits, divididos em:
6 bits para o opcode da instrução;
5 bits para o endereço de cada registrador, totalizando 15 bits.
A codificação poderia ser:
opcode | Registrador A | Registrador B | Registrador C |
---|---|---|---|
6 bits | 5 bits | 5 bits | 5 bits |
MSB bit 20 | LSB bit 0 |
Para as instruções do tipo: A = B <operação> C.
Precisamos do opcode da instrução e um endereço para o registrador e outro para a posição de memória (ou imediato). Portanto, precisamos de três campos para definí-los.
opcode | Registrador A | Endereço/Imediato |
---|---|---|
X bits | Y bits | Z bits |
MSB bit (X+Y+Z-1) | LSB bit 0 |
Exemplo:
Para o mesmo processador do exemplo anterior:
64 instruções;
32 registradores;
Endereçamento de 4096 posições de memória.
Para as 64 instruções precisaremos de 6 bits.
Para definir o registrador utilizado, precisaremos de 5 bits.
Para o endereço da posição de memória, precisaremos de 13 bits (4096 = 2^13)
O formato das instruções terá, no mínimo, 24 bits, divididos em:
6 bits para o opcode da instrução;
5 bits para o endereço do registrador;
13 bits para o endereço de memória.
A codificação poderia ser:
opcode | Registrador A | Memória/Imediato |
---|---|---|
6 bits | 5 bits | 13 bits |
MSB bit 23 | LSB bit 0 |
Para as instruções do tipo:
A = Mem[x];
Mem[x] = A;
O formato final precisa contemplar os dois formatos definidos anteriormente, ou seja, precisamos utilizar o número de bits para a maior representação entre os dois formatos.
Utilizando os exemplos anteriores, teremos 24 bits para as instruções de acesso à memória:
opcode | Registrador A | Memória/Imediato |
---|---|---|
6 bits | 5 bits | 13 bits |
MSB bit 23 | LSB bit 0 |
Para as instruções lógicas e aritméticas, como tínhamos 21 bits, faremos a definição da quantidade de bits pelo teto dos dois formatos:
opcode | Registrador A | Registrador B | Registrador C | Reservado |
---|---|---|---|---|
6 bits | 5 bits | 5 bits | 5 bits | 3 bits |
MSB bit 23 | LSB bit 0 |
Onde o campo reservado pode conter 3 bits com valor ‘0’ para facilitar a montagem das instruções pelo assembler.
Código | Complexidade Hardware | Acessos RAM | Desempenho | |
---|---|---|---|---|
Acumulador | Potencialmente Mais Longo | Baixa | Muitos | Baixo |
Registrador-Memória | Médio | Média | Médio | Médio |
Registrador-Registrador | Potencialmente Mais Curto | Alta | Poucos | Alto |
Também conhecida como arquitetura com zero endereços. É a arquitetura utilizada no processador da disciplina “Elementos de Sistemas”
Como essa arquitetura foi estudada em “Elementos de Sistemas”, não nos aprofundaremos nela.
Os operandos (argumentos) estão armazenados na pilha, nas posições do ponteiro da pilha e na posição anterior.
A operação (instrução) retira os argumentos da pilha e acerta o ponteiro da pilha.
A operação é executada e o resultado é escrito no topo da pilha.
Exemplos:
Note que a instrução que executa a operação não define nenhum endereço para os argumentos.
Responder o quiz de participação, no blackboard, em:
Conteúdos > Participação > Aula_6_Quiz-P1