Hello there, Alec here! This is my first post, so if you have any tips or feedback, feel free to comment!
Julia Virtualized CPU, will possibly be used for a video game I'm making. This was made as a fun little side project to learn Julia, and is not meant to be a faithful recreation of Assembly or how a CPU truly works. While it is faithful to some portions, it's not meant to be a 100% perfect virtualization. There are many limitations that I may decide to change, depending on if I feel the want to come back to this project.
The CPU has four 16-bit registers, A (accumulator), B (open register), C (count register), and D (data register). There are also three 16-bit pointers, the RP (read pointer), WP (write pointer), and SP (stack pointer). There is currently only a single interrupt, the UOI, or User Input Overflow Interrupt, which defaults to going back to the first line of code for now, may change later. The CPU…
You might be asking "Alec, why are you going on and on about a project you made three months ago and haven't updated in a month?"
Shush. For some odd reason, I unconditionally love this project despite its many, many flaws.
I created a Julia Virtual Machine (VM) to run my own custom instruction set. Why did I do this? It actually allowed me to both learn Julia and Assembly at the same time! Let's delve deeper into why this is, and how it actually greatly benefited my learning.
For Julia, I wanted some project idea as an excuse to learn Julia, as I was (and still am) very interested in the language. I was also interested in learning Assembly, but the current common languages seemed so daunting to use that I became somewhat discouraged. My virtual machine was made with myself in mind so that I could more easily learn Assembly. I knew I couldn't make it as close to something like x86 as I'd like, but a simple start is better than no start at all.
Here's a "Hello World!" example in x86 (Windows):
This example shows how to go directly to the Windows API and not link in the C Standard Library.
global _main extern _GetStdHandle@4 extern _WriteFile@20 extern _ExitProcess@4 section .text _main: ; DWORD bytes; mov ebp, esp sub esp, 4 ; hStdOut = GetstdHandle( STD_OUTPUT_HANDLE) push -11 call _GetStdHandle@4 mov ebx,
(Code pulled out from the answer)
global _main extern _GetStdHandle@4 extern _WriteFile@20 extern _ExitProcess@4 section .text _main: ; DWORD bytes; mov ebp, esp sub esp, 4 ; hStdOut = GetstdHandle( STD_OUTPUT_HANDLE) push -11 call _GetStdHandle@4 mov ebx, eax ; WriteFile( hstdOut, message, length(message), &bytes, 0); push 0 lea eax, [ebp-4] push eax push (message_end - message) push message push ebx call _WriteFile@20 ; ExitProcess(0) push 0 call _ExitProcess@4 ; never here hlt message: db 'Hello, World', 10 message_end:
And here's a "Hello World!" example in my instruction set (in the least lines):
strwrite Hello World! print 12
It's significantly simpler, isn't it? There are better ways to do it (even in my own instruction set), but this highlights very well the stark difference between the two. I tailor-made this Assembly language based on what would help me learn the most, and though there are some annoying aspects (such as the
My VM is a crappy, unoptimized mess, that I understand. It's not made to be a modern, optimized VM. It was made for me to learn Julia (and all of its quirks, like the fact that you can't set types, even if they're the same, multiple times for a variable name, EVEN IF they are in different local scopes) and Assembly at the same time. I believe it achieved its goal incredibly well and I wholeheartedly recommend other beginners to do something similar. It's a great way to learn the odd quirks of a higher-level language while simultaneously learning the concepts behind Assembly code and how you could apply it in other instruction sets and architectures.
This project, though the VM isn't really all that close to how a real CPU functions and how instruction sets work (especially on OS-level integrations), I believe it helped me grow as a programmer in both a high-level and low-level aspect. While learning Julia, I was able to easily wrap my head around Assembly in a comfortable environment. This really is the best personal project I've made (and the only I've fully completed thus far) and suggest other beginner to not follow what I did unconditionally because I'm some guy with the time to waste posting an article, but suggest they understand why I made this project and what I was thinking going into it, then use that mindset to create their own version that helps THEM learn the best.
Thank you for reading, and have an amazing day!