<%title%>Referencia del código EML<%/title%>

Referencia del código EML

El bytecode de los ejecutables creados con eDIV usan el sistema EML, del cual por ahora no conocemos su verdadero autor y no sabemos si tiene un origen anterior a DIV, probablemente ésta sea una variante de un código anterior, y es el sistema que se utilizó en DIV Games Studio 1 y 2. Sería perfectamente posible compilar un programa DIV a nivel de código máquina, pero dado su alto nivel y la complejidad que requeriría generar un stub en tiempo de compilación, vemos que es más viable y sencillo usar un código intermedio que el stub pueda ejecutar, a modo de máquina virtual. Esto nos permite, además, la capacidad de migrar ejecutables entre DIV 2, eDIV para Linux y eDIV para Windows, ya que el código EML que utilizan es el mismo, y tan sólo habría que cambiarle el stub por el de la plataforma adecuada y encontrar las librerías equivalentes.

El código EML utiliza una serie de mnemónicos que son los tratados en el código fuente de eDIV (véase compiler.h), y son también los utilizados para generar el desensamblado EML desde el compilador. A continuación se incluye una referencia completa (o casi) de todas las instrucciones utilizadas en el código EML de eDIV.

Para comprender las operaciones que realiza cada comando, hace falta conocer los siguientes términos:

mem[]

Memoria de la máquina destino. Contiene el bytecode, los valores de cada variable, etc. Funciona de forma similar al buffer de memoria de un emulador. Cada posición en mem[] equivale a 4 bytes.

ip Puntero de código. Apunta a la posición actual en mem[] del código que se está ejecutando.
pila[] Pila usada para calcular expresiones y pasar parámetros a los procesos y funciones.
sp Puntero de pila. Apunta a la última posición en la pila.
id Identificador del proceso actual.

 

[Instrucciones básicas] - [Instrucciones optimizadas] - [Manejo de caracteres]
[Manejo de cadenas] - [Manejo de Words] - [Miscelánea]

 

INSTRUCCIONES BÁSICAS

NOP
No operación
No realiza ninguna operación.

CAR <valor>
Carga una constante en la pila

pila[++sp]=mem[ip++];


ASI
Asignación
Saca de la pila un valor y un offset, y mete el valor en el offset

pila[sp-1]=mem[pila[sp-1]]=pila[sp];
sp--;


ORI
OR lógico
Saca un valor de la pila y realiza un OR lógico con el actual valor en la pila

pila[sp-1]|=pila[sp];
sp--;


XOR
OR exclusivo
Saca un valor de la pila y realiza un OR exclusivo con el actual valor en la pila

pila[sp-1]^=pila[sp];
sp--;


AND
AND lógico
Saca un valor de la pila y realiza un AND lógico con el actual valor en la pila

pila[sp-1]&=pila[sp];
sp--;


IGU
Igual, operador lógico de comparación
Saca dos valores de la pila y carga verdadero si son iguales

pila[sp-1]=pila[sp-1]==pila[sp];
sp--;


DIS
Distinto
Saca dos valores de la pila y carga verdadero si son distintos

pila[sp-1]=pila[sp-1]!=pila[sp];
sp--;


MAY
Mayor, comparación con signo
Saca dos valores de la pila y carga verdadero si el primero es mayor que el segundo

pila[sp-1]=pila[sp-1]>pila[sp];
sp--;


MEN
Menor, comparación con signo
Saca dos valores de la pila y carga verdadero si el primero es menor que el segundo

pila[sp-1]=pila[sp-1]<pila[sp];
sp--;


MEI
Menor o igual
Saca dos valores de la pila y carga verdadero si el primero es menor o igual que el segundo

pila[sp-1]=pila[sp-1]<=pila[sp];
sp--;


MAI
Mayor o igual
Saca dos valores de la pila y carga verdadero si el primero es mayor o igual que el segundo

pila[sp-1]=pila[sp-1]>=pila[sp];
sp--;


ADD
Suma dos constantes
Saca dos valores de la pila y carga la suma

pila[sp-1]+=pila[sp];
sp--;


SUB
Resta, operación binaria
Saca dos valores de la pila y carga la diferencia del primero con el segundo

pila[sp-1]-=pila[sp];
sp--;


MUL
Multiplicación
Saca dos valores de la pila y carga el producto

pila[sp-1]*=pila[sp];
sp--;


DIV
División de enteros
Saca dos valores de la pila y carga el cociente del primero con el segundo

pila[sp-1]/=pila[sp];
sp--;

Si el valor actual en la pila es 0, se producirá un error "División entre cero"

MOD
Módulo
Saca dos valores de la pila y carga el resto de la división del primero con el segundo

pila[sp-1]%=pila[sp];
sp--;

Si el valor actual en la pila es 0, se producirá un error "División entre cero"

NEG
Negación
Cambia de signo el valor actual en la pila

pila[sp]=-pila[sp];


PTR
Puntero
Saca un offset de la pila y carga el valor que hay en ese offset

pila[sp]=mem[pila[sp]];


NOT
Negación binaria, bit a bit
Alterna (XOR) todos los bits del valor actual en la pila

pila[sp]^=-1;


AID
Suma id al valor en la pila

pila[sp]+=id;


CID
Carga id en la pila

pila[++sp]=id;


RNG <rango>
Comprobación de rango
Sólo efectiva en modo de depurado.

pila[++sp]=id;

 

 

<%end%>