This repository implements a comprehensive toolchain for an abstract computer system, developed to provide a foundational understanding of how compilers and emulators work. The project includes three primary components: an assembler, a linker, and an emulator, each with clearly defined functionalities.
It is a project on the course System Programming ("Sistemski Softver") on University of Belgrade, Faculty of Electrical Engineering, Module for Computer Engineering and Informatics
The assembler is a single-pass tool that translates imaginary assembly language code into machine-readable code. Here are some of the main assembly directives and symbols:
- Symbol Handling:
.global
directive exports symbols for use in other modules..extern
directive imports symbols from other modules.
- Memory Organization:
.section
directive defines new code or data sections..word
directive allocates memory and initializes it with provided values..skip
directive reserves uninitialized memory of a specified size.
- Code Translation:
- Converts assembly instructions into binary format.
- Supports instructions like
halt
,int
,call
,jmp
, and arithmetic operations such asadd
,sub
,mul
, anddiv
.
- Output Generation:
- Produces a relocatable object file in a custom ELF-inspired format.
The linker combines object files generated by the assembler into a complete executable program or relocatable output. Key functionalities include:
- Section Aggregation: Merges sections with the same name from multiple input files without overlaps.
- Memory Mapping:
- Uses
-place=<section>@<address>
to assign explicit addresses to sections.
- Uses
- Output Formats:
- Generates hexadecimal files (
-hex
option) for memory initialization. - Reports errors if symbols are undefined or sections overlap.
- Generates hexadecimal files (
The emulator executes programs generated by the linker and simulates the behavior of the abstract computer system. Key features include:
- Processor Emulation:
- Simulates a 32-bit processor with general-purpose registers, a program counter (
pc
), and a stack pointer (sp
). - Executes machine instructions atomically.
- Simulates a 32-bit processor with general-purpose registers, a program counter (
- Interrupt Handling:
- Manages hardware interrupts (e.g., timer and terminal) and software interrupts (
int
).
- Manages hardware interrupts (e.g., timer and terminal) and software interrupts (
- Program Execution:
- Reads input files in hexadecimal format, executes instructions, and halts upon encountering the
halt
instruction.
- Reads input files in hexadecimal format, executes instructions, and halts upon encountering the
- Assembly: Use the assembler to convert assembly code into an object file.
- Linking: Combine multiple object files using the linker to create a final executable.
- Execution: Run the executable on the emulator and monitor the system's behavior.
You can test the source code provided in test folder by starting start.sh in terminal