Manual de lenguaje Ensamblador del Microprocesador Motorola 68000
Capitulo 1
Introducción al lenguaje Ensamblador del Microprocesador Motorola 68000
Capitulo 2
programa ensamblador
Capitulo 3
Estructura y sintaxis de un lenguaje ensamblador
Capitulo 4
Directivas de ensamblador o pseudoinstrucciones
Capitulo 5
Programación de un Microprocesador de 16 bits el 68000 de Motorola
Capitulo 6
Instrucciones en ASEMBLER Motorola 68000
Capitulo 7
Programación en ASM Motorola
Capitulo 8
Examenes
Capitulo 9
SOLUCIÓN DE LOS EXÁMENES REALIZADOS EN EL CURSO
Introducción al lenguaje Ensamblador del Microprocesador Motorola 68000
El Lenguaje Ensamblador del Motorola 68000, es la Unidad Didáctica III, de la asignatura Estructura y Tecnología de Computadores I, que se cursa en la Ingeniería Técnica de Informática de Sistemas en la UNED. El propósito de esta página es ser una primera referencia para poder empezar a comprender que es un lenguaje y un programa ensamblador, y como se programa en bajo nivel.Esta página la empecé a construir en el verano de 1997, mientras estudiaba la carrera, y me ayudó a comprender la materia a la vez que me hizo distraerme, aprendiendo a diseñar webs. Os ruego no me pidaís ayuda pues no soy ningún entendido en ensamblador ni lo he vuelto a tocar desde entonces.
El lenguaje ensamblador surge con la idea de evitar las dificultades que presenta el trabajar en lenguaje máquina, siendo la misión de este la de simplificar la programación en un computador y teniendo a la vez un control directo sobre el hardware del mismo.
El lenguaje ensamblador es un lenguaje cuyas estructuras de datos se corresponden con las estructuras físicas de los registros de la memoria principal del computador para el que está pensado,y cuyas instrucciones tienen una relación directa y biunívoca con las instrucciones del lenguaje máquina.
programa ensamblador
Un programa ensamblador es un programa que traduce un texto escrito en lenguaje ensamblador de un determinado computador al lenguaje máquina de ese mismo computador, y proporciona las facilidades necesarias para simplificar la tarea de desarrollar programas en lenguajes de bajo nivel.
También, un programa ensamblador proporciona una interfaz adecuada entre el programador y la arquitectura del computador, para las tareas de programación. Si el ordenador que se utiliza para esta tarea es el mismo, o tiene la misma CPU, que el sistema que va a ejecutar el código máquina resultante de la traducción, se dice que el programa ensamblador utilizado es un auto-ensamblador o ensamblador residente, mientras que si utiliza otra CPU diferente es un ensamblador cruzado (cross assembler).
El ordenador sobre el que corre el programa ensamblador tendrá en su memoria central el programa fuente codificado en caracteres alfanuméricos y el propio programa ensamblador que se está ejecutando, debiendo reservar en memoria, además, un espacio para ir almacenando el código resultante de la traducción. El programa fuente se encuentra almacenado en una zona de memoria, llamada buffer, en forma de caracteres alfanuméricos, ocupando cada carácter un byte. El código resultante del proceso se denomina código objeto, y queda almacenado en otro lugar de la memoria. Además se utiliza otra zona de memoria destinada a almacenar la tala de símbolos. La tabla de símbolos no es sin un pequeño diccionario que construye el programa ensamblador en el que constan todas las etiquetas utilizadas junto con sus equivalencias numéricas. La tabla de símbolos es temporal y sirve al propio programa ensamblador a la hora de efectuar la traducción. Una vez ensamblado el programa, la tabla no tiene otra utilidad que la de su posible consulta por parte del programador durante el proceso de depuración. El programa ensamblador actúa generalmente en dos pasos: durante el primero lee el código fuente y anota en la tabla de símbolos las etiquetas que se encuentran, calculando, si es necesario su equivalencia; en el segundo paso se apoya en la tabla de símbolos y, mediante otra lectura del programa fuente, va traduciendo, instrucción por instrucción, los códigos nemónicos que encuentra. eneralmente, los programas ensambladores están dotados de la posibilidad de detectar errores y dan el aviso correspondiente cuando encuentran un nemónico inexistente, un operando fuera de margen, una etiqueta definida dos veces, etc.
Estructura y sintaxis de un lenguaje ensamblador
La Sintaxis de un lenguaje ensamblador es el conjunto de reglas que debe guardar el programa fuente y que estará compuesto por una serie de instrucciones, distinguiéndose cuatro campos: etiqueta, mnemotécnico, operando y comentario. El programa fuente deberá estar en un fichero ASCII que se genera con la ayuda de un programa editor, y no un procesador de textos, ya que estos generan códigos de control que los ensambladores son incapaces de interpretar. Un sencillo editor es el de MS-DOS. Las instrucciones en código máquina se codifican por campos, por lo que las instrucciones escritas en ensamblador se codificaran también por campos.
LINEA DE INSTRUCCION EN ENSAMBLADOR
ETIQUETA |
NEMOTECNICO |
OPERANDO |
COMENTARIO |
SUBR |
MOVE.L |
D0, - (SP) ; |
Guarda D0 |
a) Campo de Etiqueta:
Es un campo opcional que se utiliza para tener una referencia de las instrucciones. El programa ensamblador va traduciendo secuencialmente las instrucciones del programa fuente, guardando los códigos traducidos en posiciones consecutivas de memoria. Cuando encuentra una etiqueta en una línea de instrucción, el ensamblador guarda dicha etiqueta en una tabla especial en la memoria, junto con la dirección de memoria en la que se ha almacenado la instrucción que la acompaña, así si alguna instrucción tiene que referenciar a la instrucción etiquetada, bastará con que se escriban los caracteres de la etiqueta en el campo de operandos correspondiente. El programa ensamblador se encargará, cuando deba traducir esta instrucción, de buscar en la tabla la dirección en memoria de la instrucción correspondiente a la etiqueta.
Las ventajas del empleo de etiquetas son:
· Las etiquetas permiten localizar y recordar fácilmente una determinada instrucción.
· Se puede modificar de forma sencilla, en la fase de corrección de un programa, el punto hacia donde tienen que realizarse uno o más saltos, simplemente cambiando la etiqueta de una instrucción a otra.
· En caso de que el programa objeto se deba colocar en posiciones de memoria diferentes de las que en un principio se habían previsto, si se han asignado etiquetas, no hay que hacer ningún cambio en el programa fuente pues al hacer la nueva traducción, el programa ensamblador asigna automáticamente las nuevas posiciones a las etiquetas. Así facilita la unión de varios programas que hayan sido desarrollados por separado.
· El programador se libera de la tarea de calcular direcciones.
Todos los ensambladores imponen algunas reglas y limitaciones en la utilización de etiquetas, siendo estas en el caso del Asm68k las siguientes:
· Unicamente son significativos los primeros quince caracteres de la etiqueta
· Los caracteres pueden ser cualquier código ASCII mayor que 32 (espacio), salvo + - / & ! < ( ) ^ | .
· El primer carácter no puede ser un número, ni los símbolos $ y %
Mayúsculas y minúsculas se consideran caracteres diferentes.
b) Campo de Nemotécnico:
Se utiliza para escribir los códigos de instrucciones ejecutables y los códigos de pseudoinstrucciones o directivos de ensamblador.
Las instrucciones ejecutables son los mnemotécnicos que constituyen las instrucciones del computador.
Las pseudoinstrucciones sirven para dar al ensamblador indicaciones como la dirección de memoria a partir de la cual debe ir guardando los códigos traducidos, realizar la reserva de las posiciones de memoria donde deben guardarse los resultados, etc. Las pseudoinstrucciones reciben este nombre porque sus mnemotécnicos no se convierten en código máquina, sino que son ejecutados directamente por el programa traductor.
c) Campo de Operandos:
Se utiliza para indicar los valores concretos de los operandos que
intervienen en la operación definida por el campo mnemotécnico. Dependiendo de
la instrucción indicada en el campo mnemotécnico, habrá que definir el modo de
direccionamiento, que estará determinado generalmente, mediante una combinación
del código de operación y la información del campo de operandos.
1. Números y constantes alfabéticas.
Las cantidades colocadas en el campo de operandos pueden venir expresadas en diferentes bases de numeración, que son: binaria, decimal y hexadecimal, y van determinados por un símbolo que se añade al valor numérico.
DECIMAL |
por defecto |
BINARIO |
% |
HEXADECIMAL |
$ |
2. Símbolos.
El conjunto de caracteres alfanuméricos que se utiliza en el campo de los operandos para indicar una dirección recibe el nombre de símbolo. El programador podrá definir sus propios símbolos mediante dos procedimientos:
a) De forma implícita, mediante el empleo de etiquetas.
b) De forma explícita, mediante algunas pseudoinstrucciones.
3. Expresiones.
Una expresión es una
combinación de números y/o símbolos unidos mediante operadores aritméticos o
lógicos
d)
Campo de Comentarios:
Mediante el campo de comentarios se trata de hacer más comprensivo al programa, incluyendo el todos los puntos claves, definición de símbolos, reservas de memoria, propósito del programa, etc.
Directivas de ensamblador o pseudoinstrucciones
Las pseudoinstrucciones dan al ensamblador indicaciones como la dirección de memoria a partir de la cual debe ir colocando los códigos traducidos, realizar la reserva de las posiciones de memoria donde deben guardarse los resultados, etc. Se utiliza el campo nemotécnico para transmitir esta información al programa traductor y darle las indicaciones necesarias para que éste pueda realizar la traducción correctamente. Por lo que debe reservarse un conjunto de mnemotécnicos para este fin los cuales no se convierten en código máquina, sino que son ejecutados directamente por el programa traductor.
DIRECTIVO |
DESCRIPCION |
etiq |
EQU |
expr |
Asigna el valor de la expresión expr a la etiqueta etiq. |
|
ORG |
n |
Las instrucciones que van después empezarán en la dirección n de memoria. |
etiq |
DC.S |
n |
Inicializa el operando de tamaño S al valor n, guardándolo en la dirección simbólica etiq. |
etiq |
DS.S |
n |
Reserva espacio en memoria para n operandos, de tamaño S cada uno, y el primer operando se almacena en la dirección simbólica etiq. |
|
END |
|
Es obligatorio y debe ser la última sentencia del programa. |
|
EXT |
etiq |
Indica al ensamblador que la dirección simbólica etiq está definida en otro módulo. |
|
DEF |
etiq |
Indica al ensamblador que la dirección simbólica etiq puede ser utilizada por otros módulos. |
|
IF ELSE ENDIF |
cond |
Acción condicional; si se verifica la condición cond, el ensamblador traduce las instrucciones comprendidas entre el IF y el ELSE, si no se verifica, traduce las instrucciones comprendidas entre el ELSE y el ENDIF. |
|
NAME |
nom |
El nombre nom aparecerá en la cabecera de cada página de listado. |
|
LIST |
|
Indica al ensamblador que debe imprimir el programa fuente. |
|
TABLE |
|
Indica al ensamblador que debe imprimir la tabla de símbolos. |
|
LALL |
|
Indica al ensamblador que debe imprimir el programa fuente, el código máquina y la tabla de símbolos. |
|
EVEN |
|
Almacena la siguiente instrucción o asignación de memoria en una dirección par. |
1.- DEFINICIÓN DE SÍMBOLOS (EQU)
Definir un símbolo consiste en asignar un valor como un número o una dirección de memoria a un nombre utilizando el directivo EQU.
Ejemplo: |
IMPRESORA |
EQU |
$AB12 |
Cuando el traductor lee este directivo, guarda la etiqueta y el valor
indicado en el operando, en una zona de memoria denominada tabla de símbolos. Al
encontrar un símbolo en el campo de operandos el traductor consultará esta tabla
para ver el valor que le corresponde.
2.- EL CONTADOR DE DIRECCIÓN DE ENSAMBLADO (ORG)
El programa
ensamblador utiliza un registro que le indica en que posición de memoria debe
guardar una instrucción y que dirección debe asignar a una determinada etiqueta.
Este registro se llama contador de dirección de ensamblado. Para poner el
contenido de este contador a un valor determinado se usa una pseudoinstrucción
denominada ORG.
Ejemplo: |
ORG |
$1500 pone el número $1500 en el contador de dirección de ensamblado. |
3.- DEFINICIÓN DE
CONSTANTES (DC)
La
sentencia DC.S permite definir una posición de memoria conteniendo un valor
determinado o una serie de valores que se colocarán en orden a partir de la
posición señalada.
4.- DEFINICIÓN DE DATOS (DS)
La sentencia DS,S reserva espacio de memoria sin especificar su contenido , y su longitud viene dada por el valor del operando , viéndose afectado este por el tamaño de la palabra como un factor multiplicador siendo por 1, por 2 o por 4 respectivamente.
5.- ULTIMA SENTENCIA DEL PROGRAMA (END)
La sintaxis de este directivo es muy simple ya que consta sólo de un campo de mnemotécnico, END. Este directivo únicamente se usa una vez en cada programa y será necesariamente la última instrucción.
6.- ENLACE ENTRE PROGRAMAS (EXT, DEF)
La programación
modular consiste en dividir un programa complejo en módulos independientes de
manera que cada uno de ellos realice una tarea concreta. Para permitir la
traducción de dichos módulos se usa el directivo EXT que indica al ensamblador
que los símbolos utilizados en el módulo objeto de la traducción están definidos
en otro módulo diferente.
En
el módulo donde se definen los símbolos que pueden ser utilizados por otros
módulos deberá indicarse con el directivo DEF.
7.- ACCIONES CONDICIONALES (IF, ELSE, ENDIF)
Estas
pseudoinstrucciones funcionan como en un lenguaje de alto nivel, es decir si se
verifica la condición, el ensamblador traduce las instrucciones entre el IF y
el ELSE y sino, entre el ELSE y el ENDIF.
8.- EJECUCIÓN DE INFORMES (NAME, PAGE, LIST, TABLE, LALL)
El programa
ensamblador puede emitir una serie de informes, como mostrar un listado en
lenguaje ensamblador y en código máquina, mostrar los errores sintácticos, etc.
Los directivos que realizan estas funciones son los siguientes:
-
NAME: da la posibilidad de poner un identificador al programa, así cuando se
liste aparecerá el nombre en la cabecera.
-
PAGE: indica al traductor que debe de saltar a una nueva página cuando esté
imprimiendo el informe.
-
LIST: indica al traductor que imprima el programa fuente.
-
TABLE: indica al traductor que imprima la tabla de símbolos
-
LALL: indica al traductor que imprima el programa fuente, el código máquina y la
tabla de símbolos.
9.- ALMACENAMIENTO EN POSICIÓN PAR
Existe una pseudoinstrucción, EVEN, que soluciona el problema de los microprocesadores de 16 bits, ya que estos sólo pueden utilizar datos de 2 bytes o más, comenzando siempre desde una posición par.
Programación de un Microprocesador de 16 bits el 68000 de Motorola
A continuación se
irán describiendo los tres componentes principales del computador, la memoria,
el procesador y la unidad de entrada/salida, según el esquema adjunto.
|
Memoria |
|
|
|
|
|
|
|
Procesador |
|
|
|
|
|||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||
|
|
|
|
|
Registros de datos |
|
Registros de direcciones |
|
Registros de control |
|
|
|||||||
0 |
|
|
|
|
|
D0 |
|
A0 |
|
PC |
|
|
||||||
1 |
|
D1 |
|
A1 |
|
|
|
|||||||||||
|
|
D2 |
|
A2 |
SR |
|||||||||||||
D3 |
|
A3 |
|
|||||||||||||||
D4 |
|
A4 |
SP(A7) |
|||||||||||||||
D5 |
|
A5 |
|
|||||||||||||||
D6 |
|
A6 |
|
|||||||||||||||
FFEFFF |
|
D7 |
|
|
|
|||||||||||||
|
|
|
|
|
|
|||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|||||||
|
|
Puertos de entrada/salida |
|
|
||||||||||||||
|
|
FFF000 |
|
FFF002 |
|
FFF004 |
|
|
|
|
||||||||
|
|
|
|
|
|
|
|
|||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||
|
|
|
|
|
|
|
|
|
|
|
|
I N D I C E
La memoria
principal de este computador está formada por celdas de un byte (8 bits), que
constituyen la unidad básica de lectura o escritura, identificándose mediante
una dirección.
Los procesos de lectura y escritura pueden realizarse con varias celdas
consecutivas simultáneamente, debiendo indicar el procesador a la memoria
principal dos parámetros, la dirección de la primera celda de memoria y la
longitud de la información a la que se desea acceder. Siendo esta longitud de un
byte, dos bytes (una palabra) o cuatro bytes (palabra larga).
El tamaño máximo de la memoria viene determinado por el número de bits de los
registros de direcciones que tiene el procesador, siendo en el caso del Motorola
68000 de 32 bits pero, debido a limitaciones en el montaje solo pueden
utilizarse 24 como máximo, así que la máxima longitud que se puede usar de la
memoria principal es de 224 bytes, desde 0 hasta FFFFFF .
El procesador puede leer y escribir información de diferentes tamaños,
existiendo una norma para almacenar las palabras (W) y las palabras largas (L),
y siendo esta la de comenzar por el byte más significativo.
Existen 7 registros de direcciones y son: A0, A1, A2, A3, A4, A5 y A6,
siendo estos de 32 bits aunque solo pudiendose utilizar 24 bits para direccionar
como antes se ha mencionado.
2.- Registros de Datos
El
Motorola 68000 consta de 8 registros de datos, que son D0, D1, D2, D3, D4, D5,
D6 y D7. Cada uno consta de 32 bits. En muchas instrucciones existe la
posibilidad de especificar el tamaño del dato, indicándose este mediante el
sufijo S (B, W y L), que va añadido al nemotécnico de la instrucción.
La forma en que se almacenan los datos en los registros, viene dada por su
longitud, ya que como esta es variable, irán ocupándolos de izquierda a derecha
empezando por el bit menos significativo del registro.
3.-
Modos de Direccionamiento
Existen cuatro modos de direccionamiento:
1.- Direccionamiento inmediato: almacena el operando precedido del símbolo # en el registro indicado. Ejemplo: MOVE.L #$18,D6
2.-
Direccionamiento absoluto: almacena el operando que está en la dirección de
memoria especificada en el registro de datos indicado.
Ejemplo: ADD.W %000000001000111110001,D2 suma la palabra que está en la
dirección de memoria indicada, a D2.
3.- Direccionamiento mediante registro: apunta a la dirección del registro donde está el dato. Ejemplo: MOVE.B D3,D4 copia el contenido del registro D3 (byte) a D4.
4.- Direccionamiento relativo a registro:
·
a)
Direccionamiento mediante registro normal: se da la dirección del registro donde
está la dirección del dato. El nombre del registro se escribe entre paréntesis.
Ejemplo: ADD.B (A0),D6 suma el contenido de la posición de memoria (byte) cuya
dirección está en A0 al registro D6, guardando el resultado en este último.
·
b)
Direccionamiento relativo a registro con posincremento: incrementa en una
cantidad de memoria, según sea el tamaño del operando (1 para B, 2 para W y 4
para L), después de traer el contenido de la posición de memoria indicada por el
registro de direcciones.
Ejemplo: MOVE.W (A0)+,D0 copia en D0 el contenido de la posición de memoria
direccionada por A0 y luego incrementa en 2 el contenido de A0.
·
c)
Direccionamiento relativo a registro con predecremento: Decrementa en una
cantidad de memoria, según sea el tamaño del operando, el registro de
direcciones y trae despues el contenido de la posición de memoria cuya dirección
es el nuevo valor de dicho registro.
Ejemplo: MOVE.B -(A0),D0 decrementa en uno el contenido del registro A0 y luego
copia en D0 el contenido de la nueva posición de memoria direccionada por A0.
·
d)
Direccionamiento relativo a registro con desplazamiento: El contenido de la
posición de memoria cuya dirección viene dada por la suma del valor del registro
de direcciones y una cantidad fija denominada desplazamiento, pudiendo ser este
positivo o negativo y su valor viene condiciondo por el tamaño del operando.
Ejemplo: MOVE.L N(A0),D1 copia en el registro D1 el contenido de la posición de
memoria cuya dirección viene dada por la suma de N multiplicado por 4(L) al
contenido de A0.
·
e)
Direccionamiento relativo a registro con índice: Este modo de direccionamiento
es la extensión natural del anterior, ya que permite usar desplazamientos
variables, utilizando como desplazamiento el resultado de sumar un número fijo
al contenido de un registro de datos denominado registro índice.
Ejemplo: MOVE.B 4(A0,D1), D0 copia en el registro D0 el contenido de la posición
de memoria cuya dirección es el resultado de sumar el número 4, el contenido del
registro A0 y el contenido del registro D1. Este modo de direccionamiento no
altera el registro de direcciones ni el registro índice.
·
f)
Direccionamiento relativo al contador de programa con desplazamiento: Cuando es
necesario hacer referencia a un operando relativo a la posición de la proxima
instrucción que va a ser ejecutada.
Ejemplo: MOVE.B 24(PC),D0 copia en el registro D0 el contenido de la posición de
memoria cuya dirección es la suma de 24 y el valor del contador del programa.
·
g)
Direccionamiento relativo al contador de programa con índice: Utiliza como
desplazamiento el resultado de sumar un número fijo al contenido de un registro
de datos.
Ejemplo: MOVE.B 24(PC,D0),D1 copia en el registro D1 el contenido de la posición
de memoria cuya dirección es el resultado de sumar el número 24, el contador de
programa y el contenido del registro D0.
4.-
Formatos de instrucciones
Los formatos
empleados para las instrucciones utilizan una o más palabras de 16 bits. La
primera palabra especifica el código de la operación y en muchos casos la
dirección de un operando. Las especificaciones para completar los operandos,
cuando no es suficiente con una palabra van a continuación de la primera
palabra. Cada operando utilizará como máximo dos palabras de ampliación,
equivalente a una palabra larga, después de la del código de operación, por lo
que la instrucción más larga del Motorola 68000 ocupa 5 palabras (10 bytes),
siendo 1 para el código de instrucción, 2 palabras de ampliación para el
operando origen, y 2 palabras de ampliación más para el operando destino.
La información que identifica la situación exacta del operando, denominada
dirección efectiva, se codifica en los formatos de instrucción mediante dos
campos, siendo uno el modo de direccionamiento (MD) y el otro el de registro.
Cada campo tiene un tamaño de 3 bits y se incluyen en la primera palabra de
instrucción. El campo MD identifica el modo de direccionamiento empleado y el
campo CR indica el registro empleado para obtener la dirección del operando. A
veces se utilizan las palabras de ampliación ya que la dirección efectiva
requiere incluir más información sobre la situación del operando en la palabra
de instrucción.
5.- Instrucciones condicionales
Al realizar
operaciones matemáticas existe la posibilidad de desbordamiento, por lo que se
realiza un test automáticamente, quedando el resultado almacenado en un
registro de control, dedicado especialmente a tal efecto, denominado registro de
código de condición (CCR), pudiendose leer mediante la instrucción MOVE. Este
registro consta de 5 flags que se almacenan en los 5 bits menos significativos
del registro de estado (SR).
Estos 5 bits tienen las siguientes denominaciones, ordenadas desde el bit
menos significativo:
- C indicador de acarreo o carry flag: indica el valor del bit de
acarreo de la posición más significativa del resultado de una operación,
poniendose a 1 si existe desbordamiento.
- V indicador de desbordamiento o overflow flag: indica si en el
resultado de una operación en complemento a 2 existe desbordamiento, poniendose
a 1.
- Z es el indicador de cero o zero flag, poniendose a 1 cuando sea 0 el
resultado de una operación aritmetica o lógica.
- N es el indicador de número negativo o negative flag, poniendose a 0
si es positivo y a 1 si es negativo el signo del resultado de una operación en
complemento a 2.
- X es el indicador extendido o extended flag que funciona de la misma
manera que C, pero unicamente con operaciones aritméticas o de desplazamiento.
6.- Entrada/Salida
Los computadores
disponen de unos registros especiales, denominados puertos de E/S o I/O en
inglés para poder comunicarse con el exterior. El Motorola 68000 consta de tres
puertos de este tipo en las siguientes direcciones de memoria:
- FFF000 de E
- FFF002 de S
- FFF004 de E/S
Una subrutina es
un conjunto de instrucciones que realizan una tarea concreta, que no puede ser
ejecutada directamente sino que debe ser llamada por un programa principal. Esta
subrutina denominada también subprograma, procedimiento o simplemente rutina se
comienza a ejecutar cuando es llamada por el programa principal, desde la
primera instrucción. Cuando se ha llegado a la última instrucción, se vuelve a
ejecutar la siguiente instrucción del programa principal anterior a la
invocación de la subrutina.
La gestión de las subrutinas se realiza mediante una estructura de
almacenamiento de tipo de pila. El espacio en memoria que se reserva para la
pila se define a partir de dos direcciones, la dirección de la posición inicial
o fondo de la pila y la dirección de la posición máxima permitida o valor máximo
que puede alcanzar la cima de la pila.
El puntero de pila indica la posición de la cima de la pila, utilizando un
registro de direcciones denominado SP (stack pointer) y que es el A7.
Instrucciones en ASEMBLER Motorola 68000
A continuación se desarrollarán las instrucciones del Motorola 68000, agrupadas según la función básica que realizan, estudiando la operación que realizan, su sintaxis, sus campos y algunos ejemplos.
1.- Instrucciones de transferencias de datos
2.- Instrucciones aritméticas
3.- Instrucciones lógicas
4.- Instrucciones de desplazamiento y rotación
5.- Instrucciones de manipulación de bits
6.- Instrucciones de operación en código BCD
7.- Instrucciones de ramificación y salto
8.- Instrucciones de manejo de subrutinas
1.- Instrucciones de transferencias de datos
El conjunto de estas
instrucciones permite el movimiento de datos entre registros de la CPU, entre
registros y memoria y entre posiciones de memoria. Estas son las siguientes:
MOVE: realiza la transferencia de un dato desde fuente a destino. Modifica el CCR de forma que refleja el signo del dato movido y el hecho de que sea cero o no. Los flags C y V se ponen a cero y el flag X no se modifica. También el manejo de la pila se lleva a cabo mediante esta instrucción, utilizando direccionamiento indirecto con el registro A7 que actúa como puntero de pila. Para llevar un dato a la pila el direccionamiento es indirecto con predecremento, mientras que para extraerlo se emplea el indirecto con posincremento.
MOVEA: (Move Adress) es una variante dedicada a la transferencia de direcciones. El tamaño del dato es de 16 ó 32 bits. No modifica el CCR.
MOVEQ: (Move Quick) tiene por finalidad la carga rápida de un registro de datos.
MOVEM:
(Move Múltiple)
carga una serie de posiciones consecutivas de memoria en varios registros a la
vez. No afecta al CCR.
Ejemplo: MOVEM.L $1000,D0-D2/A2-A4/D7 copia los contenidos de las posiciones
$1000, $1002, $1004,...$100C en los registros D0, D1, D2, D7, A2,A3 y A4
respectivamente.
EXG y SWAP: la primera intercambia el contenido completo de dos registros de datos o de dirección, mientras que la segunda actúa sobre un único registro, siempre de datos, intercambiando sus palabras alta y baja. La realización de estas transferencias sin la existencia de estas instrucciones, requeriría la ejecución de tres instrucciones MOVE, y la utilización de otro registro o de la memoria como almacenamiento temporal.
LEA y PEA: (Load Effective Adress y Push Effective Adress) determinan la dirección efectiva del operando fuente. La primera almacena la dirección efectiva calculada en el registro de direcciones que se especifique como operando destino y la segunda lo lleva a la pila. Ninguna de las dos afectan al CCR.
LINK y UNLINK:
facilitan las
operaciones necesarias para el paso de parámetros a/de subrutinas a través de la
pila, ofreciendo la ventaja de ser independiente de las áreas de memoria de
datos de un programa, y de no necesitar el uso de etiquetas, ni de direcciones
concretas para acceder a dichos parámetros, facilitando así la inclusión de las
subrutinas en programas diferentes sin necesidad de hacer cambios en ellas.
La instrucción LINK reserva una zona de memoria en la pila, desplazando el
puntero de pila (SP) hacia direcciones menores en el valor que se indique.
La instrucción UNLINK restablece la pila en la situación que se encontraba antes
de la ejecución de LINK, cargando el puntero de pila con el contenido del
registro de direcciones que se indica y a continuación extrae la palabra larga
apuntada por SP y la lleva al registro de direcciones, quedando así restaurado.
2.- Instrucciones aritméticas:
El Motorola 68000 dispone de instrucciones para las 4 operaciones aritméticas, sobre operandos binarios, y suma y resta sobre datos codificados en BCD. Además de cambio de signo para ambos tipo de datos, instrucciones de comparación, extensión de signo y actualización de los códigos de condición (CCR) según el valor de un dato.
ADD: realiza la suma de los operandos fuente y destino , quedando el resultado almacenado en destino. Modifica el CCR en función del resultado de la operación.
ADDA: (Add Adress) realiza la operación de la suma, siendo el destino un registro de direcciones en vez de datos.
ADDI: (Add Inmediate) realiza la operación suma mediante direccionamiento inmediato.
ADDQ:
(Add Quick)
realiza la operación resta mediante direccionamiento inmediato siendo el destino
menor o igual que 8.
ADDX: (Add Extended) incluye en
el resultado la suma del flag X, lo que facilita las operaciones con valores que
superan la capacidad de los registros (precisión múltiple).
SUB: (Substract) realiza la diferencia entre fuente y destino, depositando el resultado en destino.
SUBA: (Substract Adress) realiza la operación de la resta, siendo el destino un registro de direcciones en vez de datos.
SUBI: (Substract Inmediate) realiza la operación resta mediante direccionamiento inmediato.
SUBQ: (Substract Quick) realiza la operación resta mediante direccionamiento inmediato siendo el destino menor o igual que 8.
SUBX: (Substract Extended) incluye en el resultado la resta del flag X, lo que facilita las operaciones con valores que superan la capacidad de los registros (precisión múltiple).
MULS y MULU: (Multiply Signed y Multiply Unsigned) realizan la multiplicación sobre datos de 16 bits, generando un resultado de 32 bits, siendo el destino un registro de datos. Los flags C y V siempre quedan a 0 y el flag X no se modifica, reflejando el resultado de la operación los flags Z y N.
DIVS y DIVU: (Signed y Unsigned) realizan la división de un dato de 32 bits (en destino) por otro de 16 bits (en fuente), generando dos resultados de 16 bits: el cociente y el resto, siendo obligatorio que el destino sea un registro de datos. El cociente se guarda en los 16 bits menos significativos y el resto en los 16 bits más significativos del registro destino. Ambas instrucciones ponen el flag C a 0, y el flag X no se modifica. Puede producirse desbordamiento si el divisor es pequeño, reflejandose en el flag V. Los flags N y Z son modificados reflejando el resultado de la operación.
CMP: (Compara) las instrucciones de comparación efectúan la substracción destino-fuente pero la diferencia no se lleva a ningún destino, limitandose a afectar a los flags N, Z, V y C, de forma que se puedan comprobar diversas relaciones entre los datos que se comparen con el fin de producir ramificaciones en el programa.
CMPA: (Compare Adress) utiliza como destino un registro de direcciones.
CMPI: (Compare Inmediate) utiliza direccionamiento inmediato para fuente. Para el operando destino puede utilizar todos los modos salvo direccionamiento directo a registro de direcciones, indirectos con predecremento o posincremento y los relativos a PC.
CMPM: (Compare Memory) compara dos datos en memoria con direccionamiento indirecto con posincremento facilitando así la comparación de bloques de memoria.
CLR: (Clear) carga un cero binario en el operando destino poniendo los flags N a 0, Z a 1, V a 0 y C a 0.
NEG: (Negate) esta instrucción devuelve el complemento a 2 del operando y esto supone el cambio aritmético de signo. Afecta a todos los flags del CCR.
NEGX:
(Negate Extended) facilita el cambio de signo de valores de precisión múltiple.
EXT: (Extend) cuando se quiere
ampliar la longitud de un dato con signo, por ejemplo de byte a palabra o de
palabra a palabra larga , sin alterar su valor, el dato original debe mantenerse
en el byte o palabra de menor peso, y el byte o palabra que se añade debe tener
todos sus bits con el mismo valor que el bit de signo del dato original,
recibiendo esta operación el nombre de extensión de signo.
El Motorola 68000 dispone de cuatro instrucciones que realizan funciones lógicas, que actúan bit a bit sobre datos de 8, 16, ó 32 bits y cuatro para manejar bits individuales sobre datos de 8 ó 32 bits.
AND: es la Y lógica. Admite todos los modos de direccionamiento para el operando fuente menos direccionamiento directo a registro de direcciones, mientras que el operando destino admite también todos menos los direccionamientos relativos a PC.
ANDI: realiza la misma función que AND, pero su direccionamiento es inmediato en el operando fuente y todos menos el direccionamiento directo a registro de direcciones y relativos a PC.
EOR: es el O exclusivo. Admite únicamente el direccionamiento directo a registro de datos para el operando fuente, mientras que el operando destino admite también todos menos los direccionamientos directo a registro de direcciones y los relativos a PC.
EORI: realiza la misma función que EOR, pero su direccionamiento es inmediato en el operando fuente y todos menos el direccionamiento directo a registro de direcciones y relativos a PC.
NOT: complementación lógica.
OR: es la O lógica. Admite todos los modos de direccionamiento para el operando fuente menos direccionamiento directo a registro de direcciones, mientras que el operando destino admite también todos menos los direccionamientos relativos a PC y directo a registro de direcciones.
ORI: realiza la misma función que OR, pero su direccionamiento es inmediato en el operando fuente y todos menos el direccionamiento directo a registro de direcciones y relativos a PC.
TST: (Test) comprueba un operando. Los flags V y C se ponen a 0.
Scc :
compruba los códigos de condición y pone a 1 el operando. Es de tamaño byte.
4.- Instrucciones de desplazamiento y rotación:
Se caracterizan por desplazar o rotar el operando bit a bit a la derecha o a la izquierda. El operando destino, que es el afectado por el desplazamiento o por la rotación siempre será un registro de datos.
ASL: (Arithmetic Shift Left) desplaza a la izquierda los bits del operando destino. El número de desplazamientos viene indicado por el operando origen. El flag V se pone a 1 si el bit más significativo cambia en algún momento y C es el valor del último bit desplazado fuera del operando destino.
ASR: (Arithmetic Shift Right) desplaza a la derecha los bits del operando destino. El número de desplazamientos viene indicado por el operando origen. El flag V se pone a 0, y el C es el valor del último bit desplazado fuera del operando destino.
LSL: (Logical Shift Left) es el desplazamiento lógico a la izquierda. El número de desplazamientos viene indicado por el operando origen. El flag C es el valor del último bit desplazado fuera del operando destino.
LSR: (Logical Shift Right) es el desplazamiento lógico a la derecha. El número de desplazamientos viene indicado por el operando origen. El flag C es el valor del último bit desplazado fuera del operando destino.
ROL: (Rotate Left) rota a la izquierda los bits del operando destino. El número de desplazamientos viene indicado por el operando origen. El flag C es el valor del último bit desplazado fuera del operando destino.
ROR: (Rotate Right) rota a la derecha los bits del operando destino. El número de desplazamientos viene indicado por el operando origen. El flag C es el valor del último bit desplazado fuera del operando destino.
ROXL: (Rotate with Extended Left) rotación a la izquierda con extensión. El número de desplazamientos viene indicado por el operando origen. El flag C es el valor del último bit desplazado fuera del operando destino.
ROXR: (Rotate with Extended Right) rotación a la derecha con extensión. El número de desplazamientos viene indicado por el operando origen. El flag C es el valor del último bit desplazado fuera del operando destino.
SWAP: intercambia el contenido de los 16 bits más significativos con el de los 16 menos significativos, ya que los operandos son de tamaño palabra. Los flags V y C se ponen a 0.
5.- Instrucciones de manipulación de bits:
El Motorola 68000 permite comprobar, poner a cero , poner a uno e invertir los bits individuales de un valor entero.
BTST: (Bit Test) sirve para comprobar el estado de un bit concreto de destino. Actualiza el flag Z en función del valor del bit indicado en la instrucción (Z=1 si el bit es cero). Admite el direccionamiento inmediato y el directo a registro de datos en el operando fuente y en el operando destino todos menos el directo a registro de direcciones.
BCLR: (Bit Clear) pone a 0 el bit indicado. Actualiza el flag Z enfunción del valor original del mismo, poniendolo posteriormente a cero.
BSET: (Bit Set) igual que BCLR, pero poniendo el bit a 1.
BCHG: (Bit Change) en primer lugar actualiza el flag Z en función del valor del bit indicado y luego complementa el bit, es decir lo pone en el valor (0 ó 1) contrario al original.
6.- Instrucciones de operación en código BCD:
De la misma manera que el Motorola 68000 opera con enteros , también permite programar la suma y la resta en código BCD.
ABCD: suma fuente al destino.
NBCD: niega el destino.
SBCD: resta fuente al destino
7.- Instrucciones de ramificación y salto:
Este microproceador incorpora varios mecanismos para poder realizar instrucciones típicas de los lenguajes de alto nivel, como pueden ser los bucles o las instrucciones de condición, siendo el más elemental la instrucción de ramificación, que utiliza como operando una etiqueta, y que sirve para hacer que la próxima instrucción que se ejecute sea la que tenga dicha etiqueta. Cuando el procesador se encuentra con esta instrucción, sencillamente carga la etiqueta en el contador de programa, por lo que la etiqueta es la dirección de donde debe cargarse la próxima instrucción que vaya a ejecutarse.
Bcc : (Branch on condition code) utilizan un único argumento que indica la dirección de la siguiente instrucción en el caso de que se cumpla la condición indicada por cc. Utiliza siempre direccionamiento relativo al contador de programa. cc representa dos letras variables detalladas en la siguiente tabla:
NOMBRE |
CONDICIÓN DE RAMIFICACIÓN |
BEQ |
ETIQUETA |
Z |
BNE |
ETIQUETA |
Z' |
BCS |
ETIQUETA |
(C) |
BCC |
ETIQUETA |
(C') |
BHI |
ETIQUETA |
(C)' · (Z)' |
BLS |
ETIQUETA |
(C) + (Z) |
BMI |
ETIQUETA |
(N) |
BPL |
ETIQUETA |
(N)' |
BVS |
ETIQUETA |
(V) |
BVC |
ETIQUETA |
(V)' |
BGT |
ETIQUETA |
(Z)' · [[(N) · (V)] + [(N)' · (V)']] |
BGE |
ETIQUETA |
[(N) · (V)] +[(N)' · (V)'] |
BLT |
ETIQUETA |
[(N) · (V)'] + [(N)' · (V)] |
BLE |
ETIQUETA |
(Z) + [(N) · (V)'] + [(N)' · (V)] |
DBcc: (Decrement and Branch on Condition Code) facilita la realización de bucles en un programa, y tiene dos argumentos siendo el primero un registro de datos y el segundo un desplazamiento de 16 bits respecto al PC. Su funcionamiento se puede detallar a continuación:
1º Comprueba
la condición cc, si se cumple, pasa a ejecutar la instrucción siguiente
(secuencia normal del programa) y en caso de estar realizando un bucle se
saldría del mismo.
2º Decrementa el contenido del registro de datos.
3º Si el contenido del registro es -1, se ejecuta la
instrucción siguiente (salida del bucle)
4º Modifica el PC con el desplazamiento indicado
(salta al comienzo del bucle).
BRA: (Branch) utiliza direccionamiento relativo al PC, su único argumento es el desplazamiento de 8 ó 16 bits que se suma (con signo) al PC y se obtiene la dirección de la siguiente instrucción a ejecutar. Con desplazamiento corto (8 bits) lossaltos máximos que se pueden realizar son -128 y +127. Con desplazamiento largo ( 16 bits) los saltos máximos son -32.768 y +32.767.
JMP: (Jump) utiliza direccionamiento absoluto y su argumento es la dirección de comienzo de la siguiente instrucción a ejecutar y puede estar situada en cualquier parte del mapa de memoria.
STOP: para la ejecución del pograma de forma controlada y en el punto deseado.
NOP:
(No
Operation) no realiza absolutamente nada. Es una instrucción que no hace sino
consumir tiempo, exactamente 4 ciclos de reloj. Puede parecer absurda la
existencia de una instrucción así, pero tiene su justificación, como por ejemplo
si se desea efectuar un pequeño retraso en la ejecución de un programa con el
fin de sincronizar determinados acontecimientos, o cuando se desea reservar
algunas posiciones del
programa para poder intercalar nuevas instrucciones,
etc.
8.-
Instrucciones de manejo de subrutinas:
BSR y JSR:
(Branch to Subrutine y Jump to Subrutine) el operando asociado con estas
instrucciones debe ser la dirección de memoria en la que se comienza la
subrutina, con direccionamiento absoluto para JSR, y relativo a PC para BSR. Al
ejecutarse cualquiera de las dos instrucciones, se almacena automáticamente en
la pila el valor del contador de programa en el momento anterior al salto,
cuando su contenido apunta a la dirección de comienzo de la instrucción
siguiente a JSR o BSR.
La
subrutina debe tener como última instrucción a ejecutar
RTS
(Return
from Subrutine) o
RTR
(Return and Restore). Ambas recuperan de la pila el valor del contador del
programa, lo que permite reanudar la ejecución del programa precisamente en el
punto que había sido abandonado. La instrucción RTR también repone el CCR
extrayendo una palabra de la pila inmediatamente antes de recuperar el PC. La
subrutina debe llevar a la pila, justamente encima de las posiciones que
contienen la posición de retorno, una palbra cuyos 5 bits menos significativos
serán llevados al CCR al ejecutarse RTR, que puede ser una copia del CCR al
entrar en la subrutina, o cualquier otro valor.