3.5. Exemplo

Como exemplo, vamos visualizar como seria a execução de um pequeno programa na forma de microoperações. Para tal, considere um processador que executa suas instruções em cinco estágios de execução:

Cada instrução do programa é decomposta em microoperações que são executadas, geralmente, uma a cada ciclo de clock.

Sendo, assim, suponha que o programa a ser executado está na memória de acordo com a Tabela 3.1, “Exemplo de um programa de duas instruções armazenado na memória” a seguir. Cada instrução fica armazenada em um endereço de memória, assim como as variáveis envolvidas.

Tabela 3.1. Exemplo de um programa de duas instruções armazenado na memória

Endereço Instrução ou Dado

FF01

A = B * C

FF02

B = A + 2

FF03

15 // valor de A

FF04

2 // valor de B

FF05

4 // valor de C


A seguir serão apresentadas as microoperações executadas para a primeira instrução.

3.5.1. Busca de Instrução

Para que esse programa seja executado, é necessário que o registrador PC contenha o endereço FF01 para que a primeira instrução do nosso programa nessa buscada e executa. O início de execução de um programa é causado por uma ação do usuário (quando ele clica no ícone de um programa, por exemplo), pelo Sistema Operacional ou um por um outro programa.

Uma vez que o PC tenha o endereço FF01, na próxima instrução a ser buscada, a Unidade de Controle irá executar as seguintes instruções:

t1:     MAR <- PC
        Memória <- fetch;
t2:     MBR <- ‘A = B * C’
        PC <- PC + 1
t3:     IR <- MBR

Neste exemplo, no tempo t1, MAR recebeu o endereço contido em PC, ou seja, FF01. Nesse mesmo instante, a Unidade de Controle envia o sinal ‘fetch’ para memória, que por sua vez, passa o conteúdo do endereço FF01 para o registrador MBR no instante t2 seguinte. Aproveitando o tempo, enquanto o conteúdo da memória era trazido para o MBR, a Unidade de Controle incrementou o endereço de PC para FF02. Só no tempo t3 a instrução está pronta em MBR e é então copiada para IR para que possa ser Decodificada na próxima microoperação.

3.5.2. Decodificação

Durante a decodificação não são executadas Microoperações. A instrução que acabou de ser copiada para IR é analisada e a Unidade de Controle vai então escolher que Microoperações serão executadas nas etapas seguintes.

3.5.3. Busca de Dados

Nas próximas etapas, será necessário buscar os dados necessários para a execução da instrução. Como os dados envolvidos (B e C) estão na memória, e não em registradores, serão necessárias duas Buscas Indiretas. A instrução na verdade nunca chega como sendo ‘A = B * C’. Ao invés disso, ela seria armazenada como ‘(FF03) = (FF04) * (FF05). Por questões didáticas, utilizamos ainda as variáveis A, B e C.

Para buscar o conteúdo da variável B, as seguintes Microoperações são executadas.

Na etapa de Decodificação, a instr

t4:     MAR <- (FF04)
        Memória <- read
t5:     MBR <- 2
t6:     ACC <- MBR

Aqui, o endereço FF04 é passado para o MAR para que seja buscado na memória no tempo t4, em seguida é enviado um sinal de leitura para a memória. Ao receber o sinal de leitura, a memória busca o conteúdo do endereço FF04 e o copia para dentro da CPU, no registrador MBR no instante t5. Finalmente, no tempo t6, o conteúdo de MBR (valor 2) é copiado para o registrador acumulador (ACC).

[Nota]

Note que usamos sempre parêntesis para indicar que se trata de um endereço, e sem os parêntesis quando se trata de um dado.

O próximo passo seria buscar o conteúdo da variável C de forma análoga a utilizada para buscar B.

t7:     MAR <- (FF05)
        Memória <- read
t8:     MBR <- 4
t9:     R1 <- MBR

Perceba que na última Microoperação o conteúdo de C foi copiado para R1, para não sobreescrever e perder o conteúdo da variável B que foi armazenado em ACC.

3.5.4. Execução

No próximo passo, a instrução precisa ser executada. Isso é feito em um único passo no tempo t10, onde ACC, que agora mantém o conteúdo da variável B é multiplicado por R1, que possui o conteúdo da variável C.

t10:     ACC <- ACC * R1

3.5.5. Salva Resultados

Finalmente, o resultado da operação precisa ser salvo na variável A. Para tal, o endereço de A (FF03) é copiado para o registrador de endereço (MAR) no instante t11. No instante t12 seguinte, o resultado da operação aritmética armazenado em ACC é copiado para o registrador de dados (MBR). Neste mesmo instante, a Unidade de Controle envia o sinal de escrita para a memória, que localiza o endereço FF03 e escreve nele o resultado da operação aritmética que foi salvo em ACC, ou seja, oito (8).

t11:    MAR <- (FF03)
t12:    MBR <- ACC
    Memória <- write

3.5.6. Instrução completa

Podemos agora visualizar a seguir como a primeira instrução do programa (A = B * C) foi executada em microoperações.

// Busca de Instrução
t1:     MAR <- PC
        Memória <- fetch;
t2:     MBR <- ‘A = B * C’
        PC <- PC + 1
t3:     IR <- MBR

//Busca de Dados (B)
t4:     MAR <- (FF04)
        Memória <- read
t5:     MBR <- 2
t6:     ACC <- MBR

//Busca de Dados (C)
t7:     MAR <- (FF05)
        Memória <- read
t8:     MBR <- 4
t9:     R1 <- MBR

//Execução
t10:    ACC <- ACC * R1

//Salva resultados
t11:    MAR <- (FF03)
t12:    MBR <- ACC
    Memória <- write

A primeira instrução foi finalizada em 12 passos. Se cada passo for 1 ciclo de clock, então temos 12 ciclos do relógio para concluir essa instrução. A segunda instrução do programa (B = A + 2) é muito semelhante, e também precisará de 12 passos para ser executada. Esse é um ótimo exercício para você praticar. Ao final a memória estará diferente de como iniciou, e deverá estar com os conteúdos apresentados na Tabela 3.2, “Memória após execução do programa.”.

Tabela 3.2. Memória após execução do programa.

Endereço Instrução ou Dado

FF01

A = B * C

FF02

B = A + 2

FF03

8 // valor de A

FF04

10 // valor de B

FF05

4 // valor de C