Quem sou eu

Minha foto
Salvador, BA, Brazil
Analista de sistemas, expert em telecom, formado em Eng. Elétrica e nerd assumido

terça-feira, 19 de outubro de 2010

Sistemas de Computação 4 - Instruções de Máquina

O nível mais básico que um processador pode ser programado é através do conjunto das suas instruções de máquina (machine instructions set), também conhecidas como linguagem de máquina. Todos os fabricantes de processadores publicam a documentação necessária para compreender os detalhes da sua implementaão da arquitetura von Neumann e o funcionamento de cada uma das instruções de máquina reconhecidas.

Por exemplo: quem estiver interessado nos princípios de funcionamento e na linguagem de máquina das famílias de processadors Intel de 32 e 64 bits devem ler o manual Intel(R) 64 and IA-32 Architectures Software Developer's Manual (volumes 1, 2A, 2B, 3A e 3B) e os manuais Intel(R) 64 and IA-32 Architectures Optimization Reference Manual e Intel(R) 64 and IA-32 Architectures Software Developer's Manual Documentation Changes, só para começar.

Pra não dizerem que sou parcial com este ou aquele fabricante (e também em homenagem às minhas raízes profissionais), quem quiser fazer o mesmo com as máquinas IBM z/Architecture (sucessora das venerandas arquiteturas ESA/390, ESA/370, /370-XA, /370 e /360) tem que começar pela leitura do manual z/Architecture Principles of Operation.

Não quero prender meus textos à descrição da tecnologia de qualquer fabricante em particular. Em vez disso vou procurar descrever aspectos que são válidos para todos eles, embora a terminologia específica usada por cada fabricante possa variar. Vamos nos focar nas funcionalidades, e deixar a nomenclatura pra lá, ok?

Então, vamos lá... Cada instrução de máquina é um conjunto de bits que tem, geralmente, o tamanho de uma palavra de memória (fullword). Também é posível que o instruction set aceite instruções de tamanhos diferentes. Nestes casos os tamanhos alternativos mais comuns são de meia palavra (halfword) e uma palavra dupla de memória (doubleword).

A instrução de máquina é dividida logicamente em duas áreas: os bits mais signiicativos da instrução (geralmente 8 ou 16 bits em processadores com palavra de memória de 32 ou 64 bits) são denominados Operation Code (ou, simplesmente OpCode) e identificam a natureza da instrução, Os demais bits são denominados área de operandos, e identificam os operandos que devem ser utiliados na execução da instrução.

Falando em bits mais significativos e menos significativos, aqui cabe uma advertência para quem não tem familiaridade com o assunto. A memória normalmente é "vista" pela CPU como uma sequência liear de bytes (usualmente com 8 bits cada). Os bytes da memória são endereçados (em binário, e com um número de bits geralmente igual a uma fullword) a partir de zero e crescendo sequencialmente até a capacidade total instalada na máquina (em tempo: estou falando da memória física, real, aqui. Memória virtual é um assunto para mais tarde). Mas existem maneiras diversas de colocar os bytes de informação na memória: os dois principais sâo:
  • Big endian: os dados na memória são armazenados de forma que o byte mais significativo dos dados ocupa o endereço de memória mais baixo, e o byte menos significativo dos dados ocupa o endereço de memória mais alto;
  • Little endian: os dados na memória são armazenados de forma que o byte mais significativo dos dados ocupa o endereço de memória mais alto, e o byte menos significativo dos dados ocupa o endereço de memória mais baixo.
Por exemplo, suponha que temos que armazenar na memória, a partir do endereço de memória x0 (para os não iniciados, este "x" antes do número indica que ele está expresso no sistema de numeração hexadecimal) a sequência de quatro bytes que representam o número decimal 1234 (em formato ASCII, um byte por caracter - se você não está familiarizado com a sigla ASCII calma... Veremos isto mais tarde, quando falarmos dos modos de codificação do valor dos operandos). O byte mais significativo dos dados é o caracter 1, e o byte menos significativo é o caracter 4. Conforme a endianess da máquina o armazenamento na memória seria conforme mostrado abaixo.


Curiosamente já houveram máquinas (como o DEC PDP-11) que tinham endianess mista. Enfim... Nestes textos sempre vou adotar a convenção de representar dados na memória no formato big endian. Então, seguindo esta convenção, a figura abaixo mostra a representação esquemática de uma instrução de máquina.

A propósito, se alguém ainda tem dificuldades com números expressos no sistema binário ou hexadecimal, em breve devo intercalar nos meus posts uma outra série de artigos, dedicados aos sistemas de numeração, aos procedimentos de conversão de representação e aos procedimentos da aritmética básica.

Mas, vamos voltar ao assunto... OpCode e área de operandos. O diagrama abaixo representa isto.


Conforme o valor contido no OpCode a CPU (mais especificamente a unidade de controle) identifica a localização e os valores dos operandos da instrução. Genericamente existem quatro tipos de operandos que podem ser referenciados em uma instrução de máquina:
  • Operandos implícitos: são aqueles que, embora não explicitados na área de operandos da instrução, serão utilizados no seu processamento.
  • Operandos imediatos: são aqueles cujo valor faz parte da instrução;
  • Operandos indiretos: são aqueles onde a referência contida na instrução aponta para o local  onde o valor do oprando está armazenado.
Para efeito de exemplo. vamos supor que o valor do operando de uma instrução seja a sequência de quatro caracteres ASCII ABCD. Se este fosse um operando implícito não haveria nenhuma referência na área de operandos da instrução, nem sobre o valor nem sobre a localização do operando, entretanto ele seria usado durante a execução da instrução. As figuras abaixo mostram como poderiam ser os casos deste operando ser imediato ou indireto.


As referências a operandos indiretos podem ser feitas três formas principais:
  • Referência absoluta: a referência ao operando identifica o registrador onde o valor do operando está armazenado ou o endereço absoluto na memória do byte mais significativo do valor do operando;
  • Referência base-deslocamento: a referência ao operando é composta de duas partes. A primeira identifica um registrador ou um endereço absoluto na memória onde está armazenado o endereço base (absoluto) do operando. A segunda parte pode ser um operando imediato, ou a identificação de um registrador ou um endereço absoluto na memória onde está armazenado o deslocamento do operando em relação ao endereço base. O endereço absoluto na memória do byte mais significativo do operando é obtido pela soma do valor do endereço base com o valor do deslocamento;
  • Referência base-índice-deslocamento: semelhante à referência base-deslocamento, apenas com a introdução de um elemento a mais - o índice - referenciado de forma semelhante à base. O endereço absoluto do byte mais significativo do operando é obtido pela soma dos valores base, índice e deslocamento.
Observe que a figura anterior de exemplo de operando indireto representa o caso onde o endereço absoluto do byte mais significativo do operando é dado como um operando iediato na instrução de máquina. As figuras abaixo exemplificam as outras formas de referência a operandos indiretos.



Agora que já vimos como são as instruções de máquina, no próximo artigo desta série vamos falar do método usado pela CPU para executar as instruções de máquina do programa; Porém acho que é chegada a hora, pelo bem dos menos experientes nesta área, de começar a publicar a série sobre sistemas de numeração.

    Nenhum comentário:

    Postar um comentário