Jump to content

  • Log In with Google      Sign In   
  • Create Account






So I was bored and this happened..

Posted by Bacterius, 29 June 2013 · 539 views

Hello,
I couldn't get to sleep tonight (it's 6 in the morning) so I did what all software developers do when idle - I created an assembly language. No, really, I wanted to try my hand at creating some sort of toy interpreted assembly prototype for a while now.

So, without further ado, behold the next trendy programming language, aptly codenamed "asm"! Posted Image

here be dragons

WORDSIZE 32
REGISTER 3

; Calculates the GCD of two integers

@start
	; Pop arguments off the stack (we know how many we expect)
	; Now R0 and R1 contain the two arguments (in correct order)
	POP R1
	POP R0
	JMP loop

@loop
	; If R1 is zero, we're done and gcd is R0
	CMP R1 0
	EQL end

	; Else do standard operation
	MOV R2 R1
	MOV R1 R0
	MOD R1 R2
	MOV R0 R2
	JMP loop

@end
	; Clear the stack
	CLR

	PUSH 1  ; Size of output array (a single integer)
	PUSH R0 ; The GCD of the two inputs
	RET     ; We're done!

WORDSIZE 32
REGISTER 4

; Outputs the first N terms of the Fibonacci sequence

@start
	; Pop arguments off the stack (we read the number of elements desired)
	; Now R0 contains the number of Fibonnaci elements desired
	POP R0

	; Initialize R1 and R2 to the Fibonnaci sequence
	MOV R1 0
	MOV R2 1

	; Push the counter as the stack output size
	CLR
	PUSH R0

	JMP head

; This just takes care of outputting the first two terms if necessary
@head
	; If we are asked for zero terms.. make it so
	CMP R0 0
	EQL end

	; Output the first term
	PUSH R1
	DEC R0

	; Do we want the second term?
	CMP R0 0
	EQL end

	; Output the second term
	PUSH R2
	DEC R0

	; Begin main loop
	JMP loop

@loop
	; If R0 is zero, we've got all the terms we required
	CMP R0 0
	EQL end

	; Else, we need one more Fibonnaci term - calculate it in R3
	MOV R3 R1
	ADD R3 R2 ; R3 is now equal to R1 + R2 (the next term)
	MOV R1 R2
	MOV R2 R3 ; Shift down the two elements

	PUSH R2  ; Output the new term to the stack

	DEC R0
	JMP loop ; Next term!

@end
	RET ; Nothing else to do here, we've streamed out the outputs
WORDSIZE 32
REGISTER 3

; Adds a list of numbers passed as argument

@start
	CNT R0 ; Get the number of input elements
	MOV R1 0 ; R1 will contain the sum

	JMP loop ; Start processing

@loop
	; If R0 is zero, we've added all the numbers
	CMP R0 0
	EQL end

	; Else pop the integer and add it
	POP R2
	ADD R1 R2

	; Next element
	DEC R0
	JMP loop

@end
	CLR

	PUSH 1
	PUSH R1
	RET

And the best thing is that it actually works! This prints out the first seven Fibonacci terms:
$ ./bin/asm fibonacci.asm 7
0
1
1
2
3
5
8
The parsing and interpreting code is absolutely horrible, though, it started out nice but stuff got out of control after adding the third instruction type. It should be pretty easy to write the code elegantly, especially in C++ (yes, I am also suicidal and wrote the parser in C)

Anyway, the input format is basically, the first stack word is an integer representing the number of input words, those input words are then pushed on the stack. So for the Fibonnaci example, the stack upon running the program looks like this:

[1] [7] [...]

And the output format is very much the same, except the program basically erases the stack and outputs its stuff there. So after returning, it looks like this:

[7] [0] [1] [1] [2] [3] [5] [8] [...]

Yes, it's not very convenient, but you need to start somewhere right? It'll probably need an input and output stream distinct from the actual stack eventually.

Also, the POP instruction will segfault if the stack is empty, and the stack is assumed to be infinite when really, it's limited to 1024 words because I needed an arbitrary limit (later it will need to grow dynamically). The language also supports arbitrarily many registers (defined by the REGISTER keyword at the top - WORDSIZE is supposed to indicate the word size of the registers in bits but they are always 32 bits wide at the moment)

Ultimately my goal is to have some sort of prototyping language between assembly and C that I can use to play with algorithms and stuff and get valuable behavioural info (e.g. highest stack/heap usage achieved, instruction parallelism level, etc..) which would be otherwise difficult to obtain via the x86 instruction set or other (though I suppose tools already exist for this, but whatever, this is for fun too)

I have to say it's pretty thrilling to actually create some sort of parser/compiler that takes your programs and makes them work somehow. Now I know why people are so interested in designing languages.. they are turned on by compilers! Anyway, that's it for tonight.
By the way, feel free to voice your disgust at the misshapen horror I have just brought into existence Posted Image




While this is fairly interesting, do you have a way to apply this to a game or games?

Navyman: not really smile.png as you may have noticed, most of what I do isn't about game development. It's just a toy assembly programming language, an experiment of some sorts. I like how a few simple instructions and logic are enough to write working programs.

 

Though I suppose it could run minecraft, eventually..

August 2014 »

S M T W T F S
     12
3456789
10111213141516
171819 20 212223
24252627282930
31      

Recent Entries

Recent Comments

PARTNERS