MIA-Unidad 7 ()

Anuncio
85
MÓDULO III
PROGRAMACIÓN DEL MICROPROCESADOR
El módulo III está conformado por las unidades 7 y 8. El estudio de estas
unidades, permite desarrollar en el estudiante las competencias necesarias en
la solución de problemas, haciendo uso de los microprocesadores.
El desarrollo de la solución implicará, la codificación de algoritmos en el
lenguaje ensamblador del microprocesador Intel 80286 y la implementación del
programa codificado en un microprocesador de este tipo. El programa así
codificado, se ejecutará en un software simulador, el cual proporciona un
modelo real de un microprocesador Intel 80286.
Objetivo del Módulo III:
Implementar con sentido lógico y creativo,
programas específicos, haciendo uso de los microprocesadores.
El módulo III está estructurado en dos unidades:
Unidad 7:
Unidad 8:
Programación en Lenguaje Ensamblador
Implementación de Programas en el Microprocesador
86
UNIDAD 7
Programación en Lenguaje Ensamblador
Los programas que convierten un programa de usuario escrito en algún
lenguaje, a otro lenguaje, se llaman traductores. El leguaje en el que está
escrito el programa original se llama lenguaje fuente, y el lenguaje a que se
convierte se llama lenguaje objeto o lenguaje de máquina. El lenguaje fuente
es en lo esencial una representación simbólica (lenguaje mnemotécnico) de un
lenguaje de máquina numérico, el traductor se llama lenguaje ensamblador.
Las computadoras siguen utilizando el lenguaje de máquina para procesar los
datos, pero los programas ensambladores traducen antes los símbolos de
código de operación especificados a sus equivalentes en lenguaje de máquina.
Este proceso es al que se le denomina ensamblado de código. Para facilitar la
elaboración de programas a este nivel, se desarrollaron los Ensambladores y
el Lenguaje Ensamblador.
En la unidad 5 se presenta el uso del lenguaje ensamblador, específicamente
el correspondiente al microprocesador 80286. El estudio de esta unidad
afianzará en el estudiante los conocimientos obtenidos en el curso,
especialmente en lo que respecta a la programación
Objetivo de la Unidad 7: Codificar algoritmos, utilizando un lenguaje
ensamblador y las técnicas apropiadas, para la resolución de un problema
específico.
Contenido de la Unidad 7: El contenido de la unidad contempla el estudio de
los siguientes temas:
Lenguaje ensamblador, Lenguaje de máquina
Mnemónicos, Conjunto de instrucciones de un
microprocesador específico
Programación modular
Codificación de algoritmos en un lenguaje ensamblador
específico
87
Actividades recomendadas para el estudio del contenido de la unidad 7.
1.- Lea el capítulo 7 del texto Los Microprocesadores Intel, B. B. Brey.
2.- Lea los siguientes contenidos teóricos:
Lenguaje de Máquina
Es el sistema de códigos directamente interpretable por un circuito
microprogramable, como el microprocesador de un ordenador o el
microcontrolador de un autómata (un PIC). Este lenguaje está compuesto por
un conjunto de instrucciones que determinan acciones a ser tomadas por la
máquina. Un programa de computadora consiste en una cadena de estas
instrucciones de lenguaje de máquina (más los datos). Estas instrucciones son
normalmente ejecutadas en secuencia, con eventuales cambios de flujo
causados por el propio programa o eventos externos. El lenguaje de máquina
es específico de cada máquina o arquitectura de la máquina, aunque el
conjunto de instrucciones disponibles pueda ser similar entre ellas.
http://es.wikipedia.org/wiki/Lenguaje_m%C3%A1quina
Mnemónico
En Informática un Mnemónico es una palabra que sustituye a un código de
operación (Lenguaje de máquina), con lo cual resulta más fácil la
programación, es de aquí de donde resulta el concepto de lenguaje
ensamblador.
Un ejemplo común de mnemónico es la instrucción MOV, que le indica al
microprocesador que debe de mover datos de un lugar a otro. El
microprocesador no entiende palabras, sino que números binarios, por lo que
es necesario la traducción del mnemónico a código objeto.
http://es.wikipedia.org/wiki/Mnem%C3%B3nico
Lenguaje Ensamblador.
Una CPU puede interpretar y ejecutar instrucciones de máquina. Estas
instrucciones son, simplemente, números binarios almacenados en el
computador. Sin un programador quisiera programar directamente en lenguaje
de máquina, necesitaría introducir los programas como datos binarios.
Considere la sencilla sentencia BASIC:
N=I+J+K
Suponga que queremos programar esta sentencia en un lenguaje de máquina y
dar a I, J y K los valores iniciales 2,3, y 4, respectivamente. La forma de hacer
esto se muestra en la figura 7.1a. El programa empieza en la posición 101
88
(hexadecimal). Se reserva memoria parea las cuatro variables a partir de la
posición 201. El programa consta de cuatro instrucciones:
1.
2.
3.
4.
Cargar el contenido de la posición 201 en el acumulador (AC).
Sumar a AC el contenido de la posición 202.
Suma a AC el contenido de la posición 203.
Memorizar el contenido de AC en la posición 204.
Esto es claramente un proceso tedioso y muy susceptible de errores. Una
ligera mejora consiste en redactar el programa en hexadecimal, e lugar de en
binario, ver figura 7.1b.
Para que la mejora sea más significativa, podemos hacer uso de nombres
simbólicos o mnemotécnicos de las instrucciones. El resultado es el programa
simbólico mostrado en la figura 7.1c. Cada línea sigue representando una
posición de memoria, y consta de tres campos separados por espacios. El
primer campo contiene la dirección de una posición. El segundo campo
contiene el símbolo de tres letras que representa su código de operación. Si se
trata de una instrucción que hace referencia a memoria, un tercer campo
contiene la dirección. Para memorizar un dato concreto en una posición dada,
nos inventamos una pseudoinstrucción con el símbolo DAT. Esta es
meramente un indicador de que el tercer campo de la línea contiene un número
en hexadecimal a memorizar en la posición que especifica el primer campo.
El uso de programas simbólicos hace la vida mucho más fácil, pero es aun
engorroso. En particular hay, hay que dar una dirección absoluta para cada
palabra. Un procedimiento mejor, es emplear direcciones simbólicas. Esto se
ilustra en la figura 7.1d. Cada línea sigue teniendo tres campos. El primero
sigue siendo para la dirección, pero se utiliza un símbolo en lugar de una
dirección numérica absoluta. Algunas líneas carecen de dirección, indicando
que la dirección de dicha línea es uno más que la dirección precedente. Para
las instrucciones que hacen referencia a memoria, el tercer campo contiene
también una dirección simbólica.
Con este último refinamiento, hemos inventado un lenguaje ensamblador. Los
programas escritos en lenguaje ensamblador (programas en ensamblador) se
traducen a lenguaje de máquina mediante un ensamblador.
El desarrollo de los lenguajes ensambladores fue un logro importante en la
evolución de la tecnología de computadores. Fue el primer paso hacia los
lenguajes de alto nivel de hoy en día.
89
Dirección
101
102
103
104
0010
0001
0001
0011
Contenido
0010
0000
0010
0000
0010
0000
0010
0000
0001
0010
0011
0100
101
102
103
104
LDA
ADD
ADD
STA
201
202
203
204
201
202
203
204
0000
0000
0000
0000
0000
0000
0000
0000
0010
0011
0100
0000
201
202
203
204
DAT
DAT
DAT
DAT
2
3
4
0
0000
0000
0000
0000
(a) Programa en binario
(c) Programa simbólico
Dirección
101
102
103
104
Contenido
2201
1202
1203
3204
Etiqueta
FORMUL
Operación
LDA
ADD
ADD
STA
Operando
I
J
K
N
201
202
203
204
0002
0003
0004
0000
I
J
K
N
DATA
DATA
DATA
DATA
2
3
4
0
(a) Programa en hexadecimal
(c) Programa en ensamblador
Figura 7.1. Cálculo de la fórmula N = I + J + K.
Stallings, 2000.pp. 346.
Conjunto de instrucciones
Un conjunto de instrucciones ó repertorio de instrucciones ó ISA (del inglés
instruction set architecture -arquitectura del conjunto de instrucciones-) es una
especificación que detalla las instrucciones que una CPU de un ordenador
puede entender y ejecutar, o el conjunto de todos los comandos
implementados por un diseño particular de una CPU. El término describe los
aspectos del procesador generalmente visibles a un programador, incluyendo
los tipos de datos nativos, las instrucciones, los registros, la arquitectura de
memoria y las interrupciones, entre otros aspectos.
La arquitectura del conjunto de instrucciones (ISA) se emplea a veces para
distinguir este conjunto de características de la microarquitectura, que son los
elementos y técnicas que se emplean para implementar el conjunto de
instrucciones. Entre estos elementos se encuentras las microinstrucciones y los
sistemas de caché.
Procesadores con diferentes diseños internos pueden compartir un conjunto de
instrucciones; por ejemplo el Intel Pentium y AMD Athlon implementan
90
versiones casi idénticas del conjunto de instrucciones x86, pero tiene diseños
internos completamente opuestos.
http://es.wikipedia.org/wiki/Conjunto_de_instrucciones
Diseño del repertorio de instrucciones
Uno de los aspectos más interesantes y más analizado del diseño de un
computador, es el diseño del repertorio de instrucciones del lenguaje de
máquina. El diseño de un repertorio de instrucciones es muy complejo, ya que
afecta a muchos aspectos del computador. El repertorio de instrucciones define
muchas de las funciones realizadas por la CPU y tiene, por tanto, un efecto
significativo sobre la implementación de la misma. El repertorio de
instrucciones es el medio que tiene el programador para controlar la CPU.
Algunos de los aspectos más básicos relativos al diseño son los siguientes:
•
•
•
•
•
Repertorio de operaciones: Cuántas y qué operaciones considerar, y
cuán complejas deben ser.
Tipos de datos: Los distintos tipos de datos con los que se efectúan las
operaciones.
Formato de instrucciones: Longitud de la instrucción (bits), número de
direcciones, tamaño de los distintos campos, etc.
Registros: Número de registros de la CPU que pueden ser referenciados
por instrucciones, y su uso.
Direccionamiento: El modo o modos de direccionamiento mediante los
cuales puede especificarse la dirección del operando.
Stallings, 2000. pp. 318.
El microprocesador Intel 80286
El Intel 80286 (llamado oficialmente iAPX 286, también conocido como i286 o
286) es un microprocesador de 16 bits de la familia x86, que fue lanzado al
mercado por Intel el 1 de febrero de 1982. Las versiones iniciales del i286
funcionaban a 6 y 8 MHz, pero acabó alcanzando una velocidad de hasta 20
MHz. El i286 fue el microprocesador más empleado en los IBM PC y
compatibles entre mediados y finales de los años 80.
El i286 funciona el doble de rápido por ciclo de reloj que su predecesor (el Intel
8086) y puede direccionar hasta 16 Mbytes de memoria RAM, en
contraposición a 1 Mbyte del i8086. En máquinas DOS, esta memoria adicional
solo podía ser accedida a través de emulación de memoria extendida. De todos
modos, pocos ordenadores basados en el i286 tuvieron más de 1 Mbyte de
memoria.
El i286 fue diseñado para ejecutar aplicaciones multitarea, incluyendo
comunicaciones (como centralitas automatizadas), control de procesos en
tiempo real y sistemas multiusuario. Para ello se le añadió un modo protegido,
91
en el cual existían cuatro anillos de ejecución y división de memoria mediante
tablas de segmentos. En este modo trabajaban las versiones de 16 bits del
sistema operativo OS/2.
A pesar de su gran popularidad, hoy en día quedan pocos ordenadores con el
i286 funcionando. El sucesor del i286 fue el Intel 80386, de 32 bits.
http://es.wikipedia.org/wiki/Intel_80286
3.- En el ejemplo 7.1, se muestra un programa fuente que permite desplegar un
mensaje en pantalla mediante llamadas al DOS.
Ejemplo 7.1: Programa fuente que imprime un mensaje en la pantalla.
Aquí se tratará todo lo concerniente con el lenguaje ensamblador y el conjunto
de directivas del Microsoft Macro Assembler v4.0. Si bien esto puede resultar
bastante extenso y complejo, aquí sólo se describirán las instrucciones y
directivas básicas.
Para comenzar se presenta un pequeño ejemplo que ilustra el formato del
programa fuente. Este ejemplo está completamente desarrollado en lenguaje
ensamblador que usa servicios o funciones de MS-DOS (system calls) para
imprimir el mensaje Hola mundo en pantalla.
; HOLA.ASM
; Programa clasico de ejemplo. Despliega una leyenda en pantalla.
STACK SEGMENT STACK
; Segmento de pila
DW 64 DUP (?)
; Define espacio en la pila
STACK ENDS
DATA
SEGMENT
; Segmento de datos
SALUDO
DB "Hola mundo",13,10,"$" ; Cadena
DATA
ENDS
CODE
SEGMENT
; Segmento de Código
ASSUME CS:CODE, DS:DATA, SS:STACK
INICIO:
MOV AX,DATA
MOV DS,AX
MOV DX,OFFSET SALUDO
MOV AH,09H
INT 21H
MOV AH,4CH
INT 21H
CODE
ENDS
END INICIO
; Punto de entrada al programa
; Pone dirección en AX
; Pone la direccion en los registros
; Obtiene direccion del mensaje
; Función: Visualizar cadena
; Servicio: Funciones alto nivel DOS
; Función: Terminar
; Marca fin y define INICIO
92
La descripción del programa es como sigue:
•
Las declaraciones SEGMENT y ENDS definen los segmentos a usar.
•
La variable SALUDO en el segmento DATA, define la cadena a ser
desplegada. El signo de dólares al final de la cadena (denominado
centinela) es requerido por la función de visualización de la cadena de
MS-DOS. La cadena incluye los códigos para carriage-return y line-feed.
•
La etiqueta INICIO en el segmento de código marca el inicio de las
instrucciones del programa.
•
La declaración DW en el segmento de pila define el espacio para ser
usado por el stack del programa.
•
La declaración ASSUME indica que registros de segmento se asociarán
con las etiquetas declaradas en las definiciones de segmentos.
•
Las primeras dos instrucciones cargan la dirección del segmento de
datos en el registro DS. Estas instrucciones no son necesarias para los
segmentos de código y stack puesto que la dirección del segmento de
código siempre es cargada en el registro CS y la dirección de la
declaración del stack segment es automáticamente cargada en el
registro SS.
•
Las últimas dos instrucciones del segmento CODE usa la función 4CH
de MS-DOS para regresar el control al sistema operativo. Existen
muchas otras formas de hacer esto, pero ésta es la más recomendada.
•
La directiva END indica el final del código fuente y especifica a START
como punto de arranque.
5.- El ejemplo 7.2 muestra la importancia del uso de las directivas PUBLIC y
EXTRN en la programación modular.
Ejemplo 7.2: Uso de directivas PUBLIC y EXTRN.
A continuación se presentan dos módulos de programa: MAIN y TASK, el
primer módulo corresponde al módulo principal, mientras que el segundo al
módulo que contiene una rutina. Ambos módulos son archivos que se editan
por separado, se ensamblan por separado, pero se ligan juntos.
93
MODULO PRINCIPAL: MAIN.ASM
NAME
MAIN
PUBLIC EXIT
EXTRN PRINT:NEAR
STACK SEGMENT WORD STACK 'STACK'
DW
64 DUP(?)
STACK ENDS
DATA
DATA
CODE
SEGMENT WORD PUBLIC 'DATA'
ENDS
SEGMENT BYTE PUBLIC 'CODE'
ASSUME CS:CODE, DS:DATA
START:
MOV AX, DATA
MOV DS, AX
JMP PRINT
; carga localización del segmento
; en el registro DS
; va a PRINT en el otro modulo
EXIT:
MOV AH, 4CH
INT 21H
CODE ENDS
END START
SUBMODULO: TASK.ASM
NAME TASK
PUBLIC PRINT
EXTRN EXIT:NEAR
DATA
SEGMENT WORD PUBLIC 'DATA'
ENTRADA DB
"Entrando a un submodulo....",13,10,"$"
SALIDA DB
".......saliendo del submodulo.",01,07,13,10,"$"
DATA
ENDS
CODE
SEGMENT BYTE PUBLIC 'CODE'
ASSUME CS:CODE, DS:DATA
PRINT:
MOVE AH,06H
; Función para borrar pantalla
MOV
AL,0
; todas las líneas
MOV
CX,0
; de 0,0
MOV
DH,24D
MOV
DL,79D
MOV
BH,0
; atributo en líneas vacías
INT
10H
; Ser vicio de e/s vídeo
MOV
DX, OFFSET ENTRADA
MOV
AH,09H
INT
21H
MOV
DX, OFFSET SALIDA
INT
21H
94
CODE
JMP
ENDS
END
EXIT
; Regresa al otro modulo
Ejercicios propuestos
1.- Codifique una rutina en el lenguaje ensamblador del 80286 que permita el
ingreso de caracteres, verificando si se ha oprimido una tecla pero sin
esperar que ocurra. Si esto ha ocurrido entonces devuelve su codificación
ASCII en un registro; en caso contrario devuelve cero.
2.- Considere una cadena como una secuencia de caracteres terminada por un
byte cero, y se requiere calcular su longitud.
Con base a lo antes planteado, codifique en el lenguaje ensamblador 80286
un algoritmo que permita calcular la longitud de la cadena de caracteres.
Consulta en otros libros
[Stallings 2000] Incluye el repertorio de instrucciones de dos familias de
computadores: el Pentium II de Intel y el Power PC.
[Englander 2002] Incluye la descripción del conjunto de instrucciones de la
familia x86.
Consulta en la Web
http://proton.ucting.udg.mx/dpto/maestros/mateos/novedades/ensamblador/68H
C11.html:Contiene información interesante relacionada con el lenguaje
ensamblador.
http://www.alpertron.com.ar/80286.HTM: Describe el microprocesador 80286 y
las instrucciones adicionales que controlan el sistema de memoria
virtual.
Ejercicios de Autoevaluación
1.- Desarrolle un procedimiento llamado SUMS, que permita sumar el valor del
contenido de los registros BX, CX y DX con el contenido de AX. Utilice la
definición de procedimiento cercano (NEAR).
95
2.-Codifique un programa que despliegue OK en la pantalla del monitor,
utilizando para ello el procedimiento DISP mostrado a continuación:
DISP
DISP
PROC
MOV
INT
RET
ENDP
NEAR
AH, 2
21H
Respuesta a los Ejercicios de Autoevaluación
1.- El procedimiento es el siguiente:
SUMS
SUMS
PROC
NEAR
ADD AX, BX
ADD AX, CX
ADD AC, DX
RET
ENDP
2.- A continuación se muestra el programa:
.MODEL
.CODE
STARTUP
TINY
MOV
MOV
CALL
MOV
CALL
.EXIT
END
BX, OFFSET DISP
DL, ‘O’
BX0
DL, ‘K’
BX
Descargar