Situada em meio ao cenário atual da programação, a relação entre o programador e a máquina, outrora mais evidente, tornou-se desafiadora para novos desenvolvedores. O aumento da semelhança entre linguagens de programação e linguagem humana contribui para esse fator, onde compreender como o código é interpretado pelo computador representa uma tarefa complexa e que muitos sentem dificuldade.
Essa questão pode ser agravada por sintaxes convenientes e funções milagrosas, sob um contexto o qual linguagens de programação de alto nível como JavaScript e Python predominam. Para enfrentar esse desafio, destaca-se uma ferramenta pedagógica valiosa: oComputador à Gaveta.
Trata-se de um computador hipotético que adere àarquitetura de Von Neumann,
semelhante aos computadores contemporâneos.
Figura 1 - Arquitetura de Von Neumann
Entretanto, suas características são simplificadas, preservando funcionalidades análogas às encontradas em componentes reais. A distinção reside na acessibilidade da linguagem de máquina, especialmente projetada para ser compreendida por iniciantes na programação.
O propósito deste projeto é resgatar a compreensão da interação entre o código e a máquina, oferecendo uma abordagem mais clara e educativa para aqueles que estão dando os primeiros passos na programação. Para que com isso proporcione-se um melhor entendimento da relação entre o código escrito e as operações realizadas pelo computador, promovendo uma base sólida para o aprendizado da programação.
Componentes
Por meio de analogias, seus componentes são sucintos, distintos e intuitivos com intuito de viabilizar sua associação. Estão listados a seguir
Um gaveteiro com 100 gavetas;
Uma calculadora com mostrador e teclado;
Um pequeno quadro-negro denominado EPI;
Um porta-cartões;
Uma folha de papel;
Um operador de sistema chamado CHICO, com um lápis, um apagador de quadro-negro e um giz.
Figura 2 - Arquitetura do HV
Gaveteiro
O gaveteiro é como uma série de gavetas numeradas de 00 a 99, sendo este número chamado de seu endereço. Dentro de cada gaveta há uma folha vazia, mas que pode conter uma instrução, um número de até três algarismos (por exemplo: 102, 50, 3, etc.) ou informações adicionais que serão abordadas ao decorrer do texto.
Agora, vamos entender o funcionamento desse sistema de gavetas
Em qualquer momento, só podemos abrir uma gaveta.
Quando lemos o que está escrito em uma gaveta, isso não muda o que está escrito lá.
Antes de escrever algo numa gaveta, precisamos apagar o que já está lá.
O valor que será escrito numa gaveta não pode ser inferior a -99 e superior a 999.
Somente o operador do sistema pode mexer no gaveteiro.
Durante o estado de carga as instruções que estão no porta-cartões são guardadas no gaveteiro, até que seja armazenado o cartão contendo a instrução 000, que indica o fim do estado de carga.
Figura 3 - Gaveteiro
Calculadora
A calculadora utilizada no HV é semelhante a qualquer outra, apresentando um teclado com dígitos de 0 a 9 e um visor onde são exibidos os resultados das operações. Estes resultados são armazenados no acumulador. No entanto, ao contrário das calculadoras convencionais, esta opera exclusivamente com valores inteiros e oferece apenas quatro operações: soma, subtração, divisão e multiplicação.
Com a operação da calculadora sendo realizada desta forma
Para carregar um número no acumulador, é necessário pressionar a tecla “=” para garantir o encerramento de qualquer operação anterior. Em seguida, os algarismos do número desejado são digitados. Este número é então exibido no acumulador.
Uma operação aritmética é sempre realizada entre o número armazenado no acumulador e um segundo número. Para executá-la, é necessário pressionar a tecla da operação desejada, inserir o segundo número e em seguida pressionar a tecla “=”. O resultado da operação será exibido no acumulador.
Assim como o gaveteiro, a calculadora só pode ser utilizada pelo CHICO.
Figura 4 - Calculadora do HV
EPI (Quadro Negro)
O EPI é um quadro negro que o CHICO usa para deixar anotado o endereço da proxima instrução que ele deve executar durante o estado de execução. Somente o CHICO pode alterar e ler o conteúdo do EPI.
Figura 5 - Quadro Negro com EPI (Endereço da Próxima Instrução)
Porta-Cartões
É um componente que se assemelha a um porta-cigarros, com os cartões sendo inseridos na parte superior e sendo retirados para leitura na parte inferior. Os cartões que formam o código a ser executado são retirados no estado de carga e então armazenados nas gavetas até se encerrar esse estado.
Diferente dos outros componentes, esse pode ser manipulado pelo usuário, e seu funcionamento ocorre da seguinte forma
Cartões são inseridos exclusivamente pela parte superior, um por vez. Nos cartões devem estar escritos apenas instruções e números de até 3 algarismos;
Cartões são retirados da extremidade inferior, um de cada vez, aparecendo na mesma ordem em que foram colocados no dispositivo;
Somente o CHICO pode retirar um cartão;
A inserção de um cartão só pode ser feita por um usuário;
Quando o CHICO executa uma instrução de leitura do porta-cartões que se encontra vazio, é solicitado ao usuário que insira um novo cartão para que a execução do programa continue.
Figura 6 - Porta-Cigarros (demonstrativo)
Folha de Saída
Trata-se de uma folha de papel onde pode ser escrito um número em cada linha, utilizando-se sempre linhas consecutivas. Somente o CHICO pode escrever nesta folha e somente o usuário pode ler o que já foi escrito.
Figura 7 - Folha de Saída
Operador CHICO
Resumindo as diversas características descritas, vemos que o operador CHICO é a única pessoa que tem acesso ao gaveteiro, à calculadora e ao EPI, além de ser o único que pode retirar cartões do porta-cartões e escrever na folha de saída.
Ele executa estritamente as ordens recebidas, não podendo tomar nenhuma iniciativa própria ou realizar ação fora da especificação destas. Essas ordens podem ser quaisquer uma das instruções que serão detalhadas na seçãoLinguagem de Máquina.
O CHICO trabalha sempre em um de dois estados diferentes
Estado de Carga
O estado de carga se inicia assim que o usuário pede a execução do código. Nele o CHICO retira um cartão do porta-cartões, lê seu conteúdo e o copia para uma gaveta do gaveteiro, seguindo a sequência das gavetas.
Esse processo é repetido até a instrução 000, que indica o fim do programa, ser lida, encerrando o estado de carga e dando início ao estado de execução.
Figura 8 - Estado de Carga
Estado de Execução
O estado de execução é aquele no qual o operador do sistema executa as instruções que foram escritas nas gavetas. O EPI indica ao operador qual gaveta ele deve abrir para ler a instrução, esse sempre se iniciando com o valor 0. Após realizar uma instrução, CHICO atualiza o valor do EPI, geralmente fazendo o incremento de +1 ao valor atual. Novamente ele checará o valor no quadro negro e abrirá a gaveta indicada, até, por fim, executar a instrução 000, finalizando o programa.
À fim de melhor demonstrar como o estado de execução funciona, a seguir há ilustrações do CHICO executando um programa que imprime 50 na folha de saída.
Os detalhes sobre como escrever um código para CHICO executar serão detalhados posteriomente.
Figura 9 - Transição para o Estado de ExecuçãoFigura 10 - Primeira InstruçãoFigura 11 - Segunda InstruçãoFigura 12 - Terceira InstruçãoFigura 13 - Quarta Instrução
Linguagem de Máquina
Em computadores reais, os seus conjuntos de instruções é conhecida como linguagem de máquina. O HV mesmo sendo um computador hipotético tem sim sua linguagem de máquina, que são os conjuntos de instruções que o CHICO conhece. Ele só conhece os números de base 10 portanto suas instruções são números decimais, sendo composto geralmente por 3 dígitos, com exceção da 0-N.
Instruções
A seguir vamos ver todas as instruções que o CHICO conhece, lembrando que estamos tratando de uma linguagem de baixo nível, então suas instruções são bem simples e restritas, com elas podendo ser divididas em instruções de carga, aritméticas, entrada, saída e controle.
Carregamento
0EE (Copie valor da gaveta EE para AC) Esta instrução permite transferir dados armazenados em uma gaveta (registrador temporário) denominada EE para o acumulador (AC). Isso é fundamental para mover informações entre locais de armazenamento temporário e o registrador principal, onde operações subsequentes podem ser realizadas.
1EE (Copie valor do AC para gaveta EE) Inversamente à instrução anterior, esta permite a transferência de dados do acumulador para uma gaveta específica. É útil quando se deseja preservar temporariamente o conteúdo do acumulador antes de realizar outras operações.
0-N (AC recebe uma constante) Permite carregar uma constante (representada por N) diretamente no acumulador. Isso é útil para inicializar variáveis ou realizar operações com valores fixos.
Operações Aritméticas
2EE (Some cEE ao AC) Adiciona o valor armazenado em uma gaveta (cEE) ao conteúdo atual do acumulador.
3EE (Subtraia de AC o cEE) Subtrai o valor armazenado em uma gaveta (cEE) do conteúdo atual do acumulador.
4EE (Multiplique o cAC por cEE) Multiplica o conteúdo atual do acumulador (cAC) pelo valor armazenado em uma gaveta (cEE).
5EE (Divida o cAC por cEE) Divide o conteúdo atual do acumulador (cAC) pelo valor armazenado em uma gaveta (cEE).
Controle de Fluxo
6EE (Se cAC > 0, vá para EE) Permite a execução condicional, desviando o fluxo do programa para um endereço específico (EE) apenas se o conteúdo do acumulador for maior que zero. Isso é útil para tomar decisões com base em condições.
9EE (Vá para cEE) Instrução de desvio incondicional que direciona o fluxo do programa para um endereço específico (EE). É utilizado para implementar loops e sub-rotinas.
Entrada/Saída
7EE (Leia um valor e guarde na gaveta EE) Permite a entrada de dados a partir do porta-cartões, armazenando o valor lido na gaveta especificada (EE). Isso é fundamental para interações com o usuário ou inicialização de dados.
8EE (Escreva cEE no dispositivo de saída) Realiza a saída de dados para a folha de saída, utilizando o valor armazenado em uma gaveta específica (cEE). Isso permite a exibição dos dados.
Controle de Programa
000 (Fim do programa) Indica o encerramento do estado de CARGA e início do estado de EXECUÇÃO e quando executado encerra o programa, sinalizando que a execução deve ser interrompida. Essa instrução é essencial para marcar o término do código executável.
Conceitos Essenciais
Entrada e Saída
No computador hipotético HV as operações de entrada são realizadas através de um de seus componentes: o porta-cartões.
Ao executar uma instrução de leitura (7EE), o operador do sistema irá verificar se há nele algum cartão contendo informação, a fim de armazená-lo na gaveta indicada. Caso o CHICO não encontre um cartão em sua busca, a execução do código será interrompida e prosseguirá apenas quando o usuário inserir um novo dado no porta-cartões.
Por também ser o componente no qual o código a ser executado é armazenado, é possível inserir cartões contendo dados a serem utilizados no programa antes de sua execução ao se colocar números após a instrução de final de programa (000). Neste cenário, a instrução de leitura não pediria a inserção de dado pelo usuário, visto que o operador do sistema encontraria já um cartão para guardar.
Enquanto isso, a Folha de Saída, outro componente do HV, é responsável por imprimir os dados armazenados em uma gaveta específica, esta indicada pela instrução de escrita (8EE).
730 ; Leitura de cartão para gaveta 30
830 ; Escrita da gaveta 30 para folha de saída
000 ; Fim do programa
2 ; Dado a ser lido pela instrução
Variáveis
Na linguagem de máquina do HV, o conceito de variáveis é abordado de forma diferente do que estamos acostumados em linguagens de alto nível. Nessa linguagem, não há uma representação direta de variáveis, e os dados são armazenados em gavetas identificadas por endereços específicos. Para atribuir valores às "variáveis" do seu programa, é necessário escolher um endereço de gaveta e utilizar instruções apropriadas.
Considere o seguinte código em Python com três variáveis
x=5y=5result=x+yprint(result)
Para obter o mesmo resultado na linguagem de máquina do HV, escolhemos três gavetas, representadas por endereços 30, 31 e 32, respectivamente, para x, y e result. Iniciaremos as "variáveis" durante a leitura do porta-cartões, colocando valores após a instrução 000.
Desta forma, durante o estado de carga, esses valores não serão carregados no gaveteiro, garantindo que a leitura com a instrução 7EE atribua corretamente os valores às "variáveis".
730 ; Leitura do porta-cartões para gaveta 30 (x)
731 ; Leitura do porta-cartões para gaveta 31 (y)
030 ; Coloca o valor da gaveta 30 (x) no acumulador
231 ; Realiza a adição do valor da gaveta 31 (y) ao acumulador
132 ; Copia o valor do acumulador para gaveta 32 (result)
832 ; Imprime na folha de saída o valor da gaveta 32 (result)
000 ; Fim do programa
5 ; Valor 5 no porta-cartões para leitura na gaveta 30
5 ; Valor 5 no porta-cartões para leitura na gaveta 31
Desvio
Dentre as funções básicas que o operador do sistema é capaz de realizar, sem dúvidas as instruções de controle de fluxo são umas das que mais abrem possibilidades ao programador para o desenvolvimento de programas mais complexos.
A instrução 6EE, por exemplo, pode ser utilizada para construir um programa onde determinada parte do código só é executada caso alguma condição específica seja atendida.
A tomada de decisões com base apenas em verificar se o valor do acumulador é maior que zero parece limitada à primeira vista, mas lembre-se que esse pode ser manipulado de diversas maneiras, se tornando possível, desse modo, realizar praticamente qualquer comparação desejada.
Laços de repetição
Ao fazer o desvio para uma gaveta anterior, é possível a criação de um laço de repetição, ou seja, um pedaço do código que é executado diversas vezes.
As instruções de desvio podem também ser utilizadas para a construção de laços de repetição. Um mesmo pedaço de código pode ser executado diversas vezes ao colocarmos como alvo do desvio um endereço de gaveta anterior ao atual marcado pelo EPI, atribuindo um novo valor a este condizente com a estrutura do laço montado.
O uso da instrução de desvio condicional garante uma gama de opções para quem programa, tornando-o capaz de criar blocos de código que executarão até que determinada condição seja atingida ou mesmo por um número pré-determinado de vezes, entre outras aplicações.
Essas possibilidades aumentam muito o escopo de programas que podem ser desenvolvidos na linguagem HV, e criam novos desafios para os seus programadores.
Exemplos práticos
A seguir serão demonstradas operações comuns na elaboração de algoritmos, sendo representadas como seu equivalente para o HV. Os exemplos seguem as limitações da linguagem, e incentivam o seu raciocínio.
Operações matemáticas
Diferente das operações aritméticas primordias que a linguagem dispõe de instruções para realizá-las, neste tópico estamos interessados em realizar cálculos que usam destas operações para nos fornecer outros resultados.
Resto da divisão
Neste algoritmo, queremos calcular o resto da divisão entre dois números fornecidos pelo usuário. Chamaremos esses números de A e B, armazenando-os nas gavetas 30 e 31, respectivamente.
O resultado do resto da divisão será guardado na gaveta 32.
Uma coisa importante a se notar é que numa linguagem de alto nível teríamos um operador "%" para fazer cálculo do resto da divisão, operador esse que não temos na linguagem de máquina do HV.
Passos do algoritmo
Pegamos dois números do usuário, armazenamos A na gaveta 30 e B na gaveta 31.
Se B for 0, o resto será 0.
Enquanto o resto for maior ou igual a B, subtraímos B repetidamente.
Quando não for mais possível subtrair, o valor restante será o resto da divisão, armazenado na gaveta 32.
730 ; Leia o valor de A e armazene na gaveta 30
731 ; Leia o valor de B e armazene na gaveta 31
030 ; Carregue o valor de A no acumulador
132 ; Armazene o valor de A na gaveta 32 (resto)
031 ; Carregue o valor de B no acumulador
332 ; Subtraia o valor de resto (gaveta 32)
611 ; Se o resultado for maior que 0, vá para a gaveta 11 (continua o loop)
032 ; Carregue o valor de resto
331 ; Subtraia B do resto
132 ; Armazene o novo valor do resto
904 ; Volte para a gaveta 04 (repete a verificação)
832 ; Escreva o valor final do resto na saída
000 ; Fim do programa
Máximo entre dois números
Neste algoritmo, queremos encontrar o maior entre dois números informados pelo usuário.
Em linguagens de alto nível, podemos usar funções como max(a, b), mas na linguagem de máquina do HV precisamos implementar essa lógica manualmente.
Passos do algoritmo
Ler os dois números do usuário e armazená-los nas gavetas 10 e 11.
Carregar o primeiro número no acumulador.
Subtrair o segundo número.
Se o resultado for maior que zero, significa que o primeiro número é maior, então o imprimimos.
Caso contrário, imprimimos o segundo número.
710 ; Leia o primeiro número e armazene na gaveta 10
711 ; Leia o segundo número e armazene na gaveta 11
010 ; Carregue o valor da gaveta 10 no acumulador
311 ; Subtraia o valor da gaveta 11 do acumulador
607 ; Se o acumulador for maior que 0, vá para a gaveta 07 (imprime A)
811 ; Escreva o valor da gaveta 11 (B, pois A não era maior)
908 ; Vá para a gaveta 08 (fim do programa)
810 ; Escreva o valor da gaveta 10 (A, pois era maior)
000 ; Fim do programa
Raíz quadrada
Este algoritmo calcula a raiz quadrada inteira de um número fornecido pelo usuário.
Em linguagens de alto nível, podemos usar a função math.sqrt(A), mas na linguagem HV não temos essa operação. Em vez disso, precisamos implementá-la manualmente através de uma abordagem de “força bruta”, testando todos os resultados possíveis até encontrar o correto.
Devido às limitações do HV, só é possível obter o resultado para números menores que 1000 e que possuam raiz inteira. Para números que não seguem esses critérios o código gerará valores imprecisos ou mensagens de erro.
Passos do algoritmo
Leitura de um valor de entrada;
Inicialização de um contador que será incrementado em 1 a cada repetição;
Cálculo do quadrado do valor atual do contador;
Comparação entre o quadrado do contador e o valor de entrada fornecido;
Caso sejam iguais, o programa imprime o valor do contador e encerra;
Caso sejam diferentes, o contador é incrementado e voltamos ao passo 3.
730 ; Armazenamento do número fornecido na gaveta 30
0-1 ; Carrega número 1 no acumulador
151 ; Salva o número 1 na gaveta 51, para ser utilizado como incrementador
0-0 ; Carrega número 0 no acumulador
150 ; Salva o número 0 na gaveta 50, que será utilizada como um contador
050 ; Carrega o valor do nosso contador no acumulador
450 ; Multiplica o valor do nosso contador com ele mesmo, obtendo seu quadrado
152 ; Salva o resultado da multiplicação na gaveta 52
050 ; Carrega o valor da gaveta 50 para o acumulador novamente
251 ; Soma o acumulador com o valor 1, que estava armazenado na gaveta 51
150 ; Salva o valor calculado na gaveta 50
030 ; Carrega o valor anteriormente fornecido pelo usuário no acumulador
352 ; Subtrai do acumulador o conteúdo da gaveta 52
605 ; Se o resultado for menor que 0, a execução volta para a gaveta 05
050 ; Carrega o valor da gaveta 50 para o acumulador
351 ; Subtrai 1 do valor do acumulador, para ajustar o resultado final
153 ; Carrega o valor do acumulador para a gaveta 53
853 ; Imprime na folha de saída o resultado final obtido
000 ; Encerra o programa
Operações de comparação
Neste conjunto de algoritmos, queremos verificar relações entre dois números informados pelo usuário, como igualdade, diferença e comparações de maior ou menor.
Em linguagens de alto nível, podemos usar operadores como
==
(igualdade);
!=
(diferente);
>
(maior que);
<
(menor que);
>=
(maior ou igual a);
<=
(menor ou igual a).
No HV, precisamos implementar essa lógica manualmente usando operações de subtração e desvios condicionais.
Igualdade
Este algoritmo verifica se dois números são iguais. Ele lê os valores do usuário, subtrai um do outro e verifica se a diferença é zero. Se for, imprime 1, indicando que os números são iguais. Caso contrário, imprime 0.
720 ; Leia o primeiro número e armazene na gaveta 20
721 ; Leia o segundo número e armazene na gaveta 21
0-0 ; Carregue 0 no acumulador
122 ; Armazene 0 na gaveta 22 (resultado inicial)
020 ; Carregue A no acumulador
321 ; Subtraia B do acumulador
612 ; Se o resultado for maior que 0, vá para a gaveta 12 (A != B)
021 ; Carregue B no acumulador
320 ; Subtraia A do acumulador
612 ; Se o resultado for maior que 0, vá para a gaveta 12 (A != B)
0-1 ; Carregue 1 no acumulador (A == B)
122 ; Armazene 1 na gaveta 22
822 ; Escreva o resultado (1 se A == B, 0 caso contrário)
000 ; Fim do programa
Diferente
Aqui verificamos se dois números são diferentes. O processo é semelhante ao da igualdade, mas invertemos a lógica: se a subtração resultar em zero, significa que os números são iguais, então imprimimos 0; caso contrário, imprimimos 1.
720 ; Leia o primeiro número e armazene na gaveta 20
721 ; Leia o segundo número e armazene na gaveta 21
0-1 ; Carregue 1 no acumulador
122 ; Armazene 1 na gaveta 22 (resultado inicial)
020 ; Carregue A no acumulador
321 ; Subtraia B do acumulador
612 ; Se o resultado for maior que 0, vá para a gaveta 12 (A != B)
021 ; Carregue B no acumulador
320 ; Subtraia A do acumulador
612 ; Se o resultado for maior que 0, vá para a gaveta 12 (A != B)
0-0 ; Carregue 0 no acumulador (A == B)
122 ; Armazene 0 na gaveta 22
822 ; Escreva o resultado (1 se A != B, 0 caso contrário)
000 ; Fim do programa
Maior que
Este algoritmo determina se um número é maior que o outro. Ele subtrai B de A e verifica se o resultado é positivo. Se for, significa que A é maior, então imprimimos 1. Caso contrário, imprimimos 0.
720 ; Leia o primeiro número e armazene na gaveta 20
721 ; Leia o segundo número e armazene na gaveta 21
0-0 ; Carregue 0 no acumulador
122 ; Armazene 0 na gaveta 22 (resultado inicial)
020 ; Carregue A no acumulador
321 ; Subtraia B do acumulador
608 ; Se A > B, vá para a gaveta 08
910 ; Vá para o final do programa
0-1 ; Carregue 1 no acumulador
122 ; Armazene 1 na gaveta 22
822 ; Escreva o resultado
000 ; Fim do programa
Menor que
Aqui verificamos se A é menor que B. O processo é semelhante ao de "maior que", mas subtraímos A de B. Se o resultado for positivo, significa que A é menor, então imprimimos 1. Caso contrário, imprimimos 0.
720 ; Leia o primeiro número e armazene na gaveta 20
721 ; Leia o segundo número e armazene na gaveta 21
0-0 ; Carregue 0 no acumulador
122 ; Armazene 0 na gaveta 22 (resultado inicial)
021 ; Carregue B no acumulador
320 ; Subtraia A do acumulador
608 ; Se B > A, vá para a gaveta 08
910 ; Vá para o final do programa
0-1 ; Carregue 1 no acumulador
122 ; Armazene 1 na gaveta 22
822 ; Escreva o resultado
000 ; Fim do programa
Maior ou igual
Este algoritmo verifica se A é maior ou igual a B. Ele combina as lógicas de "maior que" e "igualdade". Se A for maior que B ou se os dois números forem iguais, imprimimos 1; caso contrário, imprimimos 0.
720 ; Leia o primeiro número e armazene na gaveta 20
721 ; Leia o segundo número e armazene na gaveta 21
0-0 ; Carregue 0 no acumulador
122 ; Armazene 0 na gaveta 22 (resultado inicial)
020 ; Carregue A no acumulador
321 ; Subtraia B do acumulador
613 ; Se A >= B, vá para a gaveta 13
020 ; Carregue A no acumulador
321 ; Subtraia B do acumulador
615 ; Se A == B, vá para a gaveta 15
021 ; Carregue B no acumulador
320 ; Subtraia A do acumulador
615 ; Se B == A, vá para a gaveta 15
0-1 ; Carregue 1 no acumulador
122 ; Armazene 1 na gaveta 22
822 ; Escreva o resultado
000 ; Fim do programa
Menor ou igual
Semelhante ao caso anterior, mas verificamos se A é menor ou igual a B. Se A for menor que B ou se forem iguais, imprimimos 1; caso contrário, imprimimos 0.
720 ; Leia o primeiro número e armazene na gaveta 20
721 ; Leia o segundo número e armazene na gaveta 21
0-0 ; Carregue 0 no acumulador
122 ; Armazene 0 na gaveta 22 (resultado inicial)
021 ; Carregue B no acumulador
320 ; Subtraia A do acumulador
613 ; Se B >= A, vá para a gaveta 13
020 ; Carregue A no acumulador
321 ; Subtraia B do acumulador
615 ; Se A == B, vá para a gaveta 15
021 ; Carregue B no acumulador
320 ; Subtraia A do acumulador
615 ; Se B == A, vá para a gaveta 15
0-1 ; Carregue 1 no acumulador
122 ; Armazene 1 na gaveta 22
822 ; Escreva o resultado
000 ; Fim do programa