%title%>Referencia del código EML<%/title%>
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]; |
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]; |
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]; |
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]; |
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]; |
DIS |
Distinto Saca dos valores de la pila y carga verdadero si son distintos |
pila[sp-1]=pila[sp-1]!=pila[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]; |
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]; |
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]; |
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]; |
ADD |
Suma dos constantes Saca dos valores de la pila y carga la suma |
pila[sp-1]+=pila[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]; |
MUL |
Multiplicación Saca dos valores de la pila y carga el producto |
pila[sp-1]*=pila[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]; |
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]; |
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; |