Post

Introdução ao nível de arquitetura de conjunto de instruções (ISA)

Introdução ao nível de arquitetura de conjunto de instruções (ISA)

Introdução

Este é o primeiro de uma série de artigos em que pretendo falar sobre arquitetura de computadores para fins de aprendizado e transmissão de conhecimento. Aqui, por conveniência e gosto pessoal, apresento uma breve introdução ao nível de arquitetura de conjunto de instruções (ISA), que será aprofundado em artigos posteriores.

O que é um computador?

Antes de partirmos para o que é uma ISA, é necessário resumir, ainda que de forma bem superficial, o que é um computador.

Um computador é tão-somente uma máquina feita para resolver ou ajudar em tarefas humanas. Trata-se de uma máquina primitiva, a sua única tarefa real é realizar cálculos rapidamente, além de ser capaz de entender apenas 0s (transistor desligado) e 1s (transistor ligado).

Dado tal fato, você pode estar se perguntando: como, então, conseguimos realizar tarefas complexas, a exemplo de transmissão de vídeo e execução de jogos online? A resposta está na palavra abstração. Que é essa dita abstração? É simplesmente a organização de um computador em várias camadas, sendo cada camada superior responsável por abstrair operações mais complexas do nível abaixo e transformá-las em algo mais legível e amigável para o ser humano.

Antes de prosseguirmos, vale compreender como funciona a abstração em computadores na prática. Imagine uma escada: cada degrau representa um nível de complexidade. No topo, temos linguagens e interfaces próximas da forma como pensamos e escrevemos. Mais abaixo, instruções menos intuitivas, até chegar, por fim, aos sinais elétricos que o computador real entende – tensões de 0V ou 5V, representadas pelos valores 0 e 1, respectivamente. Observe o esquema abaixo:

🖥️ Níveis de Computação
Máquina virtual nível n - Super Alto Nível
# Código em AppleScript
if age ≥ 18 then display dialog "Adulto"
🚀 Frameworks, bibliotecas, ferramentas drag-and-drop, IA etc.
⬇️
Interpretador/Framework
Máquina virtual nível 3 - Linguagens de Alto Nível
int idade = 25;
if (idade >= 18) printf("Adulto");
💻 C, Java, Python etc.
⬇️
Compilador/Interpretador
Máquina virtual nível 2 - Assembly
MOV AX, 25
CMP AX, 18
JGE adulto
🔧 Comandos simbólicos
⬇️
Assembler
Máquina virtual nível 1 - Linguagem de Máquina
10110000 00011001
00111001 00010010
01110101 00000100
🔢 Apenas 0s e 1s
⬇️
Circuitos Eletrônicos
Máquina nível 0 (Computador real) - Hardware
⚡ 5V = 1, 0V = 0
🔌 Sinais elétricos, transistores, circuitos integrados

Um computador com múltiplos níveis funciona como diferentes máquinas virtuais, cada uma com a sua linguagem específica. Apenas a linguagem do nível mais baixo é executada diretamente pelo hardware (utilizarei esse termo para me referir aos circuitos eletrônicos de agora em diante), enquanto as demais precisam ser interpretadas ou traduzidas (compiladas) para níveis inferiores. Isso é bom para o programador que trabalha em níveis superiores, porque ele não precisa se preocupar com esses processos de tradução, já que a arquitetura do sistema garante que seus programas serão executados, independentemente de como isso acontece internamente.

Nível de arquitetura de conjunto de instruções

Agora que sabemos o que é um computador, é importante ressaltar que o esquema apresentado anteriormente trata-se apenas da ponta do iceberg em relação a onde pretendemos chegar. Computadores modernos são, na verdade, constituídos por alguns outros níveis não apresentados, como é o caso do nível de microarquitetura – que será tratado em outra ocasião – e o nível ISA (Instruction Set Architecture), do qual trataremos agora.

Criado com o intuito de padronizar a fabricação de processadores e torná-los compatíveis entre si, a ISA é uma especificação meramente abstrata que define a interface de comunicação entre hardware e software, sendo um modelo de programação oferecido pelo processador e o designador do comportamento do hardware. É a linguagem comum compreendida por compiladores e hardware. Alinhando-nos a Tanenbaum, podemos dizer que o código de ISA é o que um compilador produz.

Tendo isso em mente, é possível dizer que a ISA é responsável por definir os tipos de instruções disponíveis, os tipos de operações, modos de endereçamento, modos de operação (como usuário e kernel, que serão abordados em outros artigos), além de como o hardware se comporta do ponto de vista do programador. Alguns exemplos de ISA são x86-64, ARM e RISC-V. Pela conveniência de ser o meu ponto central de estudos, focarei principalmente na ISA RISC-V.

Confusão entre ISA e Assembly

Na grande maioria dos casos concretos, o código produzido pelos compiladores está em linguagem Assembly, mas disso pode surgir a confusão de que o Assembly é a própria ISA. Podemos dizer que a ISA é a especificação, isto é, define o comportamento, enquanto o Assembly é a implementação, ou seja, a concretude da especificação, de certo modo. Recorrerei à simples analogia de que a ISA está para o Assembly do mesmo modo que a gramática está para a sintaxe, pois enquanto aquela define o idioma, suas regras e comportamentos, esta define as palavras escritas. Podem existir diversos tipos de sintaxe Assembly dentro de uma única ISA, como no caso do x86-64 (Intel) e do x86-64 (AT&T), que são sintaxes diferentes porém intercomunicáveis.

Implementações

Como dito anteriormente, focarei na ISA RISC-V. Observe a implementação abaixo:

🖥️ Assembly RISC-V
Máquina virtual nível 2 - Assembly RISC-V
li x5, 15 # Carrega 15 no registrador x5
li x6, 27 # Carrega 27 no registrador x6
add x7, x5, x6 # x7 = x5 + x6 (soma)
mv a0, x7 # Move resultado para o argumento
🔧 Mnemônicos legíveis, instruções Assembly RISC-V

O código Assembly realiza a soma de dois números (15 + 27) através de quatro instruções básicas: Primeiro, as instruções li x5, 15 e li x6, 27 carregam os valores constantes nos registradores x5 e x6, respectivamente. Em seguida, add x7, x5, x6 executa a soma propriamente dita, armazenando o resultado (42) no registrador x7. Por fim, mv a0, x7 move o resultado para o registrador a0, seguindo a convenção de chamada RISC-V, em que a0 é usado para retorno de valores. Isso demonstra que a ISA RISC-V possui alguns princípios fundamentais, como instruções simples e uniformes, operações load/store explícitas e uso eficiente do banco de 32 registradores, como toda boa ISA. A ISA RISC-V define exatamente como cada instrução deve ser codificada em binário e executada pelo hardware, criando uma interface clara entre ele e o software.

Esta postagem está licenciada sob CC BY 4.0 pelo autor.