# Little Man Computer

O Little Man Computer (LMC) é um modelo didático de um computador, criado pelo Dr. Stuart Madnick em 1965. O LMC é geralmente usado para ensinar estudantes, porque ele modela um computador simples da arquitetura de von Neumann - que possui todas as características básicas de um computador moderno. Ele pode ser programado em máquina (embora frequentemente o seja em decimal) ou em código assembly.

## Arquitetura de sistema

O modelo LMC é baseado no conceito de um homenzinho trancado em uma sala pequena. No fim da sala, há 100 caixas de correio (memória), numeradas de 0 a 99, que podem conter em cada uma uma instrução de 3 dígitos ou dados (no intervalo de 000 a 999). Há ainda duas caixas de correio na outra extremidade, etiquetadas INBOX e OUTBOX, que são usados para recebimento e saída de dados. No centro da sala, há uma área de trabalho contendo uma calculadora de duas funções simples (adição e subtração) conhecida como o Accumulator e um contador reprogramável conhecido como o Program Counter. O Program Counter mantém o endereço da próxima instrução que o Little Man empregará. Este Program Counter é normalmente incrementado em 1 após cada instrução executada, permitindo ao Little Man executar um programa sequencialmente. Instruções de desvios permitem iteração (loops) e estruturas programáveis condicionais para serem incorporadas dentro de um programa. Isto obtido pela configuração o Program Counter para um endereço de memória não-sequencial se uma condição particular é verificada (tipicamente o valor armazenado no acumulador sendo zero ou positivo). Como especificado pela arquitetura de von Neumann, a memória contém ambos, instruções e dados. Cuidado precisa ser tomado para impedir o Program Counter de atingir um endereço de memória contendo dados ou o Little Man aceitará tratar isso como uma instrução. Para usar o LMC, o usuário carrega dados dentro das caixas de correio e então sinaliza para o Little Man começar a execução, começando com a instrução armazenada no endereço de memória zero. Reprogramando o Program Counter para zero efetivamente reiniciará o programa.

## Ciclo de execução

Para executar um programa, o Little Man realiza estes passos:
* checar o Program Counter para o número da caixa de correio que contém uma instrução de programa (ex: zero)
* fetch a instrução da caixa de correio com este número
* incrementar o Program Counter (desta forma ele contém o número da caixa de correio da próxima instrução)
* decodificar a instrução (inclui encontrar o número da caixa de correio para o dado it will work on) (say it says obter dado da caixa 42)
* fetch o dado da caixa de correio com o número encontrado na etapa anterior (por exemplo, armazenar o dado no Accumulator)
* executar a instrução
* armazenar o novo dado na caixa de correio da qual o antigo dado foi retrieved
* repetir o ciclo ou halt

## Comandos

Enquanto o LMC reflete os trabalhos atuais dos processadores binários, a simplicidade dos números decimais foi escolhido para minimizar a complexidade para estudantes que não se sentem confortáveis trabalhando em binário/hexadecimal.

### Instruções

Cada instrução LMC é um número decimal de 3 dígitos. O primeiro dígito representa o comando a ser trabalhado e os dois dígitos finais representam o endereço da caixa de correio afetada pelo comando.
Instructions :
| Código numérico | Código mnemônico | Instrução | Descrição |
| 1xx | ADD | ADD | Adiciona o valor armazenado na caixa de correio xx to whatever valor está atualmente no acumulador (calculadora). Nota: o conteúdo da caixa de correio não é alterado, e as ações do acumulador (calculadora) não são definidas para instruções add o que causa sums maiores que 3 dígitos. |
| 2xx | SUB | SUBTRACT | Subtrai o valor armazenado na caixa de correio xx do whatever valor está atualmente no acumulador (calculadora). Nota: o conteúdo da caixa de correio não é alterado, e as ações do acumulador não são definidas para instruções de subtração o que causa resultados negativos - contudo, um flag negativo será configurado desse modo 8xx (BRP) e pode ser usado propriamente. |
| 3xx | STA | STORE | Armazena o conteúdo do acumulador na caixa de correio xx (destrutivo). Nota: o conteúdo do acumulador (calculadora) não é alterado (não-destrutivo), mas o conteúdo da caixa de correio é replaced regardless do qual estava ali (destrutivo) |
| 5xx | LDA | LOAD | Carrega o valor da caixa de correio xx (não-destrutivo) e entra no acumulador (destrutivo). |
| 6xx | BRA | BRANCH (incondicional) | Configura o contador do programa para o endereço dado (valor xx). Isto é, valor xx será a próxima instrução executada. |
| 7xx | BRZ | BRANCH IF ZERO (condicional) | Se o acumulador (calculadora) contém o valor 000, configura o contador do programa para o valor xx. Otherwise, não faz nada. Nota: desde que o programa é armazenado na memória, dados e instruções do programa, todos têm o mesmo formato de endereço/localização. |
| 8xx | BRP | BRANCH IF POSITIVE (condicional) | Se o acumulador (calculadora) é 0 ou positivo, configura o contador do programa para o valor xx. Otherwise, não faz nada. Nota: desde que o programa é armazenado na memória, dados e instruções do programa, todos têm o mesmo formato de endereço/localização. |
| 901 | INP | INPUT | Vai para o INBOX, fetch o valor do usuário, e põe ele no acumulador (calculadora). Nota: isto sobrescreverá whatever valor que estava no acumulador (destrutivo). |
| 902 | OUT | OUTPUT | Copia o valor do acumulador (calculadora) para o OUTBOX. Nota: o conteúdo do acumulador não é alterado (não-destrutivo). |
| 000 | HLT/COB | HALT/COFFEE BREAK | Interrompe o trabalho. |
| | DAT | DATA | Esta é uma instrução assembly que simplesmente carrega o valor dentro da próxima caixa de correio disponível. DAT pode também ser usado em conjunção com etiquetas para declarar variáveis. Por exemplo, DAT 984 armazenará o valor 984 dentro de uma caixa de correio. |

### Exemplos
#### Numérico

Este programa (instrução 901 para instrução 000) é escrito apenas utilizando códigos numéricos. O programa toma dois números como entrada e como saída a diferença. Informado que a execução começa na caixa de correio 00 e termina na caixa de correio 07. As desvantagens desta forma de programação em linguagem de máquina são discutidas abaixo.
| Caixa de correio | Código numérico | Operação | Comentários |
| 00 | 901 | INBOX --> ACCUMULATOR | ENTRA o primeiro número, entra para a calculadora (apagando whatever estava ali) |
| 01 | 308 | ACCUMULATOR --> MEMORY[08] | ARMAZENA o valor atual da calculadora (para preparar para o próximo passo...) |
| 02 | 901 | INBOX --> ACCUMULATOR | ENTRA o segundo número, entra para a calculadora (apagando whatever estava ali) |
| 03 | 309 | ACCUMULATOR --> MEMORY[09] | ARMAZENA o valor atual da calculadora (novamente, para preparar para o próximo passo...) |
| 04 | 508 | MEMORY[08] --> ACCUMULATOR | (Agora que ambos os valores de ENTRADA são ARMAZENADOS nas caixas de correio 08 e 09...) CARREGA o primeiro valor de volta para a calculadora (apagando whatever estava ali) |
| 05 | 209 | ACCUMULATOR = ACCUMULATOR - MEMORY[09] | SUBTRAI o segundo número do valor atual da calculadora (que já configurou o primeiro número) |
| 06 | 902 | ACCUMULATOR --> OUTBOX | OBTÉM o resultado da calculadora para o OUTBOX |
| 07 | 000 | (nenhuma operação realizada) | HALT o LMC |

#### Mnemônica

A conveniência da mnemônica é fabricada apparent da versão da linguagem assembly do mesmo programa mostrado abaixo - o programador não é muito exigido para memorizar uma configuração de códigos numéricos anônimos, e pode agora programar com uma configuração de mais códigos mnemônicos memoráveis (este exemplo também usa etiquetas como um further aid para programação).
    Este exemplo de programa pode ser compilado e executar no simulador LMC disponível no site da Universidade de York (Toronto, Canadá) ou Mike Coley. Todos estes simuladores incluem instruções completas e programas sample, compiladores para converter o assembly em linguagem de máquina, controlar interfaces para executar e monitorar programas, e descrição detalhada passo-a-passo de cada instrução LMC.

## Etiquetas

Sem etiquetas, o programador é exigido para manualmente guardar track das locações de caixa de correio (memória). No exemplo numérico, se uma nova instrução estava para ser inserida antes da instrução HLT final então esta instrução HLT poderia se mover do endereço 07 para o endereço 08 (endereço labeling começa na locação de endereço 00). Suppose o usuário entrou 600 como a primeira entrada. A instrução 308 poderia significar que este valor poderia ser armazenado na locação de endereço 08 e sobrescrever a instrução (HLT) 000. Desde que 600 significa "saltar para o endereço da caixa de correio 00", o programa, instead de halting, poderia obter stuck em um laço sem fim.
Trabalhar around esta dificuldade, muitas linguagens assembly (incluindo o LMC) permitem o uso de etiquetas. Uma etiqueta é simplesmente uma palavra que é usada to either nome em um endereço de memória onde uma instrução ou dado é armazenada, ou para se referir para este endereço em uma instrução.
Quando um programa é assembled.
* Uma etiqueta para a esquerda de uma instrução mnemônica é convertida para o endereço de memória, a instrução ou dado é armazenada ali.
* Uma etiqueta para a direita de uma instrução mnemônica toma o valor de um endereço de memória referido abaixo.
No exemplo da linguagem assembly que usa mnemônica e etiquetas, se uma nova instrução foi inserida antes da instrução HLT final então a locação de endereço etiquetada FIRST poderia agora estar na locação de memória 09 rather than 08 e a instrução STA FIRST poderia ser convertida para 309 (STA 09) rather than 308 (STA 08) quando o programa foi assembled.
Etiquetas são, portanto, usadas para:
* identificar uma instrução particular como um alvo para uma instrução de salto
* identificar uma locação de memória como uma variável nomeada (usando DAT) e opcionalmente carregar dados no programa na vez do assembly para uso pelo programa (este uso não é óbvio até um considerar que não meio de adicionar 1 ao contador. Um poderia perguntar ao usuário para entrar 1 no início, mas isso poderia ser melhor para ter carregado isso na vez do assembly)

### Exemplo

Este programa tomará uma entrada do usuário, e contará regressivamente até zero.
Este programa tomará uma entrada do usuário, square ela, sai a resposta e então repetir. Entrando em um zero o programa terminará. (Nota: uma entrada que resulta em uma saída maior que 999 causará um erro devido o limite de 3 dígitos do LMC).
(Nota: DAT's default para o valor 0 porque o valor default em todas as locações de memória no Little Man Computer é 0, e dessa forma não precisa ser configurado a 0 - algum outro número, contudo, deve ser especificado.)
lmc = true