Zero

Zero
Zero

06 junio 2012

The history of Zero

It is curious how fast time goes by. I started Zero in 2003, with the assembler and bytecode specifications, and the next year, around this dates, Zero will turn 10.

The development of Zero is not competely stopped. I still have the PROWL compiler very present, obtaining a lot more stability and portability, specially with Windows 7 (it seems that with Win7 it does not feel comfortable, in contrast to the Linux version, maybe the first example of a non-deterministic program). It is nevertheless true that the system is quite complete since a few years ago, and it has been used for the practices part of an undergraduate subject, as a multilanguage, programmable systems offering dynamicity and persistence. Students have also volunteered with exercises written in PROWL, such as polish calculator, interactive fiction, etc.

The question I have been more frequently asked during these years is about the VM's registers... why so few? The answer is that, when I designed it, I was trying to make it as minimalist as possible, and that within the reasonable, to be as simple as possible so its characteristics and registers could easily be mapped to the x86 family, with a possible JITter in mind. So, it presents the __ip, i.e., the program counter, hidden but modified by JMP, JOT and JOF; __exc holding a reference to the object describing the exception thrown. It could be used as a generic, extra register, but this would be more hacking that anything else. The accumulator, or __acc, working as in x86, since the result of any assembler opcode goes there (I was however, more romatically inspired by the Z80; this chip derives from the 8080, and that is the father of the x86 family ).

There are four general purpuse registers, abbreviated as gp: __gp1, __gp2, __gp3 and __gp4. Finally, the __rr register holds a references to the result returned by a given method. This register is of course manipulable during the method execution, provided that the it holds the final result at the end of the method (it is directly set by RET, which must be the last instruction in the method).

The programmer can also count with __this, which references the object executing the method (not the method containing the method, that's another, rather different concept). It won't be a good idea to manipulate that, unless you exactly now what you're doing.

The meaning of general purpose for registers has something anecdotical: the now famous jeep of the USA army during WWII have their name deriving from exactly "general purpose" -> "gp" -> "jeep". Actually, the name of this cars does not mean anything specific. The name of the Zero's registers then is general purpose 1, general purpose 2... and for me, just jeep1, jeep2...

Anécdotas sobre Zero

Es curioso como pasa el tiempo. Comencé Zero en el 2003, con la especificación del ensamblador y del bytecode. El año que viene serán ya 10 años los que se cumplan desde aquel nacimiento.

El desarrollo en Zero no está parado del todo, sigo teniendo muy presente el compilador de PROWL, que proporcionará muchísima más estabilidad, y compatibilidad con Windows 7 (parece que con Win7 no acaba de funcionar bien, en contraste con Linux, es el primer ejemplo de programa no determinista). Lo que sí es cierto es que hace ya algunos años que el sistema está ya lo bastante completo como para que se utilice en las prácticas de la asignatura, como un ejemplo de sistema programable multilenguaje que presenta dinamicidad y persistencia. Los alumnos también lo han utilizado, creando prácticas como aventuras conversacionales, calculadoras polacas, etc.

Una de las preguntas que más me han realizado a lo largo de estos años es sobre los registros... ¿por qué tiene tan pocos? La respuesta es que, cuando la diseñé, pensaba en que fuera lo más minimalista posible, y que, dentro de lo razonable, pudiesen mapearse con facilidad los registros de Zero a los registros de la arquitectura x86 (pensando en un futuro JITer). Así, tiene los siguientes registros: __ip (contador de instrucciones, que es oculto pero modificado por JMP, JOT y JOF), __exc, que lleva la referencia al objeto de descripción de excepciones cuando se produce una (se podría usar de manera genérica, aunque eso ya sería más para hacking que para cosas normales). El __acc, el acumulador, que funciona efectivamente como en un 486, ya que el resultado de cualquier operación va ahí (aunque yo me inspiré más en un Z80 de Zilog cuando lo diseñé, quizás por algún sentimiento romántico [por otra parte, el z80 "viene del" 8080, y el 8080 es la base de todos los 80x86, especialmente el 8086).

Hay cuatro registros de propósito general (general purpose), ó gp: __gp1, __gp2, __gp3 y __gp4. Finalmente, el registro __rr lleva la referencia a devolver por un método. También se puede manipular durante la ejecución de un método, siempre que al final tenga lo que se quiere devolver.

También está __this, que señala al objeto que está ejecutando el método. No creo que sea muy buena idea manipularlo, a no ser que se sepa exactamente lo que se está haciendo.

Por cierto, lo de "general purpose" tiene un significado anecdótico: los famosos jeep del ejército estadounidense deben su nombre a "general purpose" -> "gp" -> "jeep". En realidad, es un coche sin un nombre realmente significativo. Así, para mi "__gp1" es "jeep1", "__gp2", es "jeep2"... etc.