Skip to content

DKay7/stack-cpu-emulator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

32 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Stack-based processor emulator

Description

This project is a stack-based virtual CPU. It has its own assembly language, assembler, binary executable format, CPU emulator and disassembler. There is also a simple VRAM model which can print ASCII pictures to the terminal.

Small factorial example:

factorial:
    push ax
    push 1
    jbe basic_case

    push ax
    push bx
    mul                   	
    pop bx

    push ax
    push 1
    sub
    pop ax

    call factorial       
    ret             
    
    basic_case:
        ret

More examples can be found in examples/factorial/, examples/square_solver/ and examples/vram/.

What is inside

  • acc - assembler, compiles .asm files to .mc machine-code files
  • exec - CPU emulator, executes .mc files
  • disacc - disassembler, converts .mc files back to .asm
  • custom stack-based assembly language
  • stack, registers, RAM and V-RAM
  • image-to-VRAM generator script
  • command/register definitions in defines_and_setups/

Pipeline:

asm source -> assembler -> machine code -> CPU emulator
                          \
                           \-> disassembler -> asm source

Build

Clone the repo and run make:

git clone https://github.com/DKay7/stack-cpu-emulator.git
cd stack-cpu-emulator
make

This builds three executables: acc, exec and disacc.

Run examples

Compile an assembly file:

./acc ./examples/square_solver/square_solver.asm ./examples/square_solver/square_solver.mc ./examples/square_solver/square_solver.lst

Run it:

./exec ./examples/square_solver/square_solver.mc

Disassemble it back:

./disacc ./examples/square_solver/square_solver.mc output.asm

Generated .mc, .lst and output.asm files are ignored by git.

Image to VRAM

There is a small script which converts an image to an assembly program that prints it through the emulator's VRAM:

python3 ./examples/vram/ascii_generator.py

Enter the path to an image and target width in ASCII symbols. Width around 150 usually works fine for most pictures. The script creates a .asm file which can then be assembled and executed like other examples.

How does it work

CPU includes:

  1. Stack data structure
  2. Registers
  3. Random Access Memory, RAM
  4. Video Random Access Memory, V-RAM

Stack is just LIFO data structure. In this CPU it stores data of double type. Stack has no fixed size, so it can increase and decrease depending on its capacity.

Registers are fast-access memory blocks. One register can hold just one value, also of double type. Total num of registers is 24.

RAM is Random Access Memory. In real CPUs it is much slower than registers, but in this realization speeds of access to registers and to the RAM are correlated.

VRAM is just a part of RAM, which data is interpreted by CPU as ASCII characters. You can set the place where VRAM starts at RAM, how long should it be and print out VRAM data to the screen by some of the commands below.

List of available commands

  1. push value -- pushes value to stack.

    Available options:

    1.1 push reg_name -- pushes value from register

    1.2 push [value] -- pushes value from ram element, which is pointed by value.

    1.3 push [reg_name] -- same as above, but pointer stores in register.

  2. pop -- pops value out of stack

    Available options:

    1.1 pop reg_name -- pops value to register

    1.2 pop [value] -- pops value to ram element, which is pointed by value.

    1.3 pop [reg_name] -- same as above, but pointer stores in register.

  3. jmp label_name -- unconditional jump to label

  4. je label_name -- jump if two elements in stack are equal

  5. jne label_name -- jump if two elements in stack are not equal

  6. ja label_name -- jump if one element in stack are above than another

  7. jae label_name -- jump if one element in stack are above or equal than another

  8. jb label_name -- jump if one element in stack are below than another

  9. jbe label_name -- jump if one element in stack are below or equal than another

  10. call func_name -- calls a function.

  11. ret -- pops address from stack and returns from function.

  12. vrsetx value -- sets screen width.

  13. vrsety value -- sets screen height.

  14. scrupd -- updates screen (redraws it).

  15. scrclr -- clears screen buffer (not the screen).

  16. clrbuf value -- clears ram from 0 to given value.

  17. add -- adding two values from stack and pushes result back.

  18. sub -- subtracts two values from stack and pushes result back.

  19. mul -- multiplies two values from stack and pushes result back.

  20. div -- divides two values from stack and pushes result back.

  21. sqrt -- counts square root for value from stack and pushes result back.

  22. sin -- counts sine for value from stack and pushes result back.

  23. cos -- counts cosine for value from stack and pushes result back.

  24. rnd -- rounds value from stack and pushes result back.

  25. in -- takes value from the user and pushes it to the stack.

  26. out -- pops value from the stack and shows it to the user.

  27. dump -- dumps info about CPU.

  28. dumpstk -- dumps info about CPU's stack.

  29. validate -- validates CPU's stack.

  30. hlt -- terminates program.

How to add new command / register / error type

All processor commands, registers and errors are written using a small DSL based on definition headers. You can add a new command by writing a new command definition to defines_and_setups/commands_defenitions.h. New error types and registers can be added in the same style.

About

This project is a stack-based virtual CPU. It has its own assembly language, assembler, binary executable format, CPU emulator and disassembler. There is also a simple VRAM model which can print ASCII pictures to the terminal.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors