Skip to content
Snippets Groups Projects
Commit 3750ea4b authored by Robert Grancsa's avatar Robert Grancsa
Browse files

Finalized readme


Signed-off-by: default avatarRobert Grancsa <robert.grancsa2002@gmail.com>
parent e1a92ba7
No related branches found
No related tags found
No related merge requests found
transpiler
*.o
*.out
\ No newline at end of file
*.out
*.valgrind
\ No newline at end of file
......@@ -3,6 +3,9 @@ all: build
build:
cd src && make
pack:
cd src && zip ../Tema_1_Mihai_Popescu_312CA.zip *.c *.h Makefile
clean:
cd src && make clean
rm -rf transpiler
# Homework 1
# Homework 1
## Assignment: Simple C-to-Assembly Compiler
**Deadline soft**: 4 aprilie 2025, 11:55PM
**Deadline hard**: 9 aprilie 2025, 11:55PM
**Responsabili**
* Robert Grancsa
* Adelina Alexe
## Introduction
![](banner.webp)
In a neon-lit room filled with vintage circuit boards and digital memes, Alex—a modern TikTok brain rot specialist—devised a daring plan to escape Instagram’s endless scroll. Determined to reclaim his mind, he crafted a groundbreaking compiler that transformed addictive algorithms into streams of artful data. With every line of code, toxic noise became immersive stories, intricate music, and thought-provoking visuals, forging a digital sanctuary where creativity reigned. As the algorithmic chains broke, Alex emerged as a quiet revolutionary—a cyber alchemist turning the toxic into transcendent.
### Objective
Develop a small compiler or translator that converts simple C-like code snippets into basic assembly instructions. The primary goal is to familiarize yourself with assembly language mnemonics and to understand how high-level constructs map to low-level operations. This assignment is intentionally minimalistic to ease you into both assembly language and compiler design. If we actually want to be pedantic, this is actually a [transpiler](https://en.wikipedia.org/wiki/Source-to-source_compiler) implementation.
......@@ -20,14 +34,7 @@ Because we want to prevent you from having to juggle with registers and allocate
- `B``ebx`
- `C``ecx`
- `D``edx`
- For vector (array) access, use `esi` (or `edi`), e.g., if `v = [1, 2, 3]`, the base address can be represented by a label like `$vec`.
- **Array Notation:**
- Declaring an array: `v = [1, 2, 3]`
- Accessing an element: `c = v[1]` should translate into something like:
```
MOV esi, $vec ; Load the base address of the vector
MOV ecx, [esi + 4] ; Load the second element (assuming 4 bytes per element)
```
- When
- **Data types**
- We'll assume all of the data types are **4 bytes**
......@@ -66,7 +73,7 @@ The mov instructions is the simplest of all, and as the name says, it moves the
| **C Code** | **ASM Code** |
|------------ |---------------- |
| `a = a & 0xFF;` | `AND eax, 0xFF` |
| `b = a | b;` | `OR ebx, eax` |
| `b = b \| a` | `OR ebx, eax` |
| `c = a ^ c;` | `XOR ecx, eax` |
### Arithmetic operations
......@@ -93,17 +100,27 @@ You might be wondering, why only one operand? Here we have a special rule, and g
When multiplying with MUL, the multiplication will actually take EAX and source2 as the multiplication values, and set them in 2 registers -> EDX and EAX. EDX will store the higher values, and EAX the lower one, acting as a big 8 byte register, because after multiplying two 32 bit number, we might have an overflow. Looking at the table will make it a bit clearer.
Similar to MUL, DIV works with EAX as the primary operand, but it also considers EDX as part of the dividend. This means the division is performed using a 64-bit value (EDX:EAX) divided by the given divisor. The result is stored in EAX, while the remainder is placed in EDX.
| **C Code** | **ASM Code** |
|------------ |---------------- |
| `a = a * 3;` | `MUL 3` |
| `b = b * c;` | `MOV eax, ebx` |
| | `MUL ecx` |
| | `MOV ebx, eax` |
The last 3 rows represent the second operation.
| `a = a / 3;` | `MOV eax, a` |
| | `DIV 3` |
| | `MOV a, eax` |
| `b = b / c;` | `MOV eax, ebx` |
| | `DIV ecx` |
| | ` MOV ebx, eax` |
**Note**: For simplicity, we will never use eax as source2, and we will never never use the value from EDX.
If you use the *DIV* instruction with a **divisor of 0**, the processor will generate a **"Divide Error" exception**, and the program will stop if it is not handled.
Since division requires **EDX** to be set up properly, we should always **zero** it before performing DIV if we are working with unsigned values.
### Shift operations
SHL (Shift left) and SHR (Shift right) are bitwise shift instructions.
......@@ -187,24 +204,68 @@ Here's a short description of each conditional jump:
#### `for` loop
| **C Code** | **ASM Code** |
|------------- |---------------- |
| `for (a = 0; a < 10; a++) {` | `MOV eax, 0` |
| | `start_loop:` |
| | `CMP eax, 10` |
| | `JGE end_loop` |
| `// some code here` | `; some code here` |
| | `ADD eax, 1` |
| | `JMP start_loop` |
| `}` | `end_loop:` |
| **C Code** | **ASM Code** |
|------------- |---------------- |
| `for (a = 0; a < 10; a++) {` | `MOV eax, 0` |
| | `start_loop:` |
| | `CMP eax, 10` |
| | `JGE end_loop` |
| `// some code here` | `; some code here` |
| | `ADD eax, 1` |
| | `JMP start_loop` |
| `}` | `end_loop:` |
#### `while` loop
| **C Code** | **ASM Code** |
|------------- |---------------- |
| `while (b < 5) {` | `start_loop:` |
| | `CMP ebx, 5` |
| | `JGE end_loop` |
| `// some code here` | `; some code that makes b greater than or equal to 5` |
| | `JMP start_loop` |
| `}` | `end_loop:` |
\ No newline at end of file
| **C Code** | **ASM Code** |
|------------- |---------------- |
| `while (b < 5) {` | `start_loop:` |
| | `CMP ebx, 5` |
| | `JGE end_loop` |
| `// some code here` | `; some code that makes b greater than or equal to 5` |
| | `JMP start_loop` |
| `}` | `end_loop:` |
### Coding style
Coding style can be run directly in the checker, by pressing `C`, or by using the
`cs.sh` executable from `checker/cs`. The points are the folowing:
- \>= 10 of `CHECK` => -5 points
- \>= 5 of `WARNING` => -5 points
- \>= 1 of `ERROR` => -10 points
## Mentiuni
- The implementation can be done in any file, and the executable must be named
`transpiler`, situated in the root of the folder, same as the initial makefile does
- For sending the homework, you can use the `make pack` rule, which automatically creates
a zip file with the necesarry content already in it. Don't forget to change your name first
## Checker
> ! Atention, the checker doesn't run valgrind by default, but you must pass all the test
with valgrind in order to get the score. To activate valgrind on your checker, press
`v`, making sure there is a red border which will show that it is on.
### Instalation steps
You can use the `./install.sh` to install all the dependencies and the checker.
If you find any errors along this process, try to follow the steps below:
1. Download rustup using
`curl https://sh.rustup.rs -sSf | sh -s -- -y`. If you get any errors
after this step, add cargo to the PATH variable using `source "$HOME/.cargo/env"`.
2. Run the following command to install the checker
```bash
$ cargo install hw_checker
```
After install, you can use the `hw_checker` command to run the checker.
### Instructiuni checker
For a list of commands and guides for the checker, please read the README from the
`src/` directory. If you have any problems running the GUI, you can use the
`hw_checker --legacy` command to run them in text only mode.
banner.webp

531 KiB

# Checker
This checker is in it's second iteration. If you found any bugs and have features you would like me to add, or any QoL ideas, contact me and I'll try to implement them as soon as I can.
What's different from all the other checkers out there is that it uses a GUI instead of the old-school text based printing of results. It can run any test individually, it shows a diff of all the results and most importantly it will run more tasks at the same time.
**For this checker to run at max capacity, we recommend allocating more CPU cores
to your virtual machine.**
![alt-text](https://i.imgur.com/3uqwCvs.png)
## How to use the checker
Run the by using either one of these commands. You must be in the same directory
as the other checker files, otherwise it won't work. For this checker to work,
you will need a terminal of at least 52x24 (width x height).
```bash
$ ./check
$ hw_checker
# If you only want to use the text only version, add the following flag to the command
$ hw_checker --legacy
```
## Keybinds
To simplify the use of the checker, you can use the following keybinds:
- `enter` - when on a test, to run it
- `left-arrow` or `right-arrow` - switch from test window to log window
- `r` - runs all the tests from both tasks
- `f` - runs only the failed tasks that either have crashed or they got 0 points
- `v` - enables or disables valgrind globally for the tests (valgrind is enabled
when the `Tests` window is highlighted in red)
- `c` - runs the coding style checker and shows a pop-up showing all the possible problems
- `ctrl+c` or `q` - exit the program
## Source code
You can find the source code [here](https://github.com/RobertGrancsa/checker)
and the [crates.io](https://crates.io/crates/hw_checker) page here.
If you would like to contribute to the project, or open any issues, you are welcomed
to help.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment