Speaking of assembly languages, I'm designing a stack-oriented, pseudo-object-oriented* assembly language. It looks like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
[import cstdio]
sal.examples.hello_world:
[readonly]
.message: ascii "hello, world"
.length: byte 12
[readwrite]
.variable: word 65535
[execute]
.init:
return
.exit:
return
.main:
stack.push .message
call libc.printf
stack.cmp 0
..eq:
stack.push 0
return
..ne:
stack.push 1
return
|
Every program consists of one or more pseudo-classes** like the one above, each with an optional 'init' and 'exit' function, with exactly one 'main' function per program. The 8 byte offsets of all the 'init' and 'exit' functions are in the executable header followed by the address of the main function. The processor loads and runs all of the init functions (the order is probably the same as the order in which they appear in the file(s), but that can't be relied upon) and then runs the main function. When that's done, it runs all the exit functions (again, the order can't be relied upon). All you can be sure of is that all the init functions will run before the main function which will be run in order (unless it's pipelined, but I have no idea how that works) followed by all the exit functions. init and exit functions can't call any external functions (because that might introduce circular dependencies). Code in the [readonly] and [readwrite] sections cannot be executed and code in the [readonly] and [execute] sections cannot be written to. The assembler will re-organise the program so that all the sections are together (code first, with read-only and read-write data at the very end), and mark each section with a flags byte. Three of the bits will be read/write/execute (like UNIX file permissions) and the other 5 will be reserved for now.
I want to have built-in thread synchronisation primitives as well, such as a prefix for an "atomic" block (every single instruction will be atomic but there will be an "atomic" instruction to stop the processor changing threads until an "endatomic" instruction is encountered).
* in that it looks like object-oriented code, but it's not, because you can't create objects at runtime.
** in that they're more like nested namespaces than classes.