Revistas en papel
 Amiga World Nº16 - Diciembre 1990
Anterior
MenĂº
Logotipo

El Amiga Me Encanta ha conseguido el permiso por escrito de IDG Comunications España
para ofrecer los artículos de la revista Amiga World España.

Los cuadernos del
Ensamblador

CAPÍTULO III

Por F. Javier Rodríguez

Amiga World

Todo el mundo que
desee programar el
Amiga, debe saber las
estructuras a seguir
en la realización de
ciertas operaciones,
pero primero deberá
conocer
profundamente el
Ensamblador del
68000.

En éste capítulo comenzaremos a estudiar los diferentes modos y comportamientos de cada instrucción con respecto al byte de estado, así como los registros y tamaños de dato implicados en el proceso.

La primera de las instrucciones que contemplaremos es una que fácilmente se puede asociar a su equivalente del Basic: Move.x (donde 'x' puede ser sustituído por el tamaño del dato). En concreto el equivalente de ésta instrucción es el POKEw del Basic (igual que en el caso anterior 'x' se sustituye por el tamaño del dato). El cometido de ésta instrucción no es otro que el de almacenar un valor (dato) en una posición de memoria.

Desde el Basic la sintaxis de ésta instrucción sería la siguiente: POWEW 8192,32; todos los programadores de Basic saben que mediante ésta instrucción se está almacenando el valor 32 en la dirección de memoria 8192. En Ensamblador la sintaxis será la siguiente: Move.w #$20,$2000.

Analizando las dos sintaxis, tanto la del Basic como la de Ensamblador, podemos observar que la estructura es distinta. En Basic el primer valor se corresponde con la posición de memoria, mientras que en Ensamblador dicho valor es el segundo. En Basic el dato a almacenar se corresponde con el segundo elemento, en Ensamblador éste se corresponde con el primero. La última diferencia que se puede observar es que en el Basic los números se corresponden con su valor decimal, mientras que en el Ensamblador se encuentran representados en Hexadecimal.

Una de las características que se deben tener en cuenta a realizar ésta operación es el tamaño del dato. En ésta ocasión el tamaño viene representado por la letras 'w' (word/palabra), indicando que el dato tiene un tamaño de 16 Bytes. Está consideración es más importante de lo que puede parecer a primera vista, ya que un error en la definición del tamaño puede falsear un dato. Para comprobarlo veamos el ejemplo de la fig. 1.

Puede observar como el valor almacenado en la posición 8192 no es 255, sino que por el contrario es uno muy distinto... ¡ 47359 !. Por lo tanto compruebe SIEMPRE que el tamaño del dato se corresponde con el valor que usted realmente desea dejar almacenado en memoria.

También puede suceder que a usted realmente le interese almacenar sólo el Byte inferior de la palabra, prescindiendo del valor que pueda contener el Byte superior de la dirección destino; en tal caso la operación es totalmente correcta.

Otros modos de almacenar datos.

A la hora de almacenar datos no sólo se dispone de la memoria, sino que también se pueden almacenar valores en los registros de datos. Para comprenderlo mejor tomemos de nuevo el Basic como referencia.

En la programación Basic es necesario en más de una ocasión dar un valor a una variable, o que una variable le asigne su valor a otra distinta. De igual forma en Ensamblador éstas operaciones son fácilmente realizables, para ello observe el siguiente ejemplo:

Move.w #$20,D0 -> asignamos el valor 32 a la palabra baja del registro (variable) D0, recuerde que los registros de datos D0/D7 pueden contener valores de 32 bits (doble palabra).

Move.w D0,D1 -> asignamos el valor contenido en el registro de datos D0 al registro de datos D1, por tanto ahora D0 y D1 contienen el mismo valor (32).

Move.w D1,$2000 -> almacena el valor contenido en el registro D0 en la posición de memoria 8192.

La diferencia con respecto al ejemplo anterior de almacenamiento es que, además de tener el valor en la memoria, también se encuentra en los registros D0 y D1.

Hasta ahora se ha accedido a la posición de memoria directamente, es decir mediante el valor de la posición; sin embargo para realizar ésta misma operación, el Amiga se encuentra dotado con seis registros denominados de A0 a A6 (registros de dirección. Con el manejo de dichos registros el acceso a una posición de memoria se realiza con una mayor flexibilidad.

Fig. 1: Supongamos que en la posición de memoria $2000 (8192 en decimal) se encuentra el siguiente valor en binario %1011100011100111, que se corresponde en decimal con 47333. La operación que realizaremos es la de almacenar un dato en dicha posición de memoria, para ello recurriremos a la instrucción Move.x:

De nuevo compararemos la función en Ensamblador con su equivalente del Basic. En Basic la sintaxis sería la siguiente: A=8192: POKEw A,32; en Ensamblador ésta operación queda representada de la siguiente forma:

   Move.w #$2000,A0
   Move.w #$20,(A0)

Después de ver estas dos líneas en Ensamblador seguramente se formulará una pregunta: ¿por qué el registro de dirección A0 se encuentra entre paréntesis?. La explicación es la siguiente: si se realiza un Move.x de un dato o registro de dato a un registro de dirección sin paréntesis, significa que el registro de dirección toma el valor del dato (o del registro de dato).

Sin embargo si se realiza un Move.x de un dato o registro de dato a un registro de dirección entre paréntesis, significa que el registro de dirección no toma el valor del dato, sino que el dato es almacenado en la dirección indicada por el valor contenido en el registro de dirección. Por ejemplo la segunda línea de Ensamblador almacenará el valor 32 (#$20) en la dirección 8192 ($2000), no en el registro A0 (como en la primera línea). Una vez observado el esquema decirles que, como todo en Ensamblador, éste tipo de direccionamiento recibe el nombre de direccionamiento indirecto; ya que la posición de memoria, donde debe almacenarse el dato, es el valor contenido en un registro de memoria (a ésto se le llama puntero, ya que en éste caso A0 apunta a la dirección real), y no un valor fijo.

Por otro lado existe una forma de almacenar datos sin 'consumir memoria', para ello hay que recurrir a un registro especial del cual se habló en el capítulo pasado: la Pila de usuario (SP). El registro Sp, también denominado A7, es en realidad un apuntador a la dirección de pila de usuario, la cual crece de arriba hacia abajo desde su base. El siguiente ejemplo muestra como introducir un valor en la pila de usuario.

Move.w #$20,-(SP) -> introduce el valor 32 en la pila
(SP)+,D0 -> asigna al registro de datos D0 el último valor introducido en la pila (32).

Fig. 2: Podemos comprobar como el nuevo valor de la dirección es efectivamente 255 (#$FF), posteriormente si leemos ésta posición de memoria obtendremos el valor almacenado. Pero si se hubiese definido el tamaño de dato como Byte, los resultados habrían sido muy distintos.

El funcionamiento de la pila es realmente más complejo y delicado, pero por el momento sólo necesitamos ver las posibilidades de almacenamiento de datos; dejando el tratamiento de la pila en profundidad para posteriores capítulos.


Lectura de datos.

Hasta ahora se ha tratado el almacenamiento de los datos en la memoria, mediante diversos modos de operación; así como una pequeña introducción a los servicios de la Pila. La operación contraria del almacenamiento de datos es la lectura de los mismos. En más de una ocasión habrá utilizado desde el Basic la instrucción PEEK, que más o menos podríamos traducir por 'tomar'.

Bien, lo que ésta instrucción realiza es tomar el valor almacenado en una determinada posición de la memoria, por tanto mediante ésta instrucción podríamos conocer el contenido de toda la memoria de nuestro Amiga. La sintaxis de dicha instrucción en Basic es a= Peek(8192), donde la variable 'a' contendrá el valor contenido en dicha posición de memoria.

Pero volviendo al Ensamblador, hemos de encontrar la instrucción equivalente a la del Basic, y no es otra que MOVE. Efectivamente es la misma instrucción que anteriormente hemos utilizado para almacenar datos, pero también es la responsable de leer los mismos de la memoria, mediante el simple cambio de los operandos.

Si es la sintaxis utilizada para el almacenamiento de datos, se ponía primero el registro de datos o valor directo, y a continuación el registro de dirección o dirección absoluta, en el modo de "lectura" primero se tendrá que poner el registro de dirección o dirección absoluta (que actúa como fuente) y a continuación el registro de datos (que actúa como destino); evidentemente no podemos poner un valor absoluto como destino, ya que ¿qué sentido tendría la frase "Coge el valor contenido en la posición "n" y ponlo en r"? Únicamente se pondrá como destino, en la lectura de datos, un registro de datos u otra dirección o registro de dirección.

De esta forma se encuentran los siguientes modos para la lectura de datos:

Move.w $2000,D0; Lee el valor contenido en la posición 8192 y lo deja en el registro D0.

Move.w $2000, $5000; Lee el valor contenido en la posición 8192 y lo deja en la posición $5000.

Move.w $2000, SP; Lee el valor contenido en la posición 8192 y lo deja en la Pila.

Como habrá comprobado tanto la escritura de datos en la memoria, como la lectura de éstos desde la memoria, se realizan de una forma igual de simple que desde el Basic; así como el movimiento de datos entre los registros, equivalente al intercambio de los contenidos de las variables desde el Basic.


GLOSARIO

DESTINO: El destino es la dirección o registro en el cual se depositará un valor o dato.

FUENTE: En Ensamblador se utiliza el término "fuente" para denominar la dirección o registro desde la cual se lee un dato. Este término también se utiliza a la hora de transferir datos desde un periférico "fuente" hacia otro periférico "destino".

Fig. 3: Para aclararlo veamos el siguiente esquema:

PILA: Porción de memoria que contiene valores referentes a retornos de rutina, datos de sistema, o datos del usuario. Por lo general, si la Pila no es accedida por el usuario, éste contiene la dirección de retorno desde una subrutina; dicha dirección apunta a la instrucción siguiente desde donde se saltó a la subrutina.

Otro de los usos es el almacenamiento momentáneo, por parte del usuario, de valores que no desea perder durante una operación.

La denominación original de PILA es la inglesa LIFO, cuyo significado (Last in First Out) es el de "Último en entrar, primero en salir".

VALOR ABSOLUTO: Como su nombre indica, un valor absoluto es aquel que designa por sí mismo un dato o posición de memoria. Por ejemplo en la sintaxis: Move.w #$4,$2000, tanto el operando fuente como el destino son valores absolutos.


Envía esta página web a un amigo:
Esta opción está desactivada temporalmente, rogamos disculpen las molestias

Volver a la página anterior

Al menú principal