The first half of the course culminated in building a functional computer system by integrating the following omponents which were built during the earlier weeks:
Memory:
1. RAM16K: This is the computer's short-term memory, where data and programs are temporarily stored while the system is running.
2. Screen and Keyboard: These components interface with the user, displaying output and receiving input.
CPU (Central Processing Unit):
1. A Register: Acts as a temporary storage area for data that the CPU is currently processing. It's crucial for handling operations like calculations and data manipulation.
2. D Register: Holds the result of operations performed by the CPU, such as calculations or data fetched from memory. It ensures that the results are available for subsequent steps.
3. ALU (Arithmetic Logic Unit): Performs all the arithmetic and logical operations needed by the CPU, such as addition and comparison.
Computer System:
1. ROM32K: Stores the program code that the CPU executes. It can load programs from a file, allowing the system to perform various tasks based on the instructions given.
By combining memory, CPU, and instruction storage, I learned how each part contributes to the overall functionality of a computer- from executing programs to interacting with users.
I developed an assembler, a tool that converts programs written in Hack assembly language into binary code that the Hack hardware platform can execute.
The assembler handles two main types of instructions: A-instructions and C-instructions.
1. A-instructions (@value) are used to load a specific value or memory address into a register.
2. C-instructions define computations, such as arithmetic operations or data transfer between registers and memory.
The project was completed in two stages to ensure comprehensive functionality:
1. Symbol-less Assembler:
The first stage involved creating an assembler that could translate programs without symbols. I focused on converting A-instructions and C-instructions directly into binary code, which the Hack computer hardware understands.
2. Symbol Handling:
In the second stage, I extended the assembler to manage symbolic references. Symbols are placeholders in the code that represent memory addresses or variables. The assembler was designed to first scan the entire program, building a symbol table that records the locations of all labels (which mark positions in the code) and predefined variables. During the second pass, the assembler replaced each symbolic reference with its corresponding binary address or value, ensuring that the program could be correctly executed by the Hack hardware.
I developed an assembler, a tool that converts programs written in Hack assembly language into binary code that the Hack hardware platform can execute.
The assembler handles two main types of instructions: A-instructions and C-instructions.
1. A-instructions (@value) are used to load a specific value or memory address into a register.
2. C-instructions define computations, such as arithmetic operations or data transfer between registers and memory.
The project was completed in two stages to ensure comprehensive functionality:
1. Symbol-less Assembler:
The first stage involved creating an assembler that could translate programs without symbols. I focused on converting A-instructions and C-instructions directly into binary code, which the Hack computer hardware understands.
2. Symbol Handling:
In the second stage, I extended the assembler to manage symbolic references. Symbols are placeholders in the code that represent memory addresses or variables. The assembler was designed to first scan the entire program, building a symbol table that records the locations of all labels (which mark positions in the code) and predefined variables. During the second pass, the assembler replaced each symbolic reference with its corresponding binary address or value, ensuring that the program could be correctly executed by the Hack hardware.
In this project, I developed a compiler designed to translate high-level code written in a procedural programming language into machine-readable instructions. The project was divided into two main phases:
1. Implementing a Procedural Programming Language:
a. Variables: Managed the declaration and usage of variables within the code.
b. Expressions: Implemented the evaluation of mathematical and logical expressions.
c. Statements: Enabled the execution of various control structures, such as loops and conditionals.
2. Adding Object-Based Programming Features:
a. Objects: Introduced the ability to define and manipulate objects, allowing for more complex data structures.
b. Constructors: Implemented methods for initializing objects.
c. Methods: Enabled the definition and execution of functions tied to specific objects, enhancing the language's capabilities.
Throughout the project, I employed several key techniques to ensure the compiler's functionality:
1. Parsing: Handled the syntax analysis of the code, breaking it down into manageable components (initially provided).
2. Symbol Tables: Used to keep track of variable and function names, ensuring correct usage and scope management.
3. Compilation Engine: Responsible for the overall coordination of the translation process from high-level code to machine code.
4. Code Generation: Produced the final machine code that could be executed by a computer, ensuring that the translated code accurately represented the original source.
In this project, I developed a compiler designed to translate high-level code written in a procedural programming language into machine-readable instructions. The project was divided into two main phases:
1. Implementing a Procedural Programming Language:
a. Variables: Managed the declaration and usage of variables within the code.
b. Expressions: Implemented the evaluation of mathematical and logical expressions.
c. Statements: Enabled the execution of various control structures, such as loops and conditionals.
2. Adding Object-Based Programming Features:
a. Objects: Introduced the ability to define and manipulate objects, allowing for more complex data structures.
b. Constructors: Implemented methods for initializing objects.
c. Methods: Enabled the definition and execution of functions tied to specific objects, enhancing the language's capabilities.
Throughout the project, I employed several key techniques to ensure the compiler's functionality:
1. Parsing: Handled the syntax analysis of the code, breaking it down into manageable components (initially provided).
2. Symbol Tables: Used to keep track of variable and function names, ensuring correct usage and scope management.
3. Compilation Engine: Responsible for the overall coordination of the translation process from high-level code to machine code.
4. Code Generation: Produced the final machine code that could be executed by a computer, ensuring that the translated code accurately represented the original source.