Skip to content

Bare-bones processor architecture implementation in C

Notifications You must be signed in to change notification settings

morgunovmi/processor

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

49 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Processor

Welcome to the world of my very own tiny virtual CPU!

This project consists of 3 parts: an assembler, a disassembler and a processor. Each part has its own executable, but really they are meant to be used together.

Summary

ASSembler

The assembler program reads a text file written in a custom assembly language and compiles it to a binary (compiled.jf by default) that can be then read by the CPU for execution.

Currently the following assembler commands are supported:

  • hlt - Ends program execution
  • ver - Verifies the integrity of the processor stack (only works if PROT_LEVEL > 0)
  • dmp - Dumps the info about the processor stack into a log file (only works if PROT_LEVEL > 0)
  • out - Pops a value off the stack and prints it to standard output
  • in - Reads a number from standard input and pushed it onto the stack
  • push 1 - Pushes 1 (or any number) onto the stack
  • push ax - Pushes value from the ax register onto the stack
  • push [1], push [ax], push [ax + 1] - Push values from CPU RAM onto the stack, where the RAM address is the total number value in the brackets
  • pop - Pops a value off the stack
  • pop ax - Pops a value from the stack into the ax register
  • pop [1], ... - Pops the value from the stack into RAM
  • abs - Takes the absolute value of the top stack element, and pushes it onto the stack
  • sqrt - Takes the square root of the top stack element, and pushes it onto the stack
  • add - Pops 2 values off the stack, adds them, pushes them back onto the stack, right operand is the top stack value
  • sub - Adds 2 top stack values
  • mul - Multiplies 2 top stack values
  • div - Divides 2 top stack values
  • jmp lbl - Jumps to label lbl
  • ja lbl - Jumps to label lbl if the top stack values satisfy the inequality first > second
  • jae lbl - Jumps if >=
  • jb lbl - Jumps if <
  • jbe lbl - Jumps if <=
  • je lbl - Jumps if ==
  • jne lbl - Jumps if !=
  • call func - Jumps to a function with label func, the function must have a ret in the end
  • draw - Draws lines of specified width from VRAM to standard output until \0 in is encountered
  • ret - Returns to the function call site

Labels are specified in the following form:

     jmp label
     ..
     some
     kode
     ..
     label:
        ..
        more
        kode
        ..  

The assembler ignores leading whitespaces and empty lines, so you can format your code to be more readable (just be careful not to add any extra spaces before and after command arguments or it won't compile)

You can find example .asm programs in the examples folder of the repo

DisASSembler

The disassembler program reads a binary .jf file and decompiles it into the custom assembler program with using the command set described in the ASSembler section

Processor

The processor program takes in a compiled binary .jf file and executes the program from it. The processor version must match the command set version or the processor won't work.

The processor has a dynamic stack for handling numeric values, 8 registers ax - hx for storing values, a call stack that makes nested function calls possible and a 1 MB RAM (you can change its size by recompiling with a different RAM_SIZE value)

Usage

Prerequisites

Unix based system or WSL(code written for Linux originally), git(kinda), gcc, make

You have to first compile the source code by using make in the root directory of the repo

git clone https://github.com/morgunovmi/processor && cd processor/

make && cd build/

Once you have written an assembler program you can compile it by running

./assembler program.asm

which will result in a compiled.jf binary file. You can also explicitly name the binary file with the -o flag

./assembler program.asm -o my_name_is.jf

By default this program also outputs a clean.asm file, that contains your code without extra whitespaces. And obviously your program file has to be in the same directory as the executable.

You can decompile a binary file by running

./disassembler compiled.jf
or
./disassembler compiled.jf -o bollocks.asm

You can run the compiled binary with the following command

./processor compiled.jf

ASCII stuff

Don't forget to play around with the ascii part of the examples. For full support you need ffmpeg and jp2a programs:

sudo apt update
sudo apt install jp2a
sudo apt install ffmpeg

You can use the a2asm program to turn your image into a .gasm program, current terminal dimensions are used for conversion

./a2asm img.jpeg
or explicitly
./a2asm -i img.jpeg

And finally, you can even convert your video into a .gasm program, so you can enjoy your favourite show in ascii form in your terminal(without sound for now):

./a2asm -v video.mp4

This program will output a .gasm program that you can then compile and run! sus

GLHF!, @me with errors

About

Bare-bones processor architecture implementation in C

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published