Você está na fila do INPS (desculpe o mau jeito, mas é só para exemplificar...)
com sua senha para atendimento na mão. O mal humorado funcionário
do guichê lhe pergunta: “Qual é o seu número?”. Que número você
responde?
Na
sapataria, você acabou de escolher um pisante novo. Senta-se para
experimentar e o vendedor lhe pergunta: “Qual é o seu número?”.
Sua resposta é...
Assim
como a mesma pergunta recebe respostas diferentes conforme o contexto,
o mesmo byte é interpretado pela CPU como dado ou instrução dependendo
da forma como a CPU o recebe. E o mecanismo para distinguir uma
coisa de outra é simples e engenhoso.
Vamos
ver como a coisa funciona. Primeiro, os bytes que representam os
códigos das instruções que a CPU deve executar (“op-codes”) são
armazenados, um após o outro, em endereços sucessivos na memória
RAM (por enquanto, simplesmente assuma que há uma forma de depositar
as instruções na memória; depois veremos como isso é feito). Em
seguida, o endereço do código da primeira instrução a ser executada
é armazenado em um registrador especial da CPU, chamado IP (de “Instruction
Pointer”, ou “ponteiro de instruções”), ou seja, faz-se o IP “apontar”
para a primeira instrução. Isso é o que basta para iniciar a execução
de uma série de instruções. Porque, daí em diante, a CPU sabe direitinho
o que fazer.
A
CPU, como eu disse, é um chip inteligente. E, durante todo o tempo
em que o micro está ligado, está permanentemente fazendo duas coisas:
primeiro, examina o conteúdo da posição de memória “apontada” pelo
IP e executa a instrução correspondente ao código lá encontrado.
Depois, soma um ao conteúdo do IP (portanto, “aponta-o” para o endereço
seguinte). E segue adiante, sempre repetindo esses dois procedimentos.
É assim (colocando-se o op-code em um endereço que será “apontado”
pelo IP) que se “passa” uma instrução para a CPU.
Agora,
ficou claro como a CPU distingue um byte que corresponde a uma instrução
de um byte (eventualmente, de mesmo valor) que corresponde a um
dado: se o byte está em um endereço para o qual o IP “aponta”, é
interpretado como sendo uma instrução. Se não, é um dado. E o byte
usado como exemplo semana passada, “10101100”, (que corresponde
ao valor 172 em decimal) caso esteja no endereço contido no IP,
é interpretado como uma instrução que copia no primeiro registrador
(o registrador “AL”) o conteúdo da posição de memória cujo endereço
está no registrador “SI”. Mas se o mesmo byte estiver em um endereço
não “apontado” pelo IP, é interpretado como um dado (o caractere
“1/4”, correspondente ao código ANSI 172).
Neste
ponto você já deve ter percebido que um “programa” nada mais é que
uma série de instruções encadeadas, com um propósito definido. Quando
você “carrega” um programa (calma, que mais tarde veremos como isso
é feito), simplesmente deposita um conjunto de instruções em um
certo trecho de memória RAM e “aponta” o IP para a primeira instrução.
A CPU, então, executa essa instrução e aponta o IP para o endereço
da próxima, que é executada a seguir, e assim por diante.
É
claro que esta explicação foi um bocado simplificada. Pois, da forma
como foi descrito aí em cima, os programas seriam “burros” e, executando
uma instrução após a outra em uma ordem predeterminada, não admitiriam
intervenção do usuário. Na verdade, existem programas assim, mas
são raros. O mais comum são programas que executam as coisas que
o usuário “pede”. O que seria impossível caso as instruções fossem
executadas sempre na mesma ordem: como adivinhar o que o usuário
vai pedir?
Felizmente
há instruções capazes de alterar a ordem em que as demais são executadas.
E isso é feito de uma forma muito simples: alterando o conteúdo
do IP (que, como você sabe, contém sempre o endereço da próxima
instrução a ser executada). Por exemplo: agora mesmo, enquanto eu
olho para esta tela com ar aparvalhado procurando uma forma inteligente
de explicar a coisa, parece que meu micro não está “fazendo” nada.
A tela está imóvel, apenas com o cursor piscando idiotamente no
final do texto. Mas, na verdade, o micro está atarefadíssimo. O
programa que está sendo executado (um editor de textos) contém uma
série de instruções mais ou menos assim: 1 - verifique se o Piropo
saíu de seu torpor e teclou algo. 2 - se teclou, siga para a instrução
(4). 3 - se não teclou, volte para a instrução (1). 4 - veja se
o que foi teclado é um caractere, uma tecla de função ou uma combinação
de teclas de acesso aos menus. 5 - se caractere, execute a instrução
(6), se tecla de função a (7), se acesso a menus a (8)... E assim
por diante. A instrução (3), que manda voltar para a instrução (1),
nada mais faz que colocar o endereço da instrução (1) no IP. Parece
complicado (e, na verdade, é complicado mesmo...), mas no fundo
trata-se do encadeamento de procedimentos muito simples. E, fazendo
a CPU obedecer a um conjunto de instruções simples, encadeadas em
uma ordem que pode ser alterada pelo próprio programa, consegue-se
todas essas maravilhas de que nossas maquininhas são capazes.
Pronto.
Agora, já sabemos o que é um programa e como a CPU é capaz de executá-lo.
Agora, falta ver como fazer nossos micros executar o programa que
queremos.
B.
Piropo