<%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%>