PCL – The Peasant’s Computer Language

Introdução

Com a crescente demanda por treinamento em alta tecnologia, a equipe do Laboratório de Cálculos Científicos da Universidade de Brasília desenvolveu um sistema de simulação baseada em software para ensino de linguagens de computação em alto e baixo nível.

O projeto da linguagem surgiu para unificação de projetos experimentais – tais como PAPC (Projeto Assembly para Crianças) e AFOP (ASM For Old People) –, que tinham características relevantes, mas não apresentavam uma solução auto-suficiente.

Foi com o intuito de fornecer uma forma didática e fácil de ensinar linguagens de computação que surgiu a PCL (Peasant’s Computer Language) para aprendizagem de baixo nível, e  acessível para qualquer peão. Esta linguagem foi criada para ser compatível com o bytecode SAPECO (Singular Assembly PEão COde).

Características Técnicas

O código de instruções consiste em uma ISA virtualizada, com um conjunto reduzido de instruções, que permite a execução em um espaço de memória controlado pelo software EnXADA (Environment of eXtended Access Dynamic Assembler).

O programa é executado na LAJE (Large Array Jumper Environment), que é a máquina virtual responsável pelo monitoramento e interpretação do bytecode SAPECO.

A LAJE consiste em uma memória que armazena os programas com seus dados; uma fila de espera, na qual processos podem ser administrados; um registrador; uma unidade de execução para operações aritméticas e lógicas de cada instrução SAPECO; uma unidade de controle que prepara a próxima instrução (fila de controle); e a fila de espera (queue) – uma memória de dados composta por uma sequência de componentes de dados (Modelo FIFO).

A LAJE faz comunicação externa através de algumas instruções específicas para leitura e saída de dados e só executa um programa por vez.

Todas as operações realizadas na LAJE são feitas no registrador, onde as informações são colocadas e manipuladas. Todas as informações são tradas por palavras, que geram instruções de tamanho fixo. Uma palavra têm um número de tamanho fixo (4 dígitos decimais).

Para armazenamento de dados, a LAJE é equipada com uma memória de 100 palavras, que são referenciadas de 00 à 99.

OBS: os projetistas prevem uma extensão de 10000 palavras de armazenamento na segunda versão do bytecode. Na verdade, a LAJE já possui espaço de dados reservado para as 10000 palavras, contudo, como o bytecode atualmente só possui instruções de 2 dígitos decimais para referência e dados, somente 100 espaços são endereçáveis. O aumento dos dígitos para endereçamento previsto no padrão é denominado PUSHADINHO pelos próprios criadores.

O programa é carregado e começa a executar na posição 00.

Cada instrução escrita em SAPECO ocupa uma palavra de memória da LAJE. A instrução SAPECO consiste em 4 dígitos, conforme dito. Os 2 primeiros dígitos consistem no código da operação e os últimos 2 dígitos consistem consistem nos operandos.

É importante salientar que os operandos das instruções não equivalem à operandos matemáticos, como acontece em muitas ISAs. Os operandos de instruções são endereços de posição de memória contendo a palavra à qual a operação se aplica.

As operações matemáticas são sempre feitas entre acumulador e memória. Dessa forma, as instruções de operações matemáticas possuem apenas 1 operando, que é o da memória.

Abaixo segue o conjunto de instruções SAPECO:

NOME MNEMÔNICO OPCODE DESCRIÇÃO
Bota Pá Nois aê BPN * 10 Lê uma palavra do teclado para uma posição específica.
Mostra Pá Nóis Aê MPN * 11 Escreve na tela uma palavra de uma posição de memória.
Traz Pá Nois aê TPN 20 Carrega da memória para o acumulador
Guarda Pá Nóis aê GPN 21 Salva na memória o valor do acumulador
Soma aê SOM ** 30 Adiciona uma palavra de uma posição à palavra salva no acumulador
Tira Essa Porra TEP ** 31 Efetua a subtração de uma posição de memória pelo valor do registrador
Divide DIV ** 32 Divide o valor salvo na posição especificada pelo valor salvo no registrador.
Multiplica MUL ** 33 Multiplica a palavra de uma posição específica pelo acumulador.
Quebra Pá Área QPA 40 Desvia para uma posição específica na memória.
Vaza se Tiver Zerado VTZ 41 Sai para uma posição específica da memória se o acumulador estiver zerado.
Quebra o Zé Ninguém QZN 42 Desvia para uma posição se o acumulador for negativo.
Capa o Gato COG 43 Suspende todo o programa.

* Obs: A instrução MPN e BPN não são comuns em arquiteturas reais. Contudo, arquiteturas interpretadas costumam ter instruções de baixo nível com operações diretas de IO padrão.

** Após a operação o valor é salvo no acumulador.

Exemplo utilizando todas matemáticas instruções SAPECO:

POSIÇÃO CÓDIGO ASM COMENTÁRIO
00 1007 MPN 07 # equivale à scanf(&M[7]), supondo que tenha digitado valor 10
01 1008 MPN 08 # scanf(&M[8]), supondo que tenha digitado valor 8
02 2007 TPN 07 # $registrador = M[7], ou seja, $registrador = 10
03 3008 SOM 08 # $registrador = $registrador + M[8], $registrador = 10 + 8 = 18
04 3107 TEP 07 # $registrador = $registrador – M[7], $registrador = 18 – 10 = 8
05 3307 MUL 07 # $registrador = $registrador * M[7], $registrador = 8*10=80
06 3208 DIV 08 # $registrador = $registrador / M[8], $registrador = 80/8=10
07 0010 ** # Variável A
08 0008 ** # Variavel B
09 4300 COG # sai do “pograma”. Note que a LAJE ignora endereços de dados (00 nos 2 primeiros algarismos, seção de instrução)

* M[] é o vetor que representa a memória usada na LAJE
** Veja que o código 00 nos 2 primeiros indica que aquela posição armazena um DADO, não uma instrução.

Implementação da LAJE

Uma simples implementação compatível com as especificações acima pode ser obtida no endereço: http://www.sawp.com.br/code/general/LAJE.cc

Considerações Finais

Este documento foi criado em meados de 2009, sendo uma compilação de várias ideias surgidas durante uma bebedeira promovida no Centro Acadêmico de Física da Universidade de Brasília. Portanto, pedimos que os leitores sóbrios não considerem tal conteúdo.

 

Pedro Garcia