Número 4 · Julio-Septiembre 1995
NOTA: Pulsando sobre las fotos con borde azul ampliarás la imagen.
|
La familia del microprocesador Motorola 68000 siempre ha sido muy bien aceptada por los programadores de ensamblador, principalmente porque su juego de instrucciones es muy completo y fácil de utilizar. Esto, unido a que siempre se ha mantenido una compatibilidad con las instrucciones de procesadores posteriores, ha hecho de este microprocesador uno de los más atractivos para cualquier tipo de aplicación. |
En el anterior capítulo anunciaba que íbamos a ver ya las primeras instrucciones de salto, pero antes vamos a hacer un paréntesis que considero importante. Recapitulando hemos visto ya cómo podemos ensamblar, cuáles son los registros e incluso hemos visto algunas sencillas instrucciones. Ahora quizás sería interesante profundizar en el manejo de esas instrucciones para comenzar a programar, sin embargo, tras reflexionar sobre el tema, creo que sería conveniente tener primero una visión general de los tipos de instrucciones a los que nos vamos a enfrentar.
Dos razones me han motivado a actuar así: la primera es que a los lectores que ya tengan experiencia en programación de otros lenguajes podrán inmediatamente observar paralelismos entre los tipos de instrucciones que maneja en su lenaguaje y los del ensamblador.
La segunda es que para el que se inicia por primera vez, siempre es bueno poder tener una visión de conjunto de lo que se va a aprender antes de perderse en detalles.
Dicho esto, ya podemos comenzar a hablar de lo que sin duda es uno de los temas más interesantes del lenguaje ensamblador: sus instrucciones, o más concretamente en nuestro caso, el juego de instrucciones del M68000.
Tipos de instrucciones
Puede que a primera vista si observamos la tabal de la página siguiente, donde se muestran las 56 instrucciones básicas del 68000, nos parezca que puede ser complejo llegar a conocerlas todas. Sin embargo, rápidamente podremos observar que muchas de las instrucciones realizan la misma tarea y lo único que las diferencia es el tipo de datos con el que trabajan.
Por poner un ejemplo simple. La instrucción básica de suma es ADD. Pero existen 5 tipos diferentes de ADD (ADD; ADDA, ADDQ, ADDI, ADDX) que se diferencian únicamente en el tipo de datos que maneja o en el modo de direccionamiento.
En la mayoría de instrucciones básicas existen variaciones (ver tabla 2), pero afortunadamente para nosotros, siempre son el mismo tipo de variaciones y por lo tanto en cuanto aprendamos las de una, ya las podremos aplicar en las otras.
Vamos a detallar qué tipo de instrucciones existen basándonos en la función que desempeñan:
Instrucciones de transferencia de datos
Probablemente sean las más utilizadas, ya que son las que nos permite mover y copiar datos entre registros y memoria. Normalmente el código de un programa en ensamblador posee más de la mitad de sus instrucciones que pertenecen a este tipo.
"MOVE" es la instrucción que más utilizaremos en adelante, ya que siempre en algún momento de efectuar operaciones entre los datos, hay que copiarlos a los registros o la memoria, según nos interese, por ejemplo para coger los datos o para dejar los resultados.
Como el M68000 puede utilizar distintos tamaños de datos (byte (8bits), word (16 bits) y longword (32 bits)) las instrucciones de transferencia están preparadas de forma que el programador pueda en todo momento determinar que longitud en bits es la que interesa que se transfiera.
Por ejemplo. "MOVE.L d0,d1" indica que moveremos un dato de 32 bits de longitud (la extensión ".L" significa longword), mientras que "MOVE.B d0,d1" moverá un byte.
Instrucciones aritméticas con enteros
Al igual que en otros lenguajes en ensamblador también existen las instrucciones básicas para efectuar operaciones aritméticas. La suma, la resta, la división, la multiplicación y la negación son las únicas que podemos emplear, aunque a partir de estas, podemos hacer combinaciones que nos permitan crear operaciones más complejas.
Por supuesto, existen variaciones de cada una para trabajar con diferentes tamaños de datos y diferentes modos de direccionamiento.
Instrucciones de comparación
Una vez que hemos efectuado una operación aritmética y tenemos el resultado, puede ser necesario que los comparemos con otro valor para comprobarlo y actuar en consecuencia.
Por ejemplo, una de las comparaciones más utilizadas es "CMP d0,d1" o "CMP #0,d0". Comparamos dos registros o un registro y un valor numérico, y después, mediante las instrucciones de salto condicional podremos bifurcar nuestro código según nos convenga.
Las instrucciones de comparar datos, además de otras, utilizan unos bits especiales llamados bits de condición, donde en todo momento se refleja si el dato con el que operamos es cero (bit Z) o negativo (bit N) o si se ha producido acarreo (bit C) o desbordamiento (bit 0).
CONJUNTO INSTRUCCIONES
LENGUAJE MÁQUINA DEL M68000 |
| Instrucción |
Description |
Descripción |
| ABCD |
Add Decimal with Extend |
Suma Decimal con Extensión de Signo |
| ADD |
Add |
Suma |
| AND |
Logical And |
Y Lógica |
| ASL |
Arithmetic Shift Left |
Desplazamiento Aritmético a la Izquierda |
| ASR |
Arithmetic Shift Right |
Desplazamiento Aritmético a la Derecha |
| Bcc |
Bracnch Conditionally |
Salto Condicional |
| BCHG |
Bit Test and Change |
Comprueba Bit y Cambia |
| BCLR |
Bit Test and Clear |
Comprueba Bit y Desactiva (a 0) |
| BRA |
Branch Always |
Salto Incondicional |
| BSR |
Branch to Subroutine |
Salto a Subrutina |
| BTST |
Bit Test |
Comprueba Bit |
| CHK |
Check Register Against Bounds |
Chequea Registro |
| CLR |
Clear Operand |
Borrar Operando |
| CMP |
Compare |
Comparar |
| DBcc |
Test Condition, Decrement and Branch |
Comprueba Condición, Decrementa y Salta |
| DIVS |
Signed Divide |
Divide con Signo |
| DIVU |
Unsigned Divide |
Divide sin Signo |
| EOR |
Exclusive Or |
O Exclusiva |
| EXG |
Exchange Registers |
Intercambia Registros |
| EXT |
Sign Extend |
Extiende el Signo |
| JMP |
Jump |
Salto |
| JSR |
Jump to Subroutine |
Salta a Subrutina |
| LEA |
Load Effective Adress |
Carga Dirección Efectiva |
| LINK |
Link Stack |
Une la Pila |
| LSL |
Logical Shift Left |
Desplazamiento Lógico a la Izquierda |
| LSR |
Logical Shift Right |
Desplazamiento Lógico a la Derecha |
| MOVE |
Move |
Mover |
| MOVEM |
Move Multiple Registers |
Mover Varios Registros |
| MOVEP |
Move Peripheral Data |
Mover Data de Periférico |
| MULS |
Signed Multiply |
Multiplicación con Signo |
| MULU |
Unsigned Multiply |
Multiplicación sin Signo |
| NBCD |
Negate Decimal with Extend |
Negación Decimal con Extensión de Signo |
| NOP |
No Operation |
No efectuar ninguna Operación |
| NO |
Ones Complement |
Complemento a uno |
| OR |
Logical Or |
O Lógico |
| PEA |
Push Effective Adress |
Coloca en la pila la dirección efectiva |
| RESET |
Reset External Devices |
Reinicializa Periféricos Externos |
| ROL |
Rotate Left without Extend |
Rotar a la Izquierda sin Extensión de Signo |
| ROR |
Rotate Right without Extend |
Rotar a la Derecha sin Extensión de Signo |
| ROXL |
Rotate Left with Extend |
Rotar a la Izquierda con Extensión de Signo |
| ROXR |
Rotate Right with Extend |
Rotar a la Derecha con Extensión de Signo |
| RTE |
Return from Exception |
Retomar de una Excepción |
| RTR |
Return and Restore |
Retornar y Restaurar |
| RTS |
Return from Subroutine |
Retornar de una SUbrutina |
| SBCD |
Subtract Decimal with Extend |
Resta Decimal con Extensión de Signo |
| Scc |
Set Conditional |
Activar Condicionalmente |
| STOP |
Stop |
Parar |
| SUB |
Subtract |
Restar |
| SWAP |
Swap Data Register Halves |
Intercambia las mitades de un Registro |
| TAS |
Test and Set Operand |
Comprueba y Activa Operando |
| TRAP |
Trap |
Salto a excepción |
| TRAPV |
Trap on Overflow |
Salta a excepción si existe desbordamiento |
| TST |
Test |
Comprueba |
| UNLK |
Unlink |
Rompe la Unión |
|
|
|
|
|
|
| INSTRUCCIONES CON VARIACIONES DE FUNCIÓN Y FORMATO |
| Tipo de Instrucción |
Variación |
Description Descripción |
| ADD |
|
|
| ADD |
Add |
Suma |
| ADDA |
Add |
Address Suma Dirección |
| ADDQ |
Add Quick |
Suma Rápida |
| ADDI |
Add Inmediate |
Suma Inmediata |
| ADDX |
Add with Extend |
Suma con extensión de Signo |
| AND |
|
|
| AND |
Logical AND |
Y lógico |
| ANDI |
AND Immediate |
Y lógico inmediato |
| ANDI to CCR |
AND Immediate |
to Condition Code Y lógico con el Código de COndición |
| ANDI to SR |
AND Immediate |
to Status Register Y lógico con el Registro de Estado |
| CMP |
|
|
| CMP |
Compare |
Comparar |
| CMPA |
Compare Address |
Comparar Dirección |
| CMPM |
Compare Memory |
Comparar Memoria |
| CMPI |
Compare Immediate |
Comparar dato inmediato |
| EOR |
|
|
| EOR |
Exclusive OR |
O exclusiva lógica |
| EORI |
Exclusive OR Immediate |
O exclusiva lógica con dato inmediato |
| EORI to CCR |
Exclusive Immediate |
to Condition Codes O exclusiva lógica con el Código de Condición |
| EORI to SR |
Exclusive OR Immediate |
to Status Register O exclusiva lógica con el Registro de Estado |
| MOVE |
|
|
| MOVE |
Move |
Mover |
| MOVEA |
Mover Address |
Mover Dirección |
| MOVEQ |
Move Quick |
Mover Dato inmediato |
| MOVE to CCR |
Move to Condition Codes |
Mover al Código de Condición |
| MOVE to SR |
Move to Status Register |
Mover del Registro de Estado |
| MOVE to USP |
Move to User Stack Pointer |
Mover al Puntero de Pila de Usuario |
| NEG |
|
|
| NEG |
Negate |
Negar |
| NEGX |
Negate with Extend |
Negar con Extensión |
| OR |
|
|
| OR |
Logical OR |
O lógico |
| ORI |
OR Immediate |
O lógico con dato inmediato |
| ORI to CCR |
OR Immediate to Condition Codes |
O lógico con el Código de Condición |
| ORI to SR |
OR Inmmediate to Status Register |
O lógico con el Registro de Estado |
| SUB |
|
|
| SUB |
Subtract |
Restar |
| SUBA |
Subtract Address |
Restar Dirección |
| SUBI |
Subtract Immediate |
Restar Data inmediato |
| SUBQ |
Subtract Quick |
Resta Rápida |
| SUBX |
Subtract with Extend |
Resta con Extensión de Signo |
|
|
|
|
Instrucciones de salto condicional
Tal y como su nombre indica, las instrucciones saltan a otra parte del código sólo si una determinada condición se cumple. Esta condición queda reflejada en los bits de condición que hemos comentado anteriormente al hablar de comparaciones. Por ejemplo, una de las que más utilizaremos será Bcc, donde "B" es "Branch" o "Bifurcación" y "cc" es "conditional code" o "código de condición". Existen multitud de variaciones de Bcc, por ejemplo, BEQ (salto si igual), BNE (salto si no igual), BGT (salto si mayor que), etc.
Estas instrucciones suelen estar precedidas por una instrucción CMP para actualizar los bits de condición justo antes de ejecutar la instrucción de salto. Por esta razón es muy normal ver parejas de instrucciones de CMP y Bcc.
Instrucciones de salto incondicional
Podría ser que en algún momento de nuestro programa necesitemos saltar obligatoriamente a otra parte, por ejemplo, para tratar un error fatal.
Con instrucciones como "JMP" o "BRA" se bifurcará nuestro código hacia donde le indiquemos, y son equivalentes al GOTO de otros lenguajes, sólo que en ensamblador no está prohibido utilizarlo ya que no es un lenguaje fundamentalmente estructurado (como lo es C o Modula).
Instrucciones de operaciones lógicas
Tan importante o más que las operaciones aritméticas son las instrucciones que nos permiten operar lógicamente a nivel de bits. Todo programador de ensamblador debe conocer como mínimo el funcionamiento y las tablas de verdad de las operaciones lógicas OR, AND, NOT y EOR. En próximos artículos aparecerán estas instrucciones y profundizaremos más en este tema.
Instrucciones de rotación de bits
Puede parecer a primera vista un tanto extraño disponer de instrucciones que permitan rotar los bits de un dato. Sin embargo, la operación de rotar provoca determinados resultados, como por ejemplo multiplicar o dividir el número por la potencia de 2. La razón de que se emplee normalmente la operación de rotación para multiplicar o dividir por potencias de dos es que es extremadamente más rápido que utilizar las propias instrucciones "DIV" o "MUL".
Continuaremos el próximo mes...
|