¿Cuál es el objetivo de este proyecto con sus palabras y describa que debe hacer para desarrollarlo?
¿Cuál es el objetivo de este proyecto con sus palabras y describa que debe hacer para desarrollarlo?
El objetivo principal de esta práctica está en el correcto aprendizaje de un traductor, cuyo desarrollo se enfoca en la traducción del lenguaje Assembler.
Código General:
package com.aniruddha.nand2tetris.Assembler;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
/**
* An Assembler for the Hack computer
*/
public class Assembler {
String inputFileName;
String outputFileName;
// Symbols Table with pre-defined symbols
SymbolsTable symTable;
// Start new symbols from address 16
Integer symbolAddress = 16;
/**
* @param inputFileName
*/
public Assembler(String inputFileName) {
this.inputFileName = inputFileName;
this .outputFileName = getOutputFilename(inputFileName);
this.symTable = new SymbolsTable();
}
/**
* @param inputFileName
* @param outputFileName
*/
public Assembler(String inputFileName, String outputFileName) {
this.inputFileName = inputFileName;
this.outputFileName = outputFileName;
this.symTable = new SymbolsTable();
}
/**
* @param inputFilename
* @return outputFileName with ".hack" ext
*/
public static String getOutputFilename(String inputFilename) {
if (inputFilename.endsWith(".asm")) {
return inputFilename.replace(".asm", ".hack");
} else {
return inputFilename + ".hack";
}
}
public static void main(String[] args) throws IOException {
if (args.length != 1) {
System.out.println("Args: <file.asm>");
} else {
String inputFileName = args[0];
Assembler asm = new Assembler(inputFileName);
asm.assemble();
}
}
public void assemble() throws IOException {
this.firstPass();
this.secondPass();
}
/**
* First pass through the ".asm" file
* Identifies the memory location for label definitions
* (LABEL)
*/
public void firstPass() {
Parser parser = new Parser(this.inputFileName);
int currentAddress = 0;
while(parser.hasMoreCommands()) {
parser.advance();
if ((parser.commandType() == parser.ACOMMAND) || (parser.commandType() == parser.CCOMMAND)) {
currentAddress += 1;
} else if (parser.commandType() == parser.LCOMMAND) {
this.symTable.addSymbol(parser.symbol(), currentAddress);
}
}
}
/**
* Performs Assembly
* Generated byte code and outputs to file
* @throws IOException
*/
public void secondPass() throws IOException {
Parser parser = new Parser(this.inputFileName);
BufferedWriter bw;
bw = new BufferedWriter(new FileWriter(new File(this.outputFileName)));
while(parser.hasMoreCommands()) {
parser.advance();
if (parser.commandType() == parser.ACOMMAND) {
bw.write(Code.generateACode(this.getAddress(parser.symbol())));
bw.write("\n");
} else if (parser.commandType() == parser.CCOMMAND) {
bw.write(Code.generateCCode(parser.comp(), parser.dest(), parser.jump()));
bw.write("\n");
} else if (parser.commandType() == parser.LCOMMAND) {
continue;
}
}
bw.close();
}
/**
* @param symbol
* @return int address
*/
public int getAddress(String symbol) {
if (Utils.isNumeric(symbol)) {
return Integer.parseInt(symbol);
} else {
if (!this.symTable.contains(symbol)) {
this.symTable.addSymbol(symbol, this.symbolAddress);
this.symbolAddress += 1;
}
return this.symTable.getAddress(symbol);
}
}
}
ADD.ASM:
Cumple la función de realizar una suma con los valores 2 y 3, el resultante de esta suma se pone en R0.
Código aplicación ADD.ASM:
// Computes R0 = 2 + 3 (R0 refers to RAM[0])
//Se le da a A el valor de 2 en la direccion D
@2
D=A
//Se da ahora el 3 en la A más el valor que se tenia.
@3
D=D+A
//En la RAM0, se coloca entonces la cantidad acumulada.
@0 M=D
MAX.ASM:
Su función es realizar una búsqueda del número mayor que este entre R1 y R0. El número que encuentra lo ubica en R2.
Codigo del MAX.ASM:
// Computes R2 = max(R0, R1) (R0,R1,R2 refer to RAM[0],RAM[1],RAM[2])
@R0
D=M // D = first number
@R1
D=D-M // D = first number - second number
@OUTPUT_FIRST
D;JGT // if D>0 (first is greater) goto output_first
@R1
D=M // D = second number
@OUTPUT_D
0;JMP // goto output_d
(OUTPUT_FIRST)
@R0
D=M // D = first number
(OUTPUT_D)
@R2
M=D // M[2] = D (greatest number)
(INFINITE_LOOP)
@INFINITE_LOOP
0;JMP // infinite loop
RECT.ASM:
Dibuja un rectángulo en el lado izquierdo de la pantalla.
Codigo del rect.asm:
// Draws a rectangle at the top-left corner of the screen.
// The rectangle is 16 pixels wide and R0 pixels high.
@0
D=M
@INFINITE_LOOP
D;JLE
@counter
M=D
@SCREEN
D=A
@address
M=D
(LOOP)
@address
A=M
M=-1
@address
D=M
@32
D=D+A
@address
M=D
@counter
MD=M-1
@LOOP
D;JGT
(INFINITE_LOOP)
@INFINITE_LOOP
0;JMP
Pong.asm:
El pong es un programa elaborado en el que se implementa un juego para un solo individuo. Es un programa simbólico que no posee etiquetas, de gran extensión, no fue escrito por un humano es escrito por un ensamblador y se escribió en el lenguaje de programación Jack y el compilador Jack fue el responsable de traducirlo al programa ensamblador suministrado. El código tiene aproximadamente 27.000 líneas que pueden ser transformadas en código binario, estas líneas de código controlan al momento de que inicia el juego la pantalla y teclas del computador para que la barra que golpea la pelota pueda moverse a medida que nosotros lo solicitemos con las flechas del teclado. Se ejecuto este programa por medio del emulador de CPU por lo tanto por estas circunstancias el juego tiende a ser lento.
Bibliografia:
Schocken, S. and Nisan, N., 2021. NAND2Tetris - Project 06. [online] NAND2Tetris. Disponible en: https://www.nand2tetris.org/project06
Video: