432 lines
13 KiB
Plaintext
432 lines
13 KiB
Plaintext
<%title%>Referencia del código EML<%/title%>
|
|
<div align="center">
|
|
<p align="left"><h1>Referencia del código EML</h1></p>
|
|
<p align="left">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.</p>
|
|
<p align="left">El código EML utiliza una serie de mnemónicos
|
|
que son los tratados en el código fuente de eDIV (véase <a href="compiler_h.html">compiler.h</a>),
|
|
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.</p>
|
|
<p align="left">Para comprender las operaciones que realiza cada comando, hace
|
|
falta conocer los siguientes términos:</p>
|
|
<table width="70%" border="1" cellpadding="5">
|
|
<tr>
|
|
<td><font size="-1">mem[]</font></td>
|
|
<td>
|
|
<p><font size="-1">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.</font></p>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td><font size="-1">ip</font></td>
|
|
<td><font size="-1">Puntero de código. Apunta a la posición
|
|
actual en mem[] del código que se está ejecutando.</font></td>
|
|
</tr>
|
|
<tr>
|
|
<td><font size="-1">pila[]</font></td>
|
|
<td><font size="-1">Pila usada para calcular expresiones y pasar parámetros
|
|
a los procesos y funciones.</font></td>
|
|
</tr>
|
|
<tr>
|
|
<td><font size="-1">sp</font></td>
|
|
<td><font size="-1">Puntero de pila. Apunta a la última posición
|
|
en la pila.</font></td>
|
|
</tr>
|
|
<tr>
|
|
<td>id</td>
|
|
<td>Identificador del proceso actual.</td>
|
|
</tr>
|
|
</table>
|
|
<p align="center"> </p>
|
|
<p align="center">[Instrucciones básicas] - [Instrucciones optimizadas]
|
|
- [Manejo de caracteres]<br>
|
|
[Manejo de cadenas] - [Manejo de Words] - [Miscelánea]</p>
|
|
<p align="center"> </p>
|
|
<p align="center"><font size="+1">INSTRUCCIONES BÁSICAS</font></p>
|
|
<table width="90%" border="1" bgcolor="#EEEEEE" cellspacing="2" bordercolor="#FFFFFF">
|
|
<tr>
|
|
<td><font size="+1">NOP</font></td>
|
|
</tr>
|
|
<tr>
|
|
<td>No operación</td>
|
|
</tr>
|
|
<tr>
|
|
<td bgcolor="#DDDDDD">No realiza ninguna operación.</td>
|
|
</tr>
|
|
</table>
|
|
<br>
|
|
<table width="90%" border="1" bgcolor="#EEEEEE" cellspacing="2" bordercolor="#FFFFFF">
|
|
<tr>
|
|
<td><font size="+1">CAR</font> <valor></td>
|
|
</tr>
|
|
<tr>
|
|
<td>Carga una constante en la pila</td>
|
|
</tr>
|
|
<tr>
|
|
<td bgcolor="#DDDDDD">
|
|
<p>pila[++sp]=mem[ip++];</p>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<br>
|
|
<table width="90%" border="1" bgcolor="#EEEEEE" cellspacing="2" bordercolor="#FFFFFF">
|
|
<tr>
|
|
<td><font size="+1">ASI</font></td>
|
|
</tr>
|
|
<tr>
|
|
<td>Asignación<br>
|
|
Saca de la pila un valor y un offset, y mete el valor en el offset</td>
|
|
</tr>
|
|
<tr>
|
|
<td bgcolor="#DDDDDD">
|
|
<p>pila[sp-1]=mem[pila[sp-1]]=pila[sp];<br>
|
|
sp--;</p>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<br>
|
|
<table width="90%" border="1" bgcolor="#EEEEEE" cellspacing="2" bordercolor="#FFFFFF">
|
|
<tr>
|
|
<td><font size="+1">ORI</font></td>
|
|
</tr>
|
|
<tr>
|
|
<td>OR lógico<br>
|
|
Saca un valor de la pila y realiza un OR lógico con el actual valor
|
|
en la pila</td>
|
|
</tr>
|
|
<tr>
|
|
<td bgcolor="#DDDDDD">
|
|
<p>pila[sp-1]|=pila[sp];<br>
|
|
sp--;</p>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<br>
|
|
<table width="90%" border="1" bgcolor="#EEEEEE" cellspacing="2" bordercolor="#FFFFFF">
|
|
<tr>
|
|
<td><font size="+1">XOR</font></td>
|
|
</tr>
|
|
<tr>
|
|
<td>OR exclusivo<br>
|
|
Saca un valor de la pila y realiza un OR exclusivo con el actual valor
|
|
en la pila</td>
|
|
</tr>
|
|
<tr>
|
|
<td bgcolor="#DDDDDD">
|
|
<p>pila[sp-1]^=pila[sp];<br>
|
|
sp--;</p>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<br>
|
|
<table width="90%" border="1" bgcolor="#EEEEEE" cellspacing="2" bordercolor="#FFFFFF">
|
|
<tr>
|
|
<td><font size="+1">AND</font></td>
|
|
</tr>
|
|
<tr>
|
|
<td>AND lógico<br>
|
|
Saca un valor de la pila y realiza un AND lógico con el actual
|
|
valor en la pila</td>
|
|
</tr>
|
|
<tr>
|
|
<td bgcolor="#DDDDDD">
|
|
<p>pila[sp-1]&=pila[sp];<br>
|
|
sp--;</p>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<br>
|
|
<table width="90%" border="1" bgcolor="#EEEEEE" cellspacing="2" bordercolor="#FFFFFF">
|
|
<tr>
|
|
<td><font size="+1">IGU</font></td>
|
|
</tr>
|
|
<tr>
|
|
<td>Igual, operador lógico de comparación<br>
|
|
Saca dos valores de la pila y carga verdadero si son iguales</td>
|
|
</tr>
|
|
<tr>
|
|
<td bgcolor="#DDDDDD">
|
|
<p>pila[sp-1]=pila[sp-1]==pila[sp];<br>
|
|
sp--;</p>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<br>
|
|
<table width="90%" border="1" bgcolor="#EEEEEE" cellspacing="2" bordercolor="#FFFFFF">
|
|
<tr>
|
|
<td><font size="+1">DIS</font></td>
|
|
</tr>
|
|
<tr>
|
|
<td>Distinto<br>
|
|
Saca dos valores de la pila y carga verdadero si son distintos</td>
|
|
</tr>
|
|
<tr>
|
|
<td bgcolor="#DDDDDD">
|
|
<p>pila[sp-1]=pila[sp-1]!=pila[sp];<br>
|
|
sp--;</p>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<br>
|
|
<table width="90%" border="1" bgcolor="#EEEEEE" cellspacing="2" bordercolor="#FFFFFF">
|
|
<tr>
|
|
<td><font size="+1">MAY</font></td>
|
|
</tr>
|
|
<tr>
|
|
<td>Mayor, comparación con signo<br>
|
|
Saca dos valores de la pila y carga verdadero si el primero es mayor que
|
|
el segundo</td>
|
|
</tr>
|
|
<tr>
|
|
<td bgcolor="#DDDDDD">
|
|
<p>pila[sp-1]=pila[sp-1]>pila[sp];<br>
|
|
sp--;</p>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<br>
|
|
<table width="90%" border="1" bgcolor="#EEEEEE" cellspacing="2" bordercolor="#FFFFFF">
|
|
<tr>
|
|
<td><font size="+1">MEN</font></td>
|
|
</tr>
|
|
<tr>
|
|
<td>Menor, comparación con signo<br>
|
|
Saca dos valores de la pila y carga verdadero si el primero es menor que
|
|
el segundo</td>
|
|
</tr>
|
|
<tr>
|
|
<td bgcolor="#DDDDDD">
|
|
<p>pila[sp-1]=pila[sp-1]<pila[sp];<br>
|
|
sp--;</p>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<br>
|
|
<table width="90%" border="1" bgcolor="#EEEEEE" cellspacing="2" bordercolor="#FFFFFF">
|
|
<tr>
|
|
<td><font size="+1">MEI</font></td>
|
|
</tr>
|
|
<tr>
|
|
<td>Menor o igual<br>
|
|
Saca dos valores de la pila y carga verdadero si el primero es menor o
|
|
igual que el segundo</td>
|
|
</tr>
|
|
<tr>
|
|
<td bgcolor="#DDDDDD">
|
|
<p>pila[sp-1]=pila[sp-1]<=pila[sp];<br>
|
|
sp--;</p>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<br>
|
|
<table width="90%" border="1" bgcolor="#EEEEEE" cellspacing="2" bordercolor="#FFFFFF">
|
|
<tr>
|
|
<td><font size="+1">MAI</font></td>
|
|
</tr>
|
|
<tr>
|
|
<td>Mayor o igual<br>
|
|
Saca dos valores de la pila y carga verdadero si el primero es mayor o
|
|
igual que el segundo</td>
|
|
</tr>
|
|
<tr>
|
|
<td bgcolor="#DDDDDD">
|
|
<p>pila[sp-1]=pila[sp-1]>=pila[sp];<br>
|
|
sp--;</p>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<br>
|
|
<table width="90%" border="1" bgcolor="#EEEEEE" cellspacing="2" bordercolor="#FFFFFF">
|
|
<tr>
|
|
<td><font size="+1">ADD</font></td>
|
|
</tr>
|
|
<tr>
|
|
<td>Suma dos constantes<br>
|
|
Saca dos valores de la pila y carga la suma</td>
|
|
</tr>
|
|
<tr>
|
|
<td bgcolor="#DDDDDD">
|
|
<p>pila[sp-1]+=pila[sp];<br>
|
|
sp--;</p>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<br>
|
|
<table width="90%" border="1" bgcolor="#EEEEEE" cellspacing="2" bordercolor="#FFFFFF">
|
|
<tr>
|
|
<td><font size="+1">SUB</font></td>
|
|
</tr>
|
|
<tr>
|
|
<td>Resta, operación binaria<br>
|
|
Saca dos valores de la pila y carga la diferencia del primero con el segundo</td>
|
|
</tr>
|
|
<tr>
|
|
<td bgcolor="#DDDDDD">
|
|
<p>pila[sp-1]-=pila[sp];<br>
|
|
sp--;</p>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<br>
|
|
<table width="90%" border="1" bgcolor="#EEEEEE" cellspacing="2" bordercolor="#FFFFFF">
|
|
<tr>
|
|
<td><font size="+1">MUL</font></td>
|
|
</tr>
|
|
<tr>
|
|
<td>Multiplicación<br>
|
|
Saca dos valores de la pila y carga el producto</td>
|
|
</tr>
|
|
<tr>
|
|
<td bgcolor="#DDDDDD">
|
|
<p>pila[sp-1]*=pila[sp];<br>
|
|
sp--;</p>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<br>
|
|
<table width="90%" border="1" bgcolor="#EEEEEE" cellspacing="2" bordercolor="#FFFFFF">
|
|
<tr>
|
|
<td><font size="+1">DIV</font></td>
|
|
</tr>
|
|
<tr>
|
|
<td>División de enteros<br>
|
|
Saca dos valores de la pila y carga el cociente del primero con el segundo</td>
|
|
</tr>
|
|
<tr>
|
|
<td bgcolor="#DDDDDD">
|
|
<p>pila[sp-1]/=pila[sp];<br>
|
|
sp--;</p>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td bgcolor="#EEEEFF"><font color="#FF0000">Si el valor actual en la pila
|
|
es 0, se producirá un error "División entre cero"</font></td>
|
|
</tr>
|
|
</table>
|
|
<br>
|
|
<table width="90%" border="1" bgcolor="#EEEEEE" cellspacing="2" bordercolor="#FFFFFF">
|
|
<tr>
|
|
<td><font size="+1">MOD</font></td>
|
|
</tr>
|
|
<tr>
|
|
<td>Módulo<br>
|
|
Saca dos valores de la pila y carga el resto de la división del
|
|
primero con el segundo</td>
|
|
</tr>
|
|
<tr>
|
|
<td bgcolor="#DDDDDD">
|
|
<p>pila[sp-1]%=pila[sp];<br>
|
|
sp--;</p>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td bgcolor="#EEEEFF"><font color="#FF0000">Si el valor actual en la pila
|
|
es 0, se producirá un error "División entre cero"</font></td>
|
|
</tr>
|
|
</table>
|
|
<br>
|
|
<table width="90%" border="1" bgcolor="#EEEEEE" cellspacing="2" bordercolor="#FFFFFF">
|
|
<tr>
|
|
<td><font size="+1">NEG</font></td>
|
|
</tr>
|
|
<tr>
|
|
<td>Negación<br>
|
|
Cambia de signo el valor actual en la pila</td>
|
|
</tr>
|
|
<tr>
|
|
<td bgcolor="#DDDDDD">
|
|
<p>pila[sp]=-pila[sp];</p>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<br>
|
|
<table width="90%" border="1" bgcolor="#EEEEEE" cellspacing="2" bordercolor="#FFFFFF">
|
|
<tr>
|
|
<td><font size="+1">PTR</font></td>
|
|
</tr>
|
|
<tr>
|
|
<td>Puntero<br>
|
|
Saca un offset de la pila y carga el valor que hay en ese offset</td>
|
|
</tr>
|
|
<tr>
|
|
<td bgcolor="#DDDDDD">
|
|
<p>pila[sp]=mem[pila[sp]];</p>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<br>
|
|
<table width="90%" border="1" bgcolor="#EEEEEE" cellspacing="2" bordercolor="#FFFFFF">
|
|
<tr>
|
|
<td><font size="+1">NOT</font></td>
|
|
</tr>
|
|
<tr>
|
|
<td>Negación binaria, bit a bit<br>
|
|
Alterna (XOR) todos los bits del valor actual en la pila</td>
|
|
</tr>
|
|
<tr>
|
|
<td bgcolor="#DDDDDD">
|
|
<p>pila[sp]^=-1;</p>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<br>
|
|
<table width="90%" border="1" bgcolor="#EEEEEE" cellspacing="2" bordercolor="#FFFFFF">
|
|
<tr>
|
|
<td><font size="+1">AID</font></td>
|
|
</tr>
|
|
<tr>
|
|
<td>Suma id al valor en la pila</td>
|
|
</tr>
|
|
<tr>
|
|
<td bgcolor="#DDDDDD">
|
|
<p>pila[sp]+=id;</p>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<br>
|
|
<table width="90%" border="1" bgcolor="#EEEEEE" cellspacing="2" bordercolor="#FFFFFF">
|
|
<tr>
|
|
<td><font size="+1">CID</font></td>
|
|
</tr>
|
|
<tr>
|
|
<td>Carga id en la pila</td>
|
|
</tr>
|
|
<tr>
|
|
<td bgcolor="#DDDDDD">
|
|
<p>pila[++sp]=id;</p>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<br>
|
|
<table width="90%" border="1" bgcolor="#EEEEEE" cellspacing="2" bordercolor="#FFFFFF">
|
|
<tr>
|
|
<td><font size="+1">RNG</font> <rango></td>
|
|
</tr>
|
|
<tr>
|
|
<td>Comprobación de rango<br>
|
|
Sólo efectiva en modo de depurado. </td>
|
|
</tr>
|
|
<tr>
|
|
<td bgcolor="#DDDDDD">
|
|
<p>pila[++sp]=id;</p>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<p> </p>
|
|
<p align="center"> </p>
|
|
</div>
|
|
<%end%> |