ICC
Linguagem de Máquina e Programas
Já sabemos que um programa é uma seqüência de instruções que dirigem a
CPU na execução de algum cálculo/tarefa.
Os dados e as instruções de um programa, para serem manipulados ou
executados pelo processador, precisam chegar a ele sob a forma de
linguagem de máquina – impulsos elétricos codificados num sistema binário –
pois as operações internas de um processador manipulam somente dois sinais
elétricos (“tem corrente” , “não tem corrente”).
Para facilitar a compreensão, representamos a presença de corrente
(voltagem) pelo dígito 1 e a ausência de corrente (voltagem) pelo dígito 0. Os
dígitos 0 e 1 são conhecidos por bits.
Para ilustrar e facilitar o entendimento da operação de uma CPU, vamos
apresentar um programa simples em linguagem de máquina e a ação de uma
CPU ao executar as instruções contidas em tal programa.
Vamos considerar uma CPU simples, com uma linguagem de máquina
primitiva. De forma geral, qualquer linguagem nada mais é do que um
conjunto de regras que especificam como as coisas devem ser expressas para
serem compreendidas.
No caso da linguagem da nossa máquina em particular, consideraremos um
tamanho de 8 bits para cada instrução, dividindo-a em duas partes: um
código de operação de 3 bits que especifica a operação a ser executada,
mais um operando de 5 bits que indica o endereço do dado sobre o qual a
operação será realizada.
Também admitiremos a existência de um acumulador na unidade de
aritmética e lógica no qual as operações aritméticas são executadas.
A tabela a seguir define o conjunto de instruções desta nossa CPU simples (isto
significa que a CPU tem circuitos eletrônicos que executam diretamente cada
uma destas instruções em particular).
Código de Operação
001
010
011
100
101
110
111
Significado
Carregue: copie no acumulador o conteúdo da palavra (célula) endereçada
Armazene: copie na palavra endereçada o valor do acumulador
Some: substitua o conteúdo atual do acumulador pela soma de seu conteúdo
com o conteúdo da palavra (célula) endereçada
Subtraia: substitua o conteúdo atual do acumulador pelo resultado obtido da
subtração entre este conteúdo e o conteúdo da palavra (célula) endereçada
Desvie: salte para a instrução indicada pela palavra (célula) endereçada
Desvie se diferente de zero: salte para a instrução na palavra (célula) endereçada
se o valor contido no acumulador for diferente de zero
Pare: encerre a execução
Figura 1 – Exemplo de um conjunto de instruções
-1-
Vamos supor que nosso pequeno programa tenha sido carregado nas 10
primeiras palavras (células) da memória principal. Além das dez palavras
indicadas, outras também receberam valores. A figura abaixo mostra o
conteúdo completo da memória no início da execução do programa.
Palavra
Endereço
em
binário e o
correspondente em
decimal
00000 (0)
00001 (1)
00010 (2)
00011 (3)
00101010
01001100
00101110
01101011
00100 (4)
00101 (5)
00110 (6)
00111 (7)
01001110
00101100
10001101
01001100
01000 (8)
01001 (9)
01010 (10)
01011 (11)
11000010
11100000
00000011
00000100
01100 (12)
01101 (13)
01110 (14)
01111 (15)
00000000
00000001
00000000
00000000
Figura 2 – Conteúdo de memória do programa e seus dados
Para facilitar a compreensão, o código de operação e o operando de cada
instrução do programa carregado na memória são mostrados na tabela
abaixo, em separado, apesar de estarem justapostos na memória, formando
uma cadeia de 8 bits.
Endereço da Instrução (binário)
00000
00001
00010
00011
00100
00101
00110
00111
01000
01001
Código de Operação
001
010
001
011
010
001
100
010
110
111
Operando
01010
01100
01110
01011
01110
01100
01101
01100
00010
00000
Figura 3 – Endereço de memória, código e operando de cada instrução do programa
Vamos admitir que a execução comece no endereço 00000, com a instrução
00101010, e que as instruções sejam executadas na ordem em que aparecem,
exceto menção em contrário.
Com base na tabela da Figura 1, verificamos que a primeira instrução é
CARREGUE (código de operação 001) a qual está ordenando à CPU que
copie no seu acumulador o conteúdo do endereço 01010 (endereço 10 em
decimal). Assim, de acordo com a instrução, o conteúdo 00000011 (3 em
decimal) é colocado no acumulador. O fato desta operação ser apenas
“copiar” significa que o conteúdo do endereço 01010 permanece inalterado.
Entretanto, o conteúdo do acumulador foi substituído e se perdeu.
A próxima instrução a ser executada, dentro da seqüência, está contida no
endereço 00001. Esta segunda instrução é ARMAZENE (código de operação
010) a qual está ordenando à CPU que copie na palavra 01100 (12 em
-2-
decimal) o valor 00000011 (valor que está no acumulador), substituindo o
anterior que ali se encontrava.
A terceira instrução é novamente CARREGUE (código 001). O conteúdo atual
da palavra com endereço 01110 (14 em decimal) é copiado no acumulador.
O valor copiado é 00000000.
A quarta instrução é SOME (código 011). O conteúdo (00000100, 4 em
decimal) do endereço 01011 é somado ao conteúdo atual (00000000) do
acumulador. A soma é realizada em binário no acumulador, resultando
00000100 (4 em decimal). Este valor substitui o conteúdo anterior do
acumulador.
A quinta instrução é ARMAZENE. Esta instrução faz com que o resultado da
adição realizada anteriormente seja copiado do acumulador para o endereço
01110, substituindo o conteúdo anterior deste endereço.
A sexta instrução é, novamente, CARREGUE. Agora o conteúdo da palavra de
endereço 01100 (12 em decimal) é copiado no acumulador. Este valor é
aquele armazenado pela Segunda instrução, ou seja, 00000011 (3 em
decimal).
A sétima instrução é SUBTRAIA (código 100). O conteúdo (00000001) do
endereço 01101 (endereço 13) é subtraído do conteúdo do acumulador
(00000011, 3 em decimal). A subtração é realizada em binário no acumulador,
resultando o valor 00000010 (2 em decimal).
A oitava instrução (010) é, novamente, ARMAZENE. O resultado obtido
(00000010, valor 2 em decimal que está no acumulador) é armazenado na
palavra com endereço 01100 (endereço 12).
Neste ponto, vamos fazer uma pausa na computação para analisar o que
aconteceu até aqui.
O estado atual da memória e do acumulador está ilustrado na Figura 4.
Comparando-se com o estado inicial da memória (Figura 2), nota-se que
ocorreram alterações de conteúdos. As palavras afetadas foram as de
endereços 01100 e 01110 (em cinza). De fato, devemos observar estas duas
palavras à medida que a computação prossegue.
00000 (0)
00001 (1)
00010 (2)
00011 (3)
00101010
01001100
00101110
01101011
00100 (4)
00101 (5)
00110 (6)
00111 (7)
01001110
00101100
10001101
01001100
01000 (8)
01001 (9)
01010 (10)
01011 (11)
11000010
11100000
00000011
00000100
01100 (12)
01101 (13)
01110 (14)
01111 (15)
00000010
00000001
00000100
00000000
Acumulador :
00000010
Figura 4 – Conteúdo da memória e acumulador após execução de oito instruções.
-3-
Vamos passar agora para a nona instrução. A Figura 1 indica que esta
instrução é DESVIE SE DIFERENTE DE ZERO (código 110). Esta instrução é de um
tipo diferente das que vinham sendo executadas até agora. Ela indica duas
coisas. Primeiro, examine o conteúdo atual do acumulador. Se o valor contido
no acumulador é diferente de zero, o que é verdade neste momento
(00000010), então desvie imediatamente para a instrução cujo endereço é
dado no operando (00010, vai executar a instrução nesta célula. Célula 2 em
decimal). Esta será a próxima instrução a ser executada. Se o conteúdo do
acumulador é igual a zero, então, ao invés de desviar para a instrução do
endereço 00010, deve-se prosseguir executando a próxima instrução dentro
da seqüência, ou seja, a instrução localizada em 01001. Esta instrução é
chamada de Desvio Condicional.
No caso acima, houve um desvio para a terceira instrução (endereço 00010
ou 2). Como é de se esperar, as instruções de três a oito serão executadas
novamente. Este trabalho ficará como exercício (lembre-se que você deverá
iniciar agora da situação mostrada na Figura 4.
Ao passar pela segunda vez por este grupo de instruções, você deverá obter a
situação ilustrada na Figura 5, abaixo.
00000 (0)
00001 (1)
00010 (2)
00011 (3)
00101010
01001100
00101110
01101011
00100 (4)
00101 (5)
00110 (6)
00111 (7)
01001110
00101100
10001101
01001100
01000 (8)
01001 (9)
01010 (10)
01011 (11)
11000010
11100000
00000011
00000100
01100 (12)
01101 (13)
01110 (14)
01111 (15)
00000001
00000001
00001000
00000000
Acumulador:
00000001
Figura 5 – Conteúdo da memória e acumulador após a segunda execução do laço.
Neste ponto, a instrução de desvio condicional é encontrada pela segunda
vez. Novamente, o conteúdo do acumulador não é zero e o desvio é
executado uma outra vez. Este trabalho ficará como exercício. Após a
terceira execução da instrução oito, os conteúdos da memória e do
acumulador são mostrados na Figura 6.
Em particular, o conteúdo da palavra 01100 é 00000000, o da palavra 01110 é
00001100 (12 em decimal) e o conteúdo do acumulador é 00000000.
00000 (0)
00001 (1)
00010 (2)
00011 (3)
00101010
01001100
00101110
01101011
00100 (4)
00101 (5)
00110 (6)
00111 (7)
01001110
00101100
10001101
01001100
01000 (8)
01001 (9)
01010 (10)
01011 (11)
11000010
11100000
00000011
00000100
01100 (12)
01101 (13)
01110 (14)
01111 (15)
00000000
00000001
00001100
00000000
Acumulador:
00000000
-4-
Figura 6 – Conteúdo da memória e acumulador no final da execução do programa.
Neste ponto, a instrução de desvio condicional é encontrada pela terceira vez
mas não é executada, pois o conteúdo do acumulador é 0.
Conseqüentemente, passamos para a instrução do endereço 01001, que é a
seguinte na seqüência. Esta é uma instrução PARE (código 111). Assim, a
execução do programa é terminada.
A partir da Figura 6, podemos verificar os resultados finais obtidos.
Particularmente, o valor da palavra de endereço 01110 é 12 em decimal.
Agora, você poderá refletir sobre o que aconteceu, dando atenção especial
aos valores iniciais dados pela Figura 2, e tentar descobrir qual foi a finalidade
deste programa.
Conclusão
A discussão anterior descreveu como um computador típico opera. A
linguagem de máquina utilizada no exemplo foi elaborada apenas a título de
ilustração, entretanto, as linguagens reais de máquina têm propriedades
semelhantes.
O papel de um programa foi identificado como o de fornecer instruções
particulares sob as quais o controle da CPU opera para executar algum
cálculo requerido.
A tarefa de um programador é produzir a seqüência apropriada de instruções
para resolver algum problema em pauta.
-5-
Download

2-Linguagem de Maquina