Lab 14: Vm Translator
O VMTranslator é um programa escrito em Java que faz a tradução de códigos escrito na linguagem VM definida no curso e traduz para linguagem Assembly do computador Z01.
Testando
Para testar, basta executar o comando:
$ pytest -k <nome_do_teste>
O diagrama da testagem seria:
VMTranslator Assembler Z01-Simulator ------------------
arquivo.vm -------------> .nasm -----------> .hack > ------------> - Verifica saída -
------------------
Para auxiliar, foram criados alguns programas (g_VM/src/Examples/) em VM muito específicos que testam somente um comando, ou uma parte da tradução do VMTranslator.
A seguir uma lista de como cada parte do VMTranslator é testado:
code.writePushPop- pop
- SimplePopTemp : pop temp ...
- SimplePopLocal : pop local ...
- SimplePopThat : pop that ...
- SimplePopThis : pop this ...
- push
- SimplePushConst : push constant ....
- SimplePushTemp : push tempo ....
- SimplePushLocal : push local ....
- SimplePushArg : push argument ...
- SimplePushThis : push this ...
- SimplePushThat : push that ...
- pop
- code.writeArithmetic
- SimpleAdd : add
- SimpleNeg : neg
- SimpleSub : sub
- SimpleEq : eq
- SimpleGt : gt
- SimpleLt : lt
- SimpleAnd : and
- SimpleOr : or
Implementando
Vamos agora fazer a implementação do comando push constant 3 no VMtranslator.
- Abra o projeto da mesma maneira que realizado no
Assembler- o arquivo maven está na pasta
g_VMTranslator/VMtranslator
- o arquivo maven está na pasta
Nesse projeto vocês terão que mexer apenas no Code.java, os demais módulos já estão prontos (similar ao projeto do Assembler, temos nesse o parser, VMTranslator, ...).
Editando o Code.java
No Code.java encontre a implementação do método push , linha 121
public void writePushPop(Parser.CommandType command, String segment, Integer index) {
...
...
...
else if (command == Parser.CommandType.C_PUSH) {
commands.add(String.format("; %d - PUSH %s %d", lineCode++ ,segment, index));
if (segment.equals("constant")) {
}
Essa método é chamado sempre que um comando push/pop for interpretado, exemplo:
push constant 3
Os parâmetros recebidos são:
- command:
C_PUSH - segment:
constant - Index:
3
Precisamos agora traduzir a execução desse comando em vm para nasm para que ele possa ser executado no nosso hardawre, isso é pode ser feito seguindos os passos a seguir:
- Carregar o valor da constante em um registrador disponível
- Busca no StackPointer(SP) o endereço da posição vazia da stack
- Mover o valor do Index (no caso 3) para essa posição vazia
- Incrementa SP em um
Implementando
Faça a tradução do comando push constant nnn de VM para nasm,
para cada linha nasm você deve chamar a função commands.add, como no exemplo
a seguir:
commands.add("movw %A, %D");
A tradução deve ser escrita dentro do if (segment.equals("constant")) {....}
Solução
// carrega a constant em %A e move para %D
commands.add("leaw $"+ index + ", %A");
commands.add("movw %A, %D");
// carrega o calor do SP e move a constant
// para o topo da pilha
commands.add("leaw $0,%A");
commands.add("movw (%A),%A");
commands.add("movw %D,(%A)");
// altera stack pointer: SP = SP + 1
commands.add("leaw $0,%A");
commands.add("movw (%A),%D");
commands.add("incw %D");
commands.add("movw %D, (%A)");
Para testar o projeto VMtranslator, por exemplo no caso do sub, temos o teste SimpleSub, bastando apenas executá-lo com o pytest -k.