Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf ·...

408
División de Ciencias Básicas e Ingeniería Departamento de Ingeniería Eléctrica Licenciatura de Ingeniería Eléctrica Desarrollo de un depurador/ensamblador, y mejora del software Monitor para la tarjeta de experimentación UAMI188EB Presentado por: Alarcón Ramos Luis Angel 94316524 Asesor: M. en C. Agustín Suárez Fernández México D.F. Noviembre del 2005

Transcript of Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf ·...

Page 1: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

División de Ciencias Básicas e Ingeniería

Departamento de Ingeniería Eléctrica

Licenciatura de Ingeniería Eléctrica

Desarrollo de un depurador/ensamblador, y mejora del software Monitor para la tarjeta de experimentación UAMI188EB

Presentado por:

Alarcón Ramos Luis Angel 94316524

Asesor:

M. en C. Agustín Suárez Fernández

México D.F. Noviembre del 2005

Page 2: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor
Page 3: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

I

Contenido

Pag.

Introducción 1

Capitulo 1. La tarjeta de experimentación UAMI188EB

1.1 Introducción 3 1.2 El microprocesador 80C188EB 3

1.2.1 Los temporizadores 4 1.2.2 Unidad de Chip-Select 5 1.2.3 Unidad de control de interrupciones 7 1.2.4 Puertos de entrada/salida (I/O) 8 1.2.5 Unidad de comunicación serie 10 1.2.6 Los registros del 80C188EB 11

1.3 Unidades de memoria 12 1.4 Puerto serie 14 1.5 Display 15 1.6 Otros dispositivos 16 1.7 Descripción de la UAMI188EB 17 1.8 Arranque de la UAMI188EB

Capitulo 2. El BIOS de la UAMI188EB

2.1 Introducción 2.2 Arranque del BIOS 2.2.1 Configuración del Chip-Select 2.2.2 Configuración del display 2.2.3 Revisión de la memoria RAM y ROM 2.2.4 Carga de valores iniciales en memoria de configuración 2.2.5 Inicio de los vectores de interrupción 2.2.6 Inicio del hardware de la UAMI188EB 2.2.7 Ambiente del programa Monitor 2.2.8 Carga del Monitor 2.3 Modelo del sistema

Capitulo 3. El programa Monitor

3.1 Introducción 3.2 Funcionamiento del Monitor 3.3 El estado de la UAMI188EB 3.4 Los comandos 3.5 Comunicación de comandos 3.5.1 CMSOK 3.5.2 CMSRESET

Page 4: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

II

3.5.3 CMSCARGA 3.5.4 CMSEJECUTAR y CMSPASO 3.5.5 CMSEND 3.5.6 CMSERROR 3.5.7 CMSOBTENMEM y CMSOBTENPRG 3.5.8 CMSMUEVEMEM 3.5.9 CMSDETENER 3.5.10 CMSDESCONECT y CMSCONECT 3.5.11 CMSOBTENRET 3.5.12 CMSOBTENERR 3.5.13 CMSOBTENREG 3.5.14 CMSCARGAREG 3.5.15 CMSCARGAMEM 3.5.16 CMSACERCADE 3.5.17 CMSRESIDENTE 3.5.18 CMSFIJAHORA 3.6 Código residente 3.7 Trazado de programas 3.7.1 Interrupción 01H 3.7.2 Interrupción 03H

Capitulo 4. El programa D188.EXE

4.1 Introducción 4.2 Estructura del programa D188.EXE 4.3 Interfaz visual 4.3.1 Jerarquía y herencia entre clases 4.3.2 Estructura de una aplicación en Turbo Vision 4.3.3 Los objetos visibles en Turbo Vision 4.4 Interfaz de comunicación 4.4.1 Activación, reinicio y desactivación del puerto serie 4.4.2 Manejo de la interrupción del puerto serie 4.4.3 Recepción de datos vía interrupción 4.4.4 Envío y recepción de datos

Capitulo 5. El ensamblador de la UAM188EB

5.1 Introducción 5.2 Estructura y funcionamiento del ensamblador 5.2.1 Listas de instrucción, de constantes y etiquetas 5.3 El convertidor de línea 5.3.1 Separación en tokens 5.3.2 Instrucciones sin argumentos. 5.3.3 Análisis de argumentos 5.3.4 Notación de los argumentos en código máquina

Page 5: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

III

5.3.5 Instrucciones de un argumento 5.3.6 Instrucciones de dos argumentos 5.3.7 Instrucciones especiales 5.3.8 Palabras reservadas 5.3.9 Análisis de etiquetas o constantes 5.4 El ensamblador de código

Capitulo 6. El depurador de la UAM188EB

6.1 Introducción 6.2 Estructura del depurador 6.3 La interfaz de usuario 6.4 Convertidor de ensamblador a código máquina 6.5 Convertidor de código máquina a ensamblador

Page 6: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

IV

Apéndice A. Manual de usuario

A.1 Introducción A.1.1 Programa D188.EXE A.1.2 Programa BIOSM.COM A.1.3 Requisitos del programa A.2 Descripción del programa D188.EXE A.2.1 La barra de menú A.2.2 Cuadros de dialogo A.2.3 Ventanas A.3 Comandos del menú A.3.1 Archivo A.3.2 Edición A.3.3 Búsqueda A.3.4 Compilar A.3.5 UAMI188EB A.3.6 Depuración A.3.7 Ventanas A.4 Programación A.4.1 Palabras reservadas del D188.EXE A.4.2 Esquema de programación A.4.3 Declaración de constantes A.4.4 Procedimientos y etiquetas A.4.5 Variables y cadenas A.4.6 Empleo de varios archivos A.4.7 Cambio de offset A.5 Depuración de programas A.6 Ejemplos

Apéndice B. Lista de interrupciones del BIOS

B.1 Introducción B.2 Descripción de las interrupciones

Apéndice C. Mapa de memoria de la UAMI188EB.

C.1 Introducción C.2 Mapa de memoria

Apéndice D. Lista de procedimientos y funciones

D.1 Introducción D.2 Procedimientos del BIOS y Monitor relacionados con comandos D.3 Funciones del D188.EXE relacionados con comandos

Page 7: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

V

Apéndice E. Código fuente del BIOS y el Monitor

E.1 CONST.ASM E.2 BIOSVARS.ASM E.3 CHIPSEL.ASM E.4 INITDSP.ASM E.5 CHKMEM.ASM E.6 INITVARS.ASM E.7 INITVEC.ASM E.8 INITHARD.ASM E.9 INT00.ASM E.10 INT01Y03.ASM E.11 INT04.ASM E.12 INT05.ASM E.13 INT06.ASM E.14 INT07.ASM E.15 INT10.ASM E.16 INT16.ASM E.17 INT19.ASM E.18 INT1A.ASM E.19 INT1C.ASM E.20 INT20.ASM E.21 INT21.ASM E.22 INT27.ASM E.23 INT60.ASM E.24 INT61Y62.ASM E.25 INT63.ASM E.26 INT70.ASM E.27 KEYBOARD.ASM E.28 RELOJ.ASM E.29 SERIAL.ASM E.30 MONITOR.ASM E.31 ERRINT.ASM E.32 DEPURA.ASM

Apéndice F. Código fuente del D188.EXE

F.1 F.2

Page 8: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

1

Introducción La gran mayoría de los sistemas computacionales, se rigen bajo una misma arquitectura; todos cuentan con un procesador, memoria, dispositivos de control1 y un medio de comunicación con el exterior. Con todo lo anterior, estos sistemas son capaces de recibir ordenes o instrucciones, procesarlas y llegar a un resultado. Para entender el funcionamiento de una computadora, solo se toma en cuenta algunos de los elementos que lo conforman; a esto se le conoce como sistema mínimo. Un sistema mínimo consta de procesador, memoria y un medio de comunicación. Las computadoras solamente son capaces de entender a las instrucciones como cadenas de 1’s y 0’s (estas cadenas se conocen también como lenguaje maquina), en donde a cada 1 o 0 se le denomina bit; es decir, un bit puede tomar dos valores, un 1 o un 0. Las

longitudes de estas cadenas son múltiplos de una longitud fija, que puede ser de 8, 16, 32 y en la actualidad de 64 bits, a esto se le conoce como tamaño de palabra; a la longitud básica de palabra, 8 bits, se le conoce como byte. Es por medio de estas cadenas de bytes que es posible programar una computadora; cada cadena de bytes tiene un significado para la computadora y esta realiza una operación. Como se puede observar, debido a sus características programar un sistema mínimo puede resultar algo tedioso y difícil; sin embargo, no se programa escribiendo cadenas de 1’s y 0’s, en lugar de ello emplea un ensamblador. Un ensamblador traduce un conjunto de instrucciones (este conjunto también se conoce como lenguaje ensamblador) a lenguaje maquina; cada instrucción es un mnemónico del nombre de la operación que realiza el computador; así por ejemplo, si se desea mover un byte de una localidad de memoria a otra, en lugar de colocar 0010110110110101, simplemente se pone MOV (de move en ingles) y el ensamblador hará el resto. El sistema mínimo no posee un teclado, un monitor o algún otro medio de comunicación, mucho menos un software que controle la maquina (por ejemplo un sistema operativo); por lo que programar un sistema mínimo requiere de los siguientes pasos:

• Crear un programa en lenguaje ensamblador

• Ensamblarlo para convertirlo a lenguaje maquina

• Transferirlo al sistema mínimo por medio de una memoria ROM. Esto se logra trasfiriendo el programa a una memoria de solo lectura, por medio de un grabador de memorias.

1 Existe una gran cantidad de dispositivos, algunos ejemplos son: un controlador de video, un monitor, controlador de teclado, un teclado, un modem, el ratón, etc.

Page 9: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

2

• Esperar que el sistema ejecute las instrucciones y arroje el resultado de alguna forma (por medio de Leds o un display).

El interés es entender el funcionamiento interno de una computadora; es decir, en la actualidad existen herramientas con las cuales fácilmente se puede programar una computadora sin la preocupación de lo que ocurre dentro de esta, se conoce al computador pero superficialmente. Es de destacar, que si se busca un mejor aprovechamiento de los recursos de una computadora, o simplemente crear estas herramientas que nos permiten programar fácilmente, es necesario conocer muy bien lo que ocurre dentro, y un sistema mínimo ofrece este conocimiento. El sistema mínimo que se emplea para la materia de Sistemas Digitales en la UAM-Iztapalapa se conoce como UAMI188EB; este proyecto, al que se le ha denominado “Desarrollo de un depurador/ensamblador, y mejora del software Monitor para la

tarjeta de experimentación UAMI188EB”, tiene por objeto facilitar la programación de este sistema mínimo. Es un sistema que integra un ensamblador, un depurador, y un software de control (Monitor), de esta forma se tendrá apoyo de una computadora personal (PC) para la programación de la UAMI188EB.

El sistema no solo facilita la tarea de programación, también permite ahorrar tiempo, ya que en lugar de grabar una EPROM (borrarla y programarla puede tomar al menos 20 minutos), simplemente se transfiere al sistema mínimo y se ejecuta. Además, permitirá depurar un programa en tiempo de ejecución, ya que se puede trazar2 y de esta forma determinar fallas del mismo.

A lo largo del documento, detallaremos cada una de las partes que comprende el

sistema; las cuales son:

• El BIOS.

• El Monitor.

• El programa D188.EXE.

Esta última parte, comprende cuatro módulos que son: la interfaz visual, una interfaz de comunicación con la UAMI188EB, el ensamblador y el depurador. A los dos últimos módulos, se les ha dedicado un capitulo a cada uno, con la finalidad de no perder detalle alguno de sus características.

2 En este caso la frase trazar un programa es ejecutar una instrucción del programa a la vez.

Page 10: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

3

Capitulo 1 La tarjeta de experimentación UAMI188EB3

1.1 Introducción La tarjeta de experimentación UAMI188EB4 es un sistema mínimo el cual cuenta con los siguientes elementos:

• Un microprocesador Intel 80C188EB.

• Una memoria RAM de 8Kb.

• Dos memorias ROM (EPROM) de 16Kb; puede ser sustituidas por EEPROMs de 8Kb.

• Un puerto serie.

• Un puerto para display.

• Un puerto de propósito general.

• Display.

• Otros: MAX232, 74HC573, 74LS245, 74LS14, 74LS138, 74LS00, condensadores, resistencias, bases y conectores.

Es un sistema de propósito general; es decir, puede realizar las tareas comunes de

una PC, o tareas especificas, por ejemplo agregando los dispositivos (hardware) necesarios es posible controlar algún instrumento. Si bien es cierto que una PC en la actualidad es muy completa, en el sentido de que es posible hacer más cosas y es mucho más rápida, como ya se menciono se busca entender el funcionamiento de una PC a un nivel bajo, lo que la UAMI188EB ofrece.

1.2 El microprocesador 80C188EB El 80C188EB es un microprocesador mejorado a partir de su antecesor, el 8086/8088. A diferencia del 8086/8088 que requería de varios circuitos más para completar su funcionamiento (denominados periféricos), el 80C188EB los integra dentro del mismo chip; es decir, en el mismo silicio donde se encuentra el microprocesador, están los periféricos que completan el funcionamiento del microprocesador. Básicamente el 80C188EB sólo necesita un reloj y la alimentación necesaria para que este comience a funcionar. En él se integran las siguientes características5:

• Temporizadores.

3 No incluimos gran detalle de la tarjeta de experimentación ya que ese objetivo no es el perseguido, para ello se puede consultar [1]. 4 En adelante la llamaremos UAMI188EB. 5 Contiene más periféricos, aquí sólo se mencionan los necesarios; una mejor referencia se encuentra en [2].

Page 11: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

4

• Unidad de Chip-Select

• Unidad de control de interrupciones

• Puertos de entrada/salida (I/O)

• Unidad de comunicación serie El bus de datos del 80C188EB es de 8 bits, mientras que el bus de direcciones es

de 20 bits6. Esto quiere decir que el 80C188EB puede direccionar hasta 1Mb de localidades de memoria de 1 byte cada una. Para los puertos de entrada/salida, el bus de direcciones es de 16 bits, lo que indica que se tienen hasta 64K direcciones.

1.2.1 Los temporizadores

El 80C188EB tiene 3 temporizadores: dos externos (Temporizador 0 y 1) y uno interno (Temporizador 2). La diferencia entre externo e interno, es que los externos tienen salida por medio de un pin en el microprocesador; los internos no. Los temporizadores externos pueden ofrecernos una señal cuadrada, que puede o no ser simétrica, con una amplitud de 5v. El rango de frecuencia varia en función de la frecuencia del reloj del microprocesador; en la UAMI188EB el reloj tiene una frecuencia de 24MHz; sin embargo, el 80C188EB divide la frecuencia de entrada entre 2, por lo que la velocidad a la que trabaja el microprocesador es de 12MHz, esta frecuencia de microprocesador se denominara CLK. Los temporizadores emplean esta frecuencia divida entre 4, lo que resulta en 3MHz (ó 1/4CLK). Cada temporizador se maneja por medio de una serie de registros (de 16 bits): uno de control, un contador y dos de comparación, excepto el temporizador interno que sólo tiene un registro de comparación. El registro de control permite configurar cada temporizador, es posible activarlo, fijar el modo de comparación, activar interrupciones7, etc. El registro contador, como su nombre lo indica cuenta el número de ciclos que ocurren a la frecuencia de 1/4CLK. El valor de este registro se compara con el valor en los registros comparación; esta comparación se realiza bajo dos criterios:

• Alternada: Primero compara con un registro, y a la siguiente vuelta compara con el otro registro; esto permite que se puedan tener ondas cuadradas simétricas o asimétricas, ver Fig. 1.1.

6 Cada bit del bus de datos se conocerá como D y un número, por ejemplo los bits del bus de datos son de D0 a D7; lo mismo ocurre con el bus de direcciones, en este caso de A0 a A19. 7 Una interrupción es una suspensión de lo que realiza el microprocesador, para atender el llamado de algún dispositivo externo o interno; esta atención se traduce en la ejecución de un cierto procedimiento. Cada interrupción se identifica por un número que apunta a una tabla de vectores, en donde esta almacenada la dirección de este procedimiento, así el microprocesador sabe donde esta el código de la interrupción. El procedimiento de la interrupción es responsable de informarle al microprocesador cuando termina, para así seguir con lo que se estaba realizando antes de que ocurriese la interrupción.

Page 12: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

5

• Unica: La comparación sólo se realiza sobre un registro, durante el conteo se tendría la parte alta; la parte baja de onda corresponde a un ciclo de reloj del microprocesador (CLK); ver Fig. 1.1.

Figura 1.1 Diagrama de tiempos para el temporizador. A) Un sólo comparador. B) Dos comparadores para

generar una onda simétrica, cada comprador tiene el mismo valor, que es 3; la frecuencia en la UAMI188EB seria de 500KHz.

Cada temporizador puede ser empleado para generar una interrupción; sin embargo, esta interrupción se genera en cada flanco (tanto de subida como de bajada) de la onda de salida, específicamente, cuando se emplean los comparadores de forma alternada (Fig. 1.1), en lugar de generar interrupciones a una frecuencia de 500KHz, se hace a una frecuencia de 1MHz. Si la comparación se realiza de forma única, las interrupciones aparecen cada que se cumple un ciclo de onda en la seña de salida, este caso ocurre con el temporizador 2, que sólo tiene un registro de comparación. Los tres temporizadores pueden ser empleados para generar interrupciones al mismo tiempo e independientemente. Además, los temporizadores externos pueden tener un reloj independiente del microprocesador; es decir, no es 1/4CLK. En su lugar el 80C188EB tiene un pin en donde puede ser conectado un reloj externo para los temporizadores 0 y 1. 1.2.2 Unidad de Chip-Select8 Todos los elementos de los sistemas computaciones comparten algo entre sí, una misma vía de comunicación9. Este canal de comunicación envía información del microprocesador a los diversos dispositivos (así como entre estos) y viceversa. Esta vía de comunicación se conoce como bus. En la UAMI188EB existen dos tipos:

8 Esta sección se complementa con las Secciones 1.2.4 y 1.3. 9 Podemos destacar sólo dos tipos de dispositivos: las memorias donde se almacena información y los demás, que en general persiguen un propósito especifico.

Page 13: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

6

• Bus de datos. Son ocho líneas (bus de 8 bits) en las que se trasmite información de un dispositivo hacia otro.

• Bus de direcciones. El caso de la UAMI188EB son 20 líneas en las que se transmite la dirección en la cual se encuentra el dato requerido.

En la UAMI188EB tenemos varios dispositivos conectados al bus de datos y al

bus de direcciones; sin embargo aquí hay un problema, ya que como se comparte el bus, ¿cómo sincronizamos los dispositivos, de tal manera que sólo uno este colocando información en el bus? Uno o más dispositivos pueden leer los datos en el bus, pero sólo un dispositivo a la vez puede colocar estos datos. La solución es que el microprocesador sea quien sincronice esta operación10; cada dispositivo será identificado por medio de una dirección.

Para el manejo del Chip-Select, el 80C188EB tiene 12 pines de salida distribuidos

de la siguiente manera: un pin de lectura, uno de escritura y 10 de Chip-Select; dos de estos se emplean principalmente en la conexión de memoria11, los otros son de propósito general12. El pin de Chip-Select (CS) es el encargado de informar al dispositivo que tiene derecho de acceder al bus, los pines de lectura y escritura le indican que tipo de derecho tiene sobre el bus; lectura (R) para leer los datos del bus y escritura (W) para colocar datos al bus, ver Fig. 1.2.

Figura 1.2 Microprocesador con tres dispositivos (1, 2 y 3) controlados para acceder al bus. Se asume que para dispositivo tiene un pin de Chip-Select diferente; CS1 con el dispositivo 1, CS2 para el dispositivo 2

y así sucesivamente.

Suponga que se desea mover un dato del dispositivo 1 al dispositivo 2, que en general no es posible hacer esto directamente, el microprocesador sirve de

10 Los primeros procesadores no hacían directamente esta tarea, existían otros dispositivos externos que se encargaban de esto. El 80C188EB tiene los circuitos necesarios para llevar a cabo la sincronización. 11 Estos se denominan Lower Chip-Select (LCS) y Upper Chip-Select (UCS). LCS mapea la memoria baja (RAM) donde se encuentran los vectores de interrupción; UCS mapea la memoria alta, donde se encuentra la ROM, y en esta, el código de arranque de la tarjeta. Cuando se inicia el microprocesador, el único Chip-Select habilitado es UCS, pero aun así hay que terminar de habilitarlo correctamente. 12 También denominados General Chip-Select (GCS), pueden ser empleados en cualquier propósito.

Page 14: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

7

intermediario. El microprocesador envía un señal por CS113, la señal R y la dirección

donde esta el dato para que el dispositivo coloque los datos en el bus; el microprocesador lee el dato, y lo almacena en un registro intermedio. El microprocesador activa ahora CS2, la señal W, la dirección donde colocara el dato y el dato en el bus, para que lo escriba en el dispositivo 214. Cada Chip-Select se programa con un par de registros, los cuales le indican al procesador entre que direcciones es válido disparar el CS. Además se indica el tipo de CS a enviar; es decir, si están mapeando dirección de memoria o dirección I/O;

recordemos que las direcciones de memoria son de 20 bits, mientras que las de I/O son de 16 bits en la UAMI188EB. 1.2.3 Unidad de control de interrupciones

El 80C188EB integra el manejo de interrupciones externas e internas; antes esto se lograba con ayuda del 8259. Las interrupciones internas se pueden generar por:

• Puerto serie.

• Temporizadores.

• División por cero

• Sobre flujo

• Ejecución de una instrucción (trazado). Las dos primeras no son del todo internas, ya que antes estos dispositivos eran externos; sin embargo, así las trataremos. Por otra parte es posible generar hasta 5 interrupciones externas; es decir, es un pin en el microprocesador, el cual va conectado al dispositivo y le indica al 80C188EB cuando interrumpir lo que esta haciendo. Podemos conectar hasta 5 dispositivos que pueden solicitar interrupciones, aunque es posible conectar más si empleamos una configuración en cascada. Cuando algún dispositivo ha captado algún evento, por ejemplo en un control de teclado cuando se presiona una tecla, este envía una señal al microprocesador para que realice una acción sobre el evento. El microprocesador en realidad desconoce que evento es; pero no así el procedimiento que debe ejecutar, ya que sabe que dispositivo es quien solicita la interrupción. El microprocesador lee el vector de interrupciones, localizado en los primeros bytes de la memoria, obtiene la dirección en donde se encuentra el procedimiento y lo ejecuta.

13 En el 80C188EB las señales de Chip-Select, de escritura y lectura son negadas; es decir, activan en 0 e inactivan en 1. 14 En general el proceso es un poco más complejo, pero un mejor detalle y con diagramas de tiempo se puede obtener en [2].

Page 15: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

8

Las interrupciones son controladas por varios registros dentro del microprocesador; lo más importante de este control es su habilitación/inhabilitación y su prioridad. Cuando desactivamos una interrupción, si el dispositivo esta solicitándola, el microprocesador no la tomará en cuenta. La prioridad ayuda al microprocesador a determinar cual procedimiento de interrupción se ejecuta primero cuando se ha solicitado dos o más interrupciones al mismo tiempo. 1.2.4 Puertos de entrada/salida (I/O)

Un puerto de I/O es una forma de comunicación que tiene el microprocesador con otros dispositivos. El microprocesador envía la dirección donde se encuentra el dato, habilita al dispositivo y el dato viajara por el bus de datos. Se ha mencionado que la unidad de Chip-Select se encarga de dar los permisos de acceso tanto al bus de datos como al bus de direcciones; aunque en este ultimo no existe mucho problema, ya que en general el microprocesador es el que se encarga de colocar la dirección y los dispositivos únicamente la leen, sin intentar colocar datos en el bus de direcciones. Para entender el funcionamiento de los puertos de I/O se propone un ejemplo en el que se tiene un dispositivo con dos registros; un registro de lectura y uno de escritura. El registro de lectura (RL) contiene un dato de 8 bits (un byte) el cual se obtuvo de alguna fuente (por lo pronto no importa de donde); el registro de escritura (RE) es de 8 bits y sirve para controlar el dispositivo (de igual forma no importa como es el control). Las únicas instrucciones que sirven para usar los puertos I/O son IN (leer dato) y OUT (Escribir dato); las demás son para hacer movimientos en la memoria. En nuestro dispositivo se empleara el Chip-Select 0 (CS0), y lo primero es configurar el CS0, para ello es necesario conocer el dispositivo; en este caso tenemos sólo dos registros, pero en general es posible tener muchos más, aquí es donde entra el bus de direcciones, ya que es posible tener que asignar algunas direcciones a cada registro del dispositivo.

Figura 1.3 Dispositivo ejemplo. A la izquierda esta el bus de direcciones del microprocesador.

En este caso, el dispositivo cuenta con una entrada R/W que selecciona el registro, pero puede contener más en caso de un mayor numero de registros; una entrada de CS en la que conectaremos el pin CS0 y el bus de datos. Si en R/W entra un 1 se selecciona el registro RL, un 0 selecciona el registro RE.

No podemos conectar directamente las señales de W y R del microprocesador, ya

que el microprocesador tiene dos pines para una sola conexión; sin embargo, podemos hacer uso del bus de direcciones, que en general es lo que se emplea. Como son sólo dos registros, necesitamos un bit el cual será dado por A0 (y no importa el valor de los

Page 16: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

9

demás bits en el bus de direcciones). Entonces toda dirección terminada en 0 selecciona el registro RE, y toda dirección terminada en 1 selecciona RL.

El CS0 sólo se dispara cuando se hace referencia a un rango especifico de

direcciones; para memoria el rango puede ir desde 00000H hasta FFFFFH, en I/O el rango puede estar entre 0000H y FFFFH. Los valores mínimos aceptados son 00H hasta 40H, y precisamente este valor mínimo es más que suficiente. Además de esto, el CS0 sólo se dispara en operaciones de I/O y no de memoria; esto significa que sólo de dispara CS0 en el rango correspondiente, y con instrucciones IN y OUT.

El circuito final, se muestra en la Fig. 1.4. Los accesos al dispositivo para lectura

se realizan con la instrucción OUT y las direcciones validas son todas las impares comprendidas entre 00H y 3FH; para escribir un dato empleamos la instrucción IN y las direcciones validas son todas la pares comprendidas en el rango anterior.

Figura 1.4 Puerto I/O para el manejo de un dispositivo.

Inmediatamente a lo anterior surge un problema; el número de dispositivos que es posible conectar, depende del número de CS que se tengan en el microprocesador; más aun, debido a la configuración del CS y de los dispositivos, algunas direcciones pueden ser compartidas; en el ejemplo anterior, existen varias direcciones para acceder a un mismo registro. El último punto no es un problema, ya que el CS hace la

diferencia; pero el primero si. Una solución es implementar un circuito extra entre el bus de direcciones y un CS para poder conectar al menos dos dispositivos; sin embargo, esto puede producir algunos errores ya que las señales deben viajar por otros circuitos antes de llegar al dispositivo destino, la señal entonces llegara con cierto retardo y se debe hacer que este retardo sea el menor. 1.2.5 Unidad de comunicación serie

Los dispositivos dentro una computadora se comunican a través de un bus, si el bus es de 8 bits, simultáneamente los 8 bits serán trasmitidos. En una comunicación serie, los bits son trasmitidos uno por uno; en un bus se necesitan 8 alambres para trasmitir un byte, en una comunicación serie 3 cables son suficientes, uno de tierra, uno

Page 17: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

10

de transmisión y uno de recepción. Observe que en una comunicación serie esta permitido que el flujo viaje en ambas direcciones, mientras que en un bus, la comunicación sólo viaja en una dirección. El 80C188EB dispone de los circuitos necesarios para implementar una comunicación serie, sólo hay que agregar un circuito que se encarga de llevar los voltajes de 0v a 5v que maneja el microprocesador, a voltajes de ±9v. Las señales que pasan a través de un cable serial, tienen un voltaje mayor con la finalidad de que las señales viajen mayores distancias; en un bus donde los voltajes son las que maneja el microprocesador, se habla de distancias en centímetros, mientras que en una comunicación serie podemos hablar de metros. Existen dos formas de comunicación serie que puede manejar el 80C188EB: asíncrona y sincrona. En la comunicación sincronía, es necesario que los dispositivos que intervienen en la comunicación se sincronicen de alguna forma, esto se logra mediante un reloj; es decir, los dispositivos se comunican siguiendo los tiempos que se marcan con ayuda de un reloj, nadie puede enviar o recibir datos sin que el otro este preparado para recibirlos o transmitirlos. En la comunicación asíncrona, los dispositivos que intervienen en la comunicación, pueden enviar o recibir datos independientemente de lo que el otro este haciendo; es decir, un dispositivo puede enviar información a otro, y este puede o no recibirlo, ello depende de lo que este realizando en ese momento; como se puede ver, no es necesario de un reloj para sincronizar, pero en ambos casos es necesario un reloj para saber cuantos bits se trasmiten en un intervalo de tiempo, esta es la velocidad de transmisión y ambos dispositivos en la comunicación deben manejar la misma velocidad de transmisión. El 80C188EB maneja ambos modos de comunicación, pero el modo más sencillo es el asíncrono, por lo que ese modo es el que se empleara. En la comunicación es posible transmitir 5, 6, 7 u 8 bits, ello depende de como este configurado el control del serial. Para su control en el 80C188EB se requieren de 6 registros: uno de control, uno para definir la velocidad de la transmisión, un contador, uno de estado, uno de transmisión y uno de recepción. Las velocidades que acepta el controlador de puerto serie en el 80C188EB son las siguientes: 1200, 2400, 4800, 9600 y 19200, todas en unidades de bits por segundo (bps). Lo anterior no quiere decir que se transmite información a esas velocidades realmente; en una transmisión serie existen bits de control, estos bits son de parada y bits de paridad. Los primeros ayudan a delimitar los conjuntos de bits que se transmiten, y los bits de paridad, sirven para determinar cuando una cadena de bits contiene errores. El tipo de comunicación serie empleada por la UAMI188EB es la asíncrona, por lo que debe existir un medio para determinar cuando se están enviando datos; recodemos que en una transmisión asíncrona no hay un acuerdo entre ambas partes. Las soluciones son la implementación de interrupciones y el monitoreo. El 80C188EB permite el uso de

Page 18: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

11

interrupciones para el puerto serie, una interrupción se dispara cuando se ha transmitido un dato (el registro de transmisión ha quedado vacío), y cuando ha llegado un dato (el registro e recepción esta lleno). El uso de interrupciones en una comunicación asíncrona, permite enviar y recibir datos de forma dinámica, sin tener que monitorear el estado del puerto serie, que es la segunda solución. 1.2.6 Los registros del 80C188EB

El microprocesador 80C188EB cuenta con una serie de registros, los cuales funcionan como un apoyo al momento de ejecutar instrucciones, todos estos registros son de 16 bits y algunos se dividen en registros de 8 bits. Existen registros acumuladores que sirven de memoria intermedia o para almacenar un resultado; contadores que permiten crear ciclos (tipo for, while, etc); registros de direccionamiento para acceder a los datos en memoria; de segmento que permiten estructurar la memoria en bloques denominados segmentos y de pila. La Tabla 1.1 muestra el nombre de los registros en el

80C188EB. Los registros AX, CX, DX y BX se dividen a su vez en registros de 8 bits; estos se conocen con el nombre de AH y AL para AX, BH y BL para BX, CH y CL para CX, y DH y DL para DX.

Registros

Acumuladores y contadores

Para direccionamiento

De segmento para datos y código

Manejo de pila

AX BX CS SS

CX DI DS SP

DX SI ES BP

IP Tabla 1.1 Conjunto de registros del microprocesador 80C188EB.

Existe un último registro, en el cual cada bit representa una bandera en el microprocesador15; la siguiente tabla muestra la estructura de este registro.

Registro de banderas 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

OF DF IF TF SF ZF AF PF CF

Tabla 1.2 Bits del registro de banderas.

El significado de cada bandera es el siguiente:

• OF (overflow, desbordamiento) – Desbordamiento del bit más significativo en una operación aritmética.

15 Este registro lo denominaremos FLAGS.

Page 19: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

12

• DF (dirección) – Indica la dirección en la cual se mueven los registros SI y DI en

un arreglo o cadena.

• IF (interrupción) – Habilita las interrupciones externas, de circuito, será atendida.

• TF (trampa) – Este bit permite colocar al microprocesador en ejecución paso a paso (depuración).

• SF (signo) – Signo resultante de la operación aritmética.

• ZF (cero) – Indica si la ultima operación arrojó un cero.

• AF (acarreo auxiliar) – Contiene el acarreo externo del bit 3, en un dato de 8 bits.

• PF (paridad) – Indica paridad par o impar en una operación en los 8 bits menos significativos.

• CF (acarreo) – Bit de acarreo en una operación aritmética.

1.3 Unidades de memoria

La memoria en un sistema computacional sirve para almacenar información; por información tenemos a los programas y a los datos. Las memorias están organizadas en conjuntos de celdas, las cuales son identificadas por una dirección; cada celda esta compuesta de un conjunto de bits (8, 16 o 32 bits). En el caso de la UAMI188EB cada celda tiene un tamaño de 8 bits. La Fig. 1.5 muestra una memoria de 16 celdas de 8 bits.

Figura 1.5 Memoria de 16 celdas de 8 bits cada una. La capacidad de la memoria es

de 16 bytes. Ai es el bus de direcciones y Di el bus de datos.

Los pines del lado izquierdo representan la entrada de la dirección de cada celda, se tienen 4 bits que pueden direccionar hasta 16 celdas (00H a 0FH). Estas líneas son conectadas al bus de direcciones; que en este caso sólo se emplean 4. Del lado derecho tenemos los pines donde se colocan o leen datos; son 8 pines que representan datos de 8 bits, y que van conectados al bus de datos. Por último se tienen los pines de Chip-Select (CS), lectura (R) y escritura (W), que controlan el tipo de acceso al

bus de datos.

En la UAMI188EB tenemos dos tipos de memoria:

ROM (Read Only Memory – Memoria de sólo lectura): Esta es una memoria que

no puede ser escrita por ningún elemento de la UAMI188EB y no necesita voltaje para mantener los datos en ella, por lo tanto el pin W carece de significado. En este tipo de memorias se almacenan datos que el sistema pueda ocupar en todo momento y que no deben ser modificados; en el caso de la UAMI188EB se almacena dos programas de control uno denominado BIOS y el Monitor, más adelante daremos más detalle. La UAMI188EB soporta dos memorias de este tipo, una para que el usuario programe lo

Page 20: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

13

que desee y la segunda en donde se colocan los programas anteriores; sus direcciones de memoria son:

Dirección

ROM Inicia Final

1 0FC00H 0FFFFH

2 04000H 08000H Tabla 1.3 Direcciones de memoria en la que se localizan los datos en las ROMs.

En la ROM 1 están almacenados los programas BIOS y Monitor, y en la ROM 2 estarán los programas que el usuario considere. Estas direcciones son validas para una ROM de 16Kb x 8; es decir, 16384 celdas de 8 bits, el modelo recomendado es la EPROM 27128. Es posible usar otras ROM, pero esto provocaría que se cambien las direcciones inicial para la ROM 1 y final para la ROM 2, para adecuarlas al tamaño nuevo de la memoria; sin embargo, el tamaño máximo que puede emplear la UAMI188EB es de 16Kb. RAM (Random Access Memory – Memoria de acceso aleatorio): A diferencia de la ROM, en esta memoria se puede escribir datos en cualquiera de sus celdas, pero para mantener los datos en memoria es necesario que la UAMI188EB este alimentando con un nivel de voltaje a la memoria, lo cual no es necesario en la ROM. Esta memoria es muy importante, ya que todas las operaciones que el microprocesador efectué, se realizan con el apoyo de la RAM. La UAMI188EB sólo contempla el uso de una sola memoria RAM cuyas direcciones de memoria son:

Dirección

Inicia Final

RAM 00000H 02000H Tabla 1.4 Direcciones de memoria en la que se localizan los datos en la RAM.

Se puede observar que el tamaño de la RAM es de 8Kb, y las celdas son de 8 bits; el modelo de memoria para UAMI188EB es una RAM 6264.

Es posible incrementar la memoria, pero hay que hacer algunas modificaciones en la tarjeta; una de ellas es conectar una línea más del bus de direcciones, ya que con esta memoria sólo se emplean 13 líneas, y por ejemplo,. para una memoria de 16Kb son necesarias 14 líneas (de A0 a A13).

1.4 Puerto Serie Se ha comentado que el 80C128EB contiene los circuitos necesarios para implementar un puerto serie, que básicamente es donde conectaremos el cable para conectarlo a otra computadora. El puerto serie de la UAMI188EB es totalmente

Page 21: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

14

compatible con el puerto serie de cualquier PC; más aun, la programación resulta ser semejante a la que se emplea en la PC. En la siguiente figura, se muestra la configuración de los puertos serie para una PC normal y la UAMI188EB. El conector mostrado se conoce como DB9 macho16, cada pin del conector esta numerado del 1 al 9, pero sólo 3 pines se emplean; un pin es para transmisión, uno para recepción y el tercero es tierra.

Figura 1.6 Conectores DB9 para comunicación serie en la PC y la UAMI188EB.

La conexión resulta fácil, ya que el pin de tierra del DB9 en la PC se conecta al pin de tierra del DB9 de la UAMI188EB, el pin de transmisión en la PC se conecta al pin de recepción en la UAMI188EB y finalmente, el pin de transmisión en la UAMI188EB se conecta al pin de recepción en la PC; ver Fig. 1.617. Si bien el 80C188EB tiene los circuitos necesarios para la comunicación, estos no son suficientes. Hacen falta otros, esto se debe a que el voltaje que maneja el procesador esta entre 0v y 5v, y la transmisión de los bits requiere de al menos ±9v. Esta conversión de voltajes es realizada por el circuito MAX232; de esta forma, las salidas y entradas de comunicación serie del microprocesador van conectadas al MAX232 y de este al puerto serie, ver Fig. 1.11.

1.5 Display18 El display es el medio de comunicación visual entre el usuario y la UAMI188EB, en el se muestran los resultados del programa en ejecución. El dispositivo comúnmente

16 El conector serie en toda PC es un DB9 macho, en la UAMI188EB se debe tener el mismo tipo de conector para asegurar el orden correcto de los pines. 17 Debido a que la tarjeta experimental UAMI188EB ha sufrido algunos cambios, la ultima versión de la tarjeta contiene un ligero error de diseño. Los orificios del conector DB9 macho para la tarjeta están colocados a la inversa; la solución a este problema es eliminar el pin 1 de la conexión a la tarjeta y ajustar los demás pines de tal forma que se adapten a la nueva configuración. Esto no afecta en modo alguno a la tarjeta; sólo hay que asegurarse de los pines entre la UAMI188EB y la PC se conecten adecuadamente. 18 Para una mayor detalle del display y su programación, consultar [10].

Page 22: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

15

empleado es el AND491GST19, el cual cuenta con una pantalla LCD en la que es posible mostrar 2 líneas de 16 caracteres, el controlador del LCD es el HD44780. En teoría la UAMI188EB puede manejar cualquier tipo de display ya programado; es decir, al dispositivo antes mencionado, sólo hay que enviarle el caracter y este lo desplegará en pantalla. La UAMI188EB también puede emplear los siguientes displays: AND481GST, AND471GST, AND501GST, AND731GST y AND721GST; en donde las pantallas LCD son más grandes y pueden alcanzar tamaños de 4 líneas de 20 caracteres. La conexión del display con la UAMI188EB resulta muy sencilla, el AND491GST tiene 14 pines para su conexión; dos pines de alimentación, uno de contraste para la pantalla, uno de control RS, un pin de lectura escritura, un pin de habilitación y 8 pines de datos; ver Fig. 1.7.

Figura 1.7 Display AND491GST.

El display es considerado como un dispositivo de I/O; esto quiere decir que se le

asigna un Chip-Select que básicamente es conectado al pin E20 para habilitar el display. Por otra parte, existe un problema en la conexión R/W, ya que el display sólo tiene una y el 80C188EB tiene dos; la solución es conectar uno de los bits del bus de dirección y mediante el valor de la dirección determinar la escritura W y lectura R. El pin RS ayuda a seleccionar la función junto con la información en el bus de datos. En conclusión RS = A0 y R/W = A1, que son los bits del bus de direcciones, la siguiente figura muestra la conexión del display.

19 También es posible emplear cualquier otro sustituto. 20 El Chip-Select empleado se conecta a un cierto numero de compuertas, con la finalidad de generar un pequeño retardo, para más información consultar [1].

Page 23: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

16

Figura 1.8 Conexión del display en la UAMI188EB. Para la UAMI188EB CS corresponde al Chip-Select 1

(GCS1).

De esta forma y programando correctamente el Chip-Select, el valor de A1 en el bus de direcciones determinará si se escribe o lee en el display; el display internamente contiene un conjunto de registros, los cuales son accesados dependiendo del valor de RS (A0) y del valor enviado por el bus de datos.

1.6 Otros dispositivos En la UAMI188EB existen otros dispositivos importantes, entre estos se pueden mencionar a los circuitos 74LS245 y 74HC573. El funcionamiento de estos circuitos se limita principalmente a manejar la información en el bus de datos y en el bus de direcciones. EL 80C188EB tiene multiplexados los pines del bus de datos y del bus de direcciones; es decir, los pines D0 a D7 del bus de datos son los mismos que los pines A0 a A7 del bus de direcciones, por lo que es necesario separar la información cuando se trata de un dato o una dirección para canalizarlos por el bus correspondiente; aquí es donde entran los circuitos 74LS245 y 74HC573.

El 74LS245 es un circuito buffer bidirecional, puede dejar pasar datos en una u otra dirección, ello dependerá de los bits de control [E]21 y DIR; un circuito básico de un bit se muestra en la Fig. 1.9, en donde pueden pasar 8 bits de A a B o viceversa.

21 Las variables entre paréntesis cuadrados indican que se activan en 0 (0v) y no en 1 (5v), en algunos otros casos, el colocar un barra en la parte superior de la variable también tiene el mismo significado.

Page 24: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

17

Bits de Control

[E] DIR

Acción

0 0 Datos de B a A

0 1 Datos de B a A

1 X22 Alta impedancia

Figura 1.9 Circuito básico del 74LS245 para un bit. Lo que ocurre con este bit, sucede para los otros 7 bits.

Tabla 1.5 Tabla de verdad de los bits de control para el 74LS245.

El bit de control [E] habilita el 74LS245 y el bit DIR selecciona la dirección, transfiere 8 bits de un lado a otro, ver Tabla 1.3. Es circuito es importante, ya que se encarga de enviar o recibir los bits del bus de datos.

El 74HC573 es un conjunto de Flip-Flip’s23 tipo D con compuerta de tercer estado24 a la salida. Este circuito retiene la información durante cierto intervalo de tiempo para que otros la lean, funciona como una memoria intermedia; un circuito básico de un bit se muestra en la Fig. 1.10.

Bits de Control

C [OC]

Salida Q

0 0 Se mantiene Q

X 1 Alta impedancia

1 0 D -> Q

Figura 1.10 Circuito básico del 74HC573 para un bit.

Lo que ocurre con este bit, sucede para los otros 7 bits.

Tabla 1.6 Tabla de verdad de los bits de control para el 74HC573.

22 La X indica que no importa el valor, puede ser 0 ó 1. 23 Es un circuito básico capaz de almacenar un bit. El Flip-Flop D tiene una entrada D, dos salidas Q y [Q] y un control C; las salidas mantienen sus respectivos valores a menos que al control C se le proporcione un pulso, en este caso, sustituyen su valor por el de D y lo mantienen hasta que C reciba otro pulso. Para una mejor descripción consultar [14]. 24 La compuerta de tercer estado se comporta como un “alambre” que permite el paso de corriente o como un dispositivo de alta impedancia (un circuito abierto). El comportamiento de circuito abierto o cerrado, es controlado por una señal externa.

Page 25: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

18

Es circuito mantiene datos almacenado en un registro hasta que ocurra un cambio en el bit de control C; mantiene una compuerta de tercer estado para evitar tener acceso al bus.

1.7 Descripción de la UAMI188EB Estamos ahora en condiciones de describir completamente la tarjeta de experimentación UAMI188EB. Esta tarjeta tiene un microprocesador 80C188EB de Intel, cuyo reloj esta regulado por un cristal de cuarzo de 24MHz, y con una alimentación de 5v. La memoria RAM del sistema es de 8Kb y ocupa los pines A0 a A12 del bus de direcciones, el Chip-Select para la RAM esta dado por el pin LCS. Contiene dos bases para ROM, una de las cuales emplea el Chip-Select UCS, y la segunda usa el GCS0; emplea los bits A0 a A13 del bus de direcciones y todas las memorias son del tamaño del bus, 8 bits El 80C188EB tiene conectado al bus de datos un 74LS245, que permite controlar el flujo de información por este bus; este circuito permite que la información fluya en una sola dirección, que entre al microprocesador o que salga. Como el bus de datos y el de direcciones esta multiplexado, falta un medio que permita “recordar” la información del bus de datos o la del bus de direcciones, mientras se envía la información del otro. En este caso la información que se mantiene es la del bus de direcciones, para ello están los circuitos 74HC573. El 80C188EB envía la dirección hacia el 74HC573, este la mantiene en sus Flip-Flops, mientras el microprocesador ahora envía la información por el bus de datos; de esta forma se demultiplexa el bus de datos y el de direcciones, y el dispositivo recibe al mismo tiempo dirección y datos. El puerto serie el 80C188EB esta conectado a un circuito manejador que permite elevar el voltaje; este circuito es el MAX232 el cual esta conectado al DB9 macho en la tarjeta. Finalmente tiene dos puertos de salida, uno para el display en donde se tiene el bus de datos y los respectivos controles del display; y uno de propósito general, el cual contiene además del bus de datos, todos los bits del bus de direcciones, todos los pines de las interrupciones externas, el temporizador 0 y una salida de reloj. El diagrama completo de la UAMI188EB, se muestra en la Fig. 1.11.

Page 26: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

19

1.8 Arranque de la UAMI188EB Una vez que encendemos a la UAMI188EB el microprocesador inmediatamente inicia todos sus registros a sus valores por default, después de esto sin importar lo que este conectado en esa dirección, salta a los últimos 16 bytes de toda la memoria; es decir, activa el UCS en la dirección 0FFFF0H y procede a ejecutar lo que ahí se encuentre. En esos últimos 16 bytes, el usuario debe mapear la memoria ROM con el UCS; si la ROM es de 16Kb, entonces el UCS se debe disparar en direcciones a memoria comprendidas entre 0FC000H y 0FFFFFH.

Únicamente existen 16 bytes para código, por lo que resulta lógico un salto a un dirección más baja, con la finalidad de seguir ejecutando código. En nuestro caso, el salto se realiza al inicio de la ROM; es decir, 0FC000H. Lo que ahí ocurra es responsabilidad del programador, pero lo que se recomienda es que se continúe con la configuración de los Chip-Select y de los periféricos del microprocesador.

Page 27: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

20

1 2 3 4 5 6

A

B

C

D

6 5 4 3 2 1

D

C

B

A

Title Number Revision Size

C Date: 11-Oct-2005 Sheet of File: C:\MAMR\Reinst\188EB10.DDB Drawn By:

AD0 AD1 AD2 AD4 AD5 AD6 AD7 A8 A9 A10 A11 A12 A13 A14 A15 A16 A17 A18 A19

AD3

P1.3/GCS3 25

RESOUT 38

P1.1/GCS1 27

RESIN 37

P1.0/GCS0 28

PDTMR 36

LCS 29 T0IN 46

UCS 30

INT0 31

AD0 61

INT1 32

AD1 66 AD2 68

T0OUT 45

AD3 70

INT2/INTA0 33

AD4 72

T1IN 48

AD5 74

INT3/INTA1 34

AD6 76

INT4 35

AD7 78 A8 62 A9 67

CLKOUT 44

A10 69 A11 71

CLKIN 41

A12 73 A13 75 A14 77 A15 79

P2.3/SINT1 55

A16 80 A17 81

P2.6 50

A18 82

CTS0 51

A19/ONCE 83 T1OUT 47

TXD0 52 RXD0 53

P2.4/CTS1 56 P2.5/BCLK0 54 P2.0/RXD1 57 P1.7/GCS7 19 P2.2/BCLK1 59 P1.6/GCS7 20 P2.1/TXD1 58 P1.5/GCS5 21 P1.4/GCS4 24

HLDA 12 HOLD 13 LOCK 15

DEN 11 DT/R 16 READY 18

WR 5 RD 4

RFSH 7 ALE 6

S0 10 S1 9 S2 8

NC 60

P1.2/GCS2 26

NC 39 NC 3

OSCOUT 40

TEST/BUSY 14 NMI 17

U1A

188EB

C1 10uf

C3 20PF J1

S1 3 4 U12B 74LS14

1 2 U12A 74LS14

D1 R1

OC 1 C 11 1D 2 2D 3 3D 4 4D 5 5D 6 6D 7 7D 8 8D 9

1Q 19 2Q 18 3Q 17 4Q 16 5Q 15 6Q 14 7Q 13 8Q 12

U2

74HC573

OC 1 C 11 1D 2 2D 3 3D 4 4D 5 5D 6 6D 7 7D 8 8D 9

1Q 19 2Q 18 3Q 17 4Q 16 5Q 15 6Q 14 7Q 13 8Q 12

U4

74HC573 OC 1 C 11 1D 2 2D 3 3D 4 4D 5 5D 6 6D 7 7D 8 8D 9

1Q 19 2Q 18 3Q 17 4Q 16 5Q 15 6Q 14 7Q 13 8Q 12

U5

74HC573

AD7 AD6 AD5 AD4 AD2 AD1 AD0 AD3

A15

AD7 AD6 AD5 AD0 AD1 AD2 AD4 AD3

A13 A12 A11 A10 A9 A8

A17 A18 A19

A14

A8

A19 A18 A17 A16

A9 A10 A11 A12 A13 A14 A15

A0 A1 A2 A3 A4 A5 A6 A7

A0 2 A1 3 A2 4 A3 5 A4 6 A5 7 A6 8 A7 9

B0 18 B1 17 B2 16 B3 15 B4 14 B5 13 B6 12 B7 11

E 19 DIR 1

U3

74LS245

A0 10 A1 9 A2 8 A3 7 A4 6 A5 5 A6 4 A7 3 A8 25 A9 24 A10 21 A11 23 A12 2 A13 26 CE 20 OE 22 PGM 27 VPP 1

D0 11 D1 12 D2 13 D3 15 D4 16 D5 17 D6 18 D7 19

U6

27128

D0

A9 A8 A13 A12 A11 A10 A7 A6 A5 A4 A3 A2 A1 A0

D1 D2 D3 D4 D5 D6 D7

A0 10 A1 9 A2 8 A3 7 A4 6 A5 5 A6 4 A7 3 A8 25 A9 24 A10 21 A11 23 A12 2

CS1 20 CS2 26 WE 27 OE 22

D0 11 D1 12 D2 13 D3 15 D4 16 D5 17 D6 18 D7 19

U7

6264

A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12

D0 D1 D2 D3 D4 D5 D6 D7

A0 10 A1 9 A2 8 A3 7 A4 6 A5 5 A6 4 A7 3 A8 25 A9 24 A10 21 A11 23 A12 2 A13 26 CE 20 OE 22 PGM 27 VPP 1

D0 11 D1 12 D2 13 D3 15 D4 16 D5 17 D6 18 D7 19

U8

27128

A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A1

1 A12 A1

3

D0 D1 D2 D3 D4 D5 D6 D7

D7 D6 D5 D4 D3 D2 D1 D0

4 5 6 U10B

74LS00

8 9 10

U10C 74LS00

11 12 13

U10D 74LS00

1 2 3 U10A 74LS00

VCC 16

C1+ 1 C1- 3 C2+ 4 C2- 5 T1/IN 11 T2/IN 10 R1/OUT 12

V+ 2 V- 6

T1/OUT 14 T2/OUT 7

R1/IN 13 GND 15

R2/OUT 9 R2/IN 8

U9

MAX220

5VCC

5VCC

A9 A8 A13 A12 A11 A10 A7 A6 A5 A4 A3 A2 A1 A0

D6 D7 D5 D4 D0 D1

5VCC

RV1

10K VCC

A0 A1

C8 10uf

C5 10uf C6

4.7uf C4

4.7uf C7

4.7uf

5VCC

1 6 2 7 3 8 4 9 5

P1

DB9

C36 C36 12PF

5VCC C37 12PF 5VCC C38 C38

12PF 5VCC C39 C39

12PF 5VCC C30

5VCC

C31 5VCC C32

5VCC C33 5VCC C34 C35 C35

12PF 5VCC

5VCC

D2 D3

A14 A1

5 A16 A1

7 A18 A1

9 D0 D2 D1 D3 D4 D5 D6 D7

R4 RES1

5VCC R5 RES1

R2 RES1

R3 RES1

5VCC

8 7 4

C2 20pf

1 CON1 1 2

JP1 HEADER 2

1 CON1 1 CON1

1 CON1 1 CON1

1 CON1

VCC

5VCC GN

D 1 CON1 1 CON1

1 CON1 1 CON1

1 CON1 1 CON1

5VCC 5VCC 5VCC 5VCC 5VCC 5VCC GND GN

D GND GN

D GND GN

D 5VCC 5V

CC 5VCC 5V

CC 5VCC 5V

CC

32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 J2 CON AT62A

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 JP1 CON20

1 4

J? GND

J? GND

J? GND

J? GND

J? GND

J? GND

J? GND J?

GND J? GND J?

GND J? GND J?

GND J? GND

J? GND

VCC

Figura 1.11 Diagrama completo de la UAMI188EB

Page 28: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

21

Capitulo 2. El BIOS de la UAMI188EB

2.1 Introducción La palabra BIOS son las siglas de Basic Input Output System (sistema básico de entrada/salida); es el componente de software de más bajo nivel en el sistema operativo de una computadora. En general en una PC las rutinas del BIOS consisten en verificar el hardware, activar algunos dispositivos y cargar el propio sistema operativo. La forma de implementar el BIOS en la UAMI188EB es a través de una memoria ROM25, de esta forma el BIOS prácticamente forma parte del hardware. Al encender la UAMI188EB, el procesador inmediatamente accede a esta ROM y ejecuta las instrucciones que en ella están. A diferencia de una PC, el BIOS no carga ningún tipo de sistema operativo, en lugar de ello le cede el control a un pequeño programa llamado Monitor que se encarga de administrar la comunicación con el depurador de la UAMI188EB; el programa Monitor se encuentra dentro de la misma ROM en donde se localiza el BIOS.

2.2 Arranque del BIOS26 Al encender la UAMI188EB, el BIOS realiza, y en ese orden las siguientes operaciones (ver archivo BIOSM.ASM):

• Desactiva toda interrupción con la instrucción CLI.

• Configuración del Chip-Select.

• Configuración del Display.

• Revisión de la memoria RAM y ROM.

• Carga valores iniciales en memoria de configuración.

• Inicio de los vectores de interrupción.

• Inicio del hardware de la UAMI188EB.

• Prepara ambiente para el programa Monitor.

• Carga el Monitor.

25 Hay dos bases para memorias ROM en la UAMI188EB, la primera ROM (base 1) esta conectada al Upper Chip-Select, y al encender la UAMI188EB este es la única memoria activa. La base 2 contiene a la segunda ROM y su Chip-Select es propósito general, por lo que hay que programarlo. 26 El código del BIOS y el Monitor se localiza en el Apéndice E; a lo largo del documento solo se hará referencia al nombre de archivo donde se localiza el código.

Page 29: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

22

2.2.1 Configuración del Chip-Select

El Chip-Select es una parte importante en la UAMI188EB, ya que controla el acceso de los dispositivos al bus de datos. La primera configuración que realiza el BIOS es sobre el Upper Chip-Select (UCS), que esta destinado a controlar la ROM; el siguiente es el Lower Chip-Select (LCS), que controla a la memoria RAM; por ultimo configura el General Chip-Select (GCS) 0 y 1 que controlan la segunda ROM y el display respectivamente. Los parámetros de configuración se muestran en la Tabla 2.1.

Mapeo en memoria Tipo de Chip-Select Inicial Final Mapeo

Objetivo

UCS 0FC000H 0FFFFFH Memoria Controla la primera ROM

LCS 000000H 002000H Memoria Controla la RAM

GCS0 004000H 008000H Memoria Controla la segunda ROM

GCS1 0040H 0080H I/O Display Tabla 2.1 Parámetros de configuración de los Chip-Select en la UAMI188EB.

Todas las configuraciones de Chip-Select están a 15 estados de espera; es decir,

15 ciclos de reloj es lo que espera el microprocesador a cada dispositivo. Es posible cambiar algunas de las direcciones, pero hay que poner mucha atención a las direcciones que se están fijando; por ejemplo, para la ROM 2 se ha fijado una dirección entre 04000H y 08000H, pero solo los 14 bis menos significativos son los que toman en cuentan, para ello ver Fig. 1.11.

El código que realiza lo anterior se encuentra en el archivo CHIPSEL.ASM.

2.2.2 Configuración del display

El BIOS por default configura el sistema para usar el display AND471GST, que es de 2 renglones de 16 caracteres (2x16). Básicamente lo que realiza es encender el display y limpiar la pantalla. Durante el arranque del BIOS, todos los mensajes son presentados para un display de 2x16, el acceso se realiza directamente al display y no se emplea ninguna interrupción. Después de verificar la memoria, se reconfigura el display para 2x1627 y ya es posible usar el display mediante interrupciones. Es recomendable imprimir los mensajes con ayuda de las interrupciones (10H, 21H o 60H), ya que existe información que es constantemente actualizada dentro de un área de memoria reservada para el BIOS y el Monitor; si el despliegue de mensajes se realiza

27 En este punto es posible elegir otro tipo de display; por ejemplo un display de 4x20.

Page 30: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

23

directamente al display, es posible que algunas interrupciones no funcionen adecuadamente. 2.2.3 Revisión de la memoria RAM y ROM

La revisión de RAM consiste en almacenar cierta información, para después leerla y saber si efectivamente fue guardada; la revisión de ROM se realiza sumando todas sus localidades, el resultado esta suma debe concordar con un número ya conocido con anterioridad. Verificar la RAM consiste en dos pasos:

1. Se colocan 0’s en todas sus localidades y se verifica que todas sus localidades sean 0.

2. Finalmente se colocan 1’s (0FFH) y se verifica que todos los bits de todas sus localidades sean 1.

Si alguno de los pasos anteriores falla, el sistema muestra el mensaje

correspondiente y se detiene. El código es muy sencillo y se encuentra en el archivo CHKMEM.ASM, a continuación se muestra solo la parte que guarda y lee el dato en la RAM.

MOV CX, 1000H ;Contador desde 0 a 4096, es la mitad de la RAM. XOR DI, DI ;DI ayuda al direccionamiento, es el of fset. XOR AX, AX ;AX = 0, se llena de ceros la RAM. MOV ES, AX ;En este caso ambos registros de segme nto valen MOV DS, AX ;cero, pero solo se emplea el par ES:DI . CLD ;Incrementa DI en cada ciclo de REP. REP ;REP ejecuta la siguiente instrucción el núme ro STOSW ;veces que se especifico en CX. DEC DI ;DI = 1000H, habrá que decrementar en 2 par a que DEC DI ;inicie en 0FFEH. STD ;Ahora el regreso, se decrementa DI. MOV CX, 1000H ;Nuevamente la mitad de la RAM. REP ;Busca en la memoria un valor específico, en este SCASW ;el valor a buscar esta en AX y es cero. JZ CHKMEM_RAMOK ;Si todo bien, la bandera de cero e sta activa.

Observe que la revisión de la RAM se realiza por palabra de 2 bytes y no de 1 un byte, por lo que el conteo debe realizarse solo hasta la mitad del tamaño de la RAM. El código anterior, primero rellena de ceros todas las localidades con ayuda de la instrucción STOSW; esta instrucción coloca en la localidad, dado por dirección ES:DI, el valor de AX e incrementa o decrementa en dos el valor de DI, ello depende de la bandera de dirección que se modifica con las instrucciones CLD y STD. Aprovechando el valor de DI, se realiza ahora un búsqueda en memoria, esto se logra con la instrucción SCASW, que realiza un comparación del valor en memoria

Page 31: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

24

dado por ES:DI con el valor en AX, e incrementa o decrementa el valor en DI. Si el valor leído en memoria no concuerda con el valor en AX, la bandera de cero no se activa y es cuando se sabe del error. La segunda pasada, la realiza el mismo código, pero se cambia el valor en AX por el valor 0FFFFH. En la revisión de la ROM se involucra un suma de 16 bits; es decir, se suman todas las localidades de la ROM, excepto las dos últimas, y este valor se compara con el valor almacenado en las dos últimas localidades. La suma debe ser calculada antes de grabar la memoria y colocado en las dos ultimas localidades de la ROM. El código para la revisión es el siguiente:

MOV CX, 3FFEH ;Todo el tamaño de la ROM – 2 bytes. XOR DI, DI ;Contiene el offset. MOV AX, 0FC00H ;La ROM esta en el segmento 0FC00H, AX solo MOV DS, AX ;sirve como auxiliar, para cargar el se gmento. XOR AX, AX ;AX es el operador que lleva la suma. CONTINUA_ROM: MOV DX, [DI] ;El valor se carga en DX. INC DI ;Se actualiza el offset, se suma 2. INC DI ADD AX, DX ;Se hace la operación. LOOP CONTINUA_ROM CMP AX, [DI] ;Se compara el resultado de la suma co n el valor JE CHKMEM_ROMOK ;los últimos 2 bytes; si es igual, no hay error.

El código para la ROM resulta muy pequeño, ya que solo hay que sumar las localidades. Hay que mencionar que la suma es de 16 bits, y al momento de grabar la ROM, el grabador realiza la suma solo a 8 bits. Si la suma es a 8 bits, hay que cambiar la operación de la suma para tomar en cuenta los acarreos. 2.2.4 Carga de valores iniciales en memoria de configuración

Esta parte del BIOS se encarga de colocar, en su zona de memoria reservada, los valores por default de configuración; esta área de memoria abarca de la dirección 00400H hasta la dirección 006FFH. En la PC existe un área de memoria similar a la UAMI188EB, pero no es del todo compatible. La siguiente tabla muestra las direcciones, sus respectivos valores iniciales y si es compatible con la PC, en el Apéndice B se encuentra una descripción del uso que se le da a cada localidad de memoria, y en [9] una descripción de las que hay en la PC.

Page 32: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

25

Offset28 Compatible con la PC Valor de inicio

0400H Si 0FF60H

0402H Si 0FF00H

0404H Si 0000H

0406H Si 0000H

0410H Si 0000H

0413H Si 0008H

0417H Si 0000H

041AH Si 041EH

0449H Si 01H

044AH Si 0210H

0450H Si 0000H

0460H Si 0000H

0462H Si 0000H

046CH Si 0000H

046EH Si 0000H

0470H Si 00H

0480H Si 041AH

0482H Si 043CH

04F0H Si 0000H

0500H No *

0582H No 0000H

0584H No 00H

0588H No *

05B0H No 01H

05B1H No 4800H

05B3H No 03H

05B4H No *

05B6H No *

05B8H No *

05BAH No *

05BCH No *

05DAH No 00H

05DBH No 00H

05DDH No 01H

05DEH No 2000H

0600H No *

0700H No * Tabla 2.2 Valores de inicio de memoria. Los valores marcados con *

indican que se definen durante la ejecución de un programa, excepto para las direcciones 05BCH y 05DEH, que se verán en el Capitulo 3.

28 El segmento para todas estas variables es, por default 0000H.

Page 33: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

26

2.2.5 Inicio de los vectores de interrupción

El BIOS se encarga de colocar las respectivas direcciones de los procedimientos de algunas interrupciones, ver Tabla 2.3. Cada interrupción es identificada por un número, el cual a su vez identifica una zona de memoria, en donde se coloca la posición (segmento:offset) del procedimiento de dicha interrupción. La zona de memoria reservada para lo anterior se conoce como área de vectores de interrupción, y va de la dirección 00000H hasta la 003FFH.

No. de interrupción Descripción

00H División entre cero.

01H Interrupción de depuración (trazado).

03H Interrupción de punto de ruptura.

04H Desbordamiento (overflow).

05H* Error de límite (Bound error).

06H* Error de código en instrucción (unused opcode).

07H* Ejecución de instrucción ESC (escape opcode).

08H* Interrupción del temporizador 0.

0CH Interrupción por hardware 0.

0DH Interrupción por hardware 1.

0EH Interrupción por hardware 2.

0FH Interrupción por hardware 3.

10H Interrupción de servicios del display.

11H* Interrupción por hardware 4.

12H* Interrupción del temporizador 1.

13H* Interrupción del temporizador 2.

14H* Interrupción por recepción puerto serie.

15H* Interrupción por transmisión puerto serie.

16H Interrupción de servicios del teclado.

19H Interrupción de reset.

1AH Interrupción de servicios del temporizador.

1CH Interrupción del temporizador del sistema.

20H Interrupción de servicios tipo MS-DOS.

21H Interrupción de servicios tipo MS-DOS.

27H Interrupción de servicios tipo MS-DOS.

60H* Interrupción de utilerías de la UAMI188EB.

61H* Interrupción de banderas de equipo.

62H* Interrupción de tamaño de memoria.

63H* Interrupción de servicios de puerto serie.

64H* Interrupción para uso por Monitor.

70H* Interrupción de servicios de los temporizadores. Tabla 2.3 Lista de interrupciones. Las marcadas con * no son compatibles con la PC.

Page 34: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

27

Existen 256 interrupciones, la cuales no son empleadas todas, por lo que el

programador puede disponer de una gran cantidad de ellas en sus programas. Cuando el microprocesador recibe una interrupción (ya sea por software o

hardware), multiplica el número de la interrupción por 4 y el resultado es el offset donde obtendrá la dirección del procedimiento. Por ejemplo, cuando el microprocesador ejecuta la instrucción INT 21H, multiplica 21H por 4 y el resultado es tomado como un offset, debido a la posición de memoria la dirección obtenida es 0000:0084H, esta la dirección dice hacia donde debe continuar con la ejecución; es decir, el microprocesador guarda en la pila las banderas, y los registros IP y CS, y “brinca” a la dirección FC00:4456H, ver Fig. 2.1; ahora CS = 0FC00H e IP = 4456H, y se continua con la ejecución del código. El proceso anterior, es el que se sigue para cargar los vectores en memoria.

Figura 2.1 Ejemplo de interrupción.

Algunas interrupciones son semejantes a las que existen en una PC, esto se debe a que se trató de crear compatibilidad entre los programas de una PC y los de la UAMI188EB; sin embargo, esto no se logro del todo, pero se aseguró de que los cambios fueran mínimos. Para ver las diferencias entre la PC y la UAMI188EB, se puede consultar [9] y [11].

Un ejemplo de lo anterior, es que en una PC existe un contador del sistema, que no es sino un temporizador el cual se emplea como contador y como reloj de tiempo real. El contador registra el número de pulsos que suceden por el temporizador, estos pulsos son a una razón de 18.2 pulsos por segundos; en otras palabras en un día, este contador ya registro un número de 1572480 pulsos. La interrupción que atiende esta contador es la 08H. En la UAMI188EB, la interrupción es la 12H29 y la razón de pulsos es de 24 por segundo; es decir, 2073600 pulsos en un día.

29 En este caso se debió emplear el temporizador 0 y no el 1; sin embargo, el temporizador 0 esta destinado al usuario, por lo que se tuvo que usar el temporizador 1 para la UAMI188EB.

Page 35: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

28

Existe una interrupción que se emplea por lo regular para programas

residentes en una PC, la 1CH; recodemos que el sistema operativo MS-DOS es monolítico y no permite ejecutar varios procesos a la vez. Esta interrupción, permitía al MS-DOS tener varios procesos ejecutándose al mismo tiempo, con ciertas dificultades, ya que se dependía del temporizador del sistema. En la UAMI188EB se tiene la misma interrupción y es posible lograr el mismo objetivo que se perseguía con el MS-DOS; sin embargo, el problema aquí es que no hay un administrador de memoria, en el Capitulo 3 se vera con un mayor detalle esto.

Por otra parte, el área de vectores de interrupción es la misma que hay en una PC y el propósito es el mismo, almacenar las direcciones donde se localizan los procedimientos de atención a interrupciones. Finalmente lo que se hace por cada interrupción, es multiplicar su número respectivo por 4 y colocar el offset y el segmento de su procedimiento; el código es el siguiente:

CLD ;Incrementa DI XOR DI, DI ;Para colocar el segmento a 0000H, dond e se MOV ES, DI ;encuentra el área de los vectores. MOV AL, 04 ;Suponemos que en AH esta el número de interrupción MUL AH ;y lo multiplicamos por 4. MOV DI, AX ;El producto es el Offset. MOV AX, OFFSET ;Se coloca el offset del procedimien to. STOSW MOV AX, SEGMENTO ;Finalmente el segmento. STOSW

Todo el código se emplea para cada una de las interrupciones que se muestran

en la Tabla 2.3.

2.2.6 Inicio del hardware de la UAMI188EB

En este caso el BIOS simplemente activa los periféricos que serán usados por el Monitor y el propio BIOS; son únicamente dos:

• El temporizador 1 del 80C188EB,

• Y su puerto serie 0.

El temporizador 1 se configura para que genere un señal cuadrada asimétrica y se active su interrupción; en el comparador A se establece el número 0FFFEH, y en el comparador B el número 0E84AH. Esto genera una señal cuadrada con una frecuencia de 24 Hz; sin embargo, las interrupciones se generaran con una frecuencia

Page 36: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

29

igual al doble (48 Hz), debido a que cada vez que el contador alcanza el conteo en cada comparador, se dispara una interrupción.

La solución a lo anterior, es que la interrupción sea quien realice el monitoreo

de que registro de comparación se esta empleando. En los registros de control del temporizador, existe un bit que indica cual registro de comparación se esta empleando, al A o el B; sólo hay un registro contador, pero hay dos registros comparadores. Cuando se activa el temporizador, en cada ciclo de 1/4CLK (3 MHz) se incrementa en 1 el contador, cuando el contador llega al valor en el comparador A se dispara una interrupción, en ese instante se cambia al comparador B y se inicia el contador, cuando el contador alcanza el valor en el comparador B, se dispara otra interrupción, se inicia de nuevo el contador y se cambia al comparador A, este proceso se sigue indefinidamente. Este bit, llamado RIU en el registro de control30 permite saber que comparador se esta empleando; así cuando se dispara la interrupción, el proceso que la atiende primero examina este bit, si el comparador es A continúa con la ejecución normal; pero si es B, sale del procedimiento sin realizar nada. Con esto se logra que la interrupción se dispare aproximadamente a 24 Hz.

Una vez configurado adecuadamente el temporizador 1, el BIOS lo emplea

para tres propósitos:

• Un contador del sistema.

• Para el reloj de tiempo real.

• Un contador de segundos.

El contador del sistema es una variable de 32 bits en donde se almacenan el número de pulsos del temporizador 1; es decir, cuantas veces se ha disparado la interrupción del temporizador. Este contador se inicia en 0 y llega hasta 207359931, en un día a la frecuencia de 24 Hz, para después reiniciarse. Este contador también ayuda a saber la hora, ya que el día se divide en 2073599 pulsos del temporizador y simplemente hay que calcular el número de pulsos que corresponden a determinada hora; por ejemplo, las 01:00 hrs. corresponden a 86400 pulsos, este se toma como un reloj de tiempo real.

Finalmente el contador de segundos, es una utilería que no esta disponible en

la PC; ayuda a determinar el número de segundos transcurridos, en este caso el contador de segundos determina cuantos múltiplos de 24 han transcurrido en el contador del sistema. La interrupción con la que es posible emplear estos servicios es la 1AH.

30 Consultar [2] para una mejor descripción. 31 Esta constante esta el archivo de CONST.ASM, y esta dividida en dos constantes RELOJ_LTICKS y RELOJ_LTICKS.

Page 37: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

30

El puerto serie se emplea para comunicar a la UAMI188EB con el depurador D188.EXE, los parámetros de configuración del puerto son: velocidad igual 19200, modo 3 y paridad par. La variable que controla esta configuración se denomina UAMI188_D188_COM y se encuentra en el archivo CONST.ASM. El archivo que se encarga de activar el hardware es INITHARD.ASM; y los archivos para el control del temporizador y el serial son RELOJ.ASM y SERIAL.ASM respectivamente.

El puerto serie también puede ser accedido por medio de interrupciones, en

este caso la interrupción es la 63H32. Es posible emplearla sin ningún problema, pero primero hay que desconectar el programa D188.EXE de la UAMI188EB, esto se logra con la interrupción 60H subfunción 10H, ver Apéndice A, Sección A.6. 2.2.7 Ambiente del programa Monitor

Esta es una parte importante del BIOS, y se le conoce como entrada del BIOS. Se

encarga de preparar el ambiente para la ejecución del Monitor. Cuando se carga y ejecuta un programa en la UAMI188EB, este debe terminar de una manera correcta, debe informar al BIOS y al depurador D188.EXE que ya terminó su tiempo de ejecución; cuando ocurre esto, el programa le cede el control al BIOS33 y este restaura la configuración que se tiene cuando se enciente la UAMI188EB. Básicamente el BIOS realiza un reset. El proceso es el siguiente:

• Deshabilita todos los Chip-Select.

• Deshabilita todas las interrupciones externas.

• Desactiva todos los temporizadores.

• Reinicia el sistema.

• Envía una señal al D188.EXE para

No reinicia el sistema del todo, ya que no revisa la memoria y no restaura todos los valores de inicio en la memoria. Los únicos valores que se restaura son el buffer de registros (0000:05BCH), y la pila empleada por el Monitor (0000:05DEH).

Todo lo que se haya guardado en el área de vectores de interrupción no se

afectará, esto proporciona que interrupciones con código en la segunda ROM, estén siempre presentes.

Además de lo anterior, el BIOS antes de cargar el Monitor reinicia la pila; los

valores que asigna son: SP = 2000H y SS = 0000H. En este caso el registro SP tiene el valor del tamaño de la memoria RAM, esto se debe a que cada que se introduce algo

32 En la PC esta interrupción es la 14H. 33 Esto se logra con la interrupción 21H subfunción 4CH. Pero hay una forma de no ceder el control al BIOS con las interrupciones 20H y 27H; ver Capitulo3, Apéndices A y B.

Page 38: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

31

en la pila, este registro decrece en 2. Después de esto, el sistema esta listo para recibir el Monitor.

2.2.8 Carga del Monitor

Terminada le entrada del BIOS, se continua con la carga del Monitor, esta operación se le ha denominado entrada del Monitor. Básicamente son las siguientes líneas de código:

ENTRADA_MONITOR: STI ;Activa las interrupciones. CALL SER0_COLAVACIA ;Revisa la cola del puerto s erie. CMP AL, 01H ;Si AL=01H, entonces hay dato. JNE CONTINUA_MONITOREO ;Si hay datos los procesa JMP ENTRADA_MONITOR ;No hay datos, continua el m onitoreo. CONTINUA_MONITOREO: CALL SER0_OBTENDATO ;Obtiene el dato de la cola. CALL MONITOREO ;Procesa el dato. JMP ENTRADA_MONITOR El código revisa una cola en donde se almacenan los datos que son recibidos

por el puerto serie, de parte del programa D188.EXE. Si existen datos, se asume que es un comando del D188.EXE y es procesado por el monitor. Dependiendo del tipo de dato procesado, el monitoreo puede continuar o se le cede el procesador a algún programa. El funcionamiento del Monitor será explicado en el siguiente apartado.

2.3 Modelo del sistema La estructura del BIOS permite estar por encima del Monitor, todas las

operaciones que el Monitor realice, las hace a través del BIOS; puede pensarse que el Monitor es un sistema operativo, pero un sistema operativo hace una mayor administración de los recursos y de manera rigurosa; es decir, el Monitor simplemente administra el tiempo de microprocesador, pero en general un programa en ejecución tiene completa libertad de hacer lo que sea34, el Monitor no restringe esto.

Todo el sistema de la UAMI188EB consta de varios elementos, estos son:

• BIOS

• Monitor

• Depurador D188.EXE

• Los programas

34 En el Capitulo 3 se vera que el BIOS puede detener un programa con ayuda del depurador D188.EXE; esto se debe a que el BIOS controla la interrupción del puerto serie.

Page 39: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

32

Básicamente el BIOS tiene una jerarquía mayor, este programa tiene acceso directo a los recursos de la UAMI188EB; si se requiere de algún dispositivo, este debe solicitarse al BIOS por medio de las interrupciones de software. Por ejemplo, si el monitor hace uso del puerto serie para comunicación este lo realiza solicitando un servicio al BIOS, que en este caso son una conjunto de procedimientos dentro del archivo SERAL.ASM. Por otra parte, cuando el depurador se trata de comunicar con el Monitor, es el BIOS quien recibe la información y el Monitor se encarga de solicitar esta información, ver Fig. 2.2.

Figura 2.2 El sistema completo de la UAMI188EB. Las líneas indican el flujo de la información entre los

diversos componentes; la línea punteada muestra un flujo de información alternativo, pero que el programador debe asegurar para evitar desestabilizar todo el sistema.

En los programas se intenta algo similar, si este requiere de un servicio o algún

recurso, puede solicitarlo al Monitor o al BIOS; sin embargo, esto no es completamente necesario, a final de cuentas un programa puede acceder a cualquier recurso dentro de la UAMI188EB sin pasar por el BIOS; un ejemplo claro es el display, un programa para poder imprimir un carácter en el display puede realizarlo de dos formas, con las interrupciones 10H o 60H, o accediendo directamente al display por medio de las instrucciones IN y OUT. Esto ultimo en este caso, no es

aconsejable ya que el BIOS almacena determinados valores, por ejemplo posición del cursor, tipo de display, etc., que se perderían si no se emplean las interrupciones. Aun así, hay ciertos recursos en los que el BIOS no tiene ningún control y si algún programa los necesita tendrá que acceder directamente a ellos.

Page 40: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

33

Capitulo 3. El programa Monitor

3.1 Introducción El programa Monitor, se encarga básicamente de establecer la comunicación entre la UAMI188EB y el programa D188.EXE. Esta comunicación se realiza mediante el empleo de comandos; es decir, el D188.EXE envía por el puerto serie un determinado byte, que es traducido por el Monitor o el BIOS como un comando o una acción a seguir.

Cada comando tiene un determinado significado; por ejemplo, para enviar un archivo desde el D188.EXE a la UAMI188EB, primero se envía el comando respectivo para establecer la comunicación, para después enviar la información correspondiente.

El Monitor en todo momento esta a la espera de comandos; sin embargo, como

el BIOS es quien captura primero el comando, puede atenderlo o en todo caso permitir que el Monitor actúe, esto depende del tipo de atención que requiera el comando.

3.2 Funcionamiento del Monitor Una vez que el BIOS cede el control del microprocesador al Monitor, este se dedica a esperar comandos del depurador D188.EXE. Un comando es un byte que indica una determinada acción; el programa D188.EXE envía un comando y la UAMI188EB determina que acción realizara en base al comando que capturó; cada comando ejecuta un cierto procedimiento (ver archivo MONITOR.ASM35).

Sin embargo no sólo el Monitor puede procesar comandos, ya que existen comandos que requieren de atención inmediata, por lo que estos son procesados por el BIOS. En este caso sólo existen 3 comandos que pueden ser procesados directamente por el BIOS, los demás no requieren pronta atención, por lo que son procesados por el Monitor. La función del Monitor es esperar a que existan datos en el buffer de recepción

del puerto serie, este buffer es controlado por el procedimiento de interrupción del BIOS para el puerto serie, es una cola circular que se localiza en la dirección 0000:0470H. Cuando el buffer contiene algún dato, el Monitor lo extrae y determina si este dato es un comando valido o no. La Fig. 3.1 muestra el diagrama de flujo del funcionamiento del Monitor.

35 Durante todo el capitulo sólo se mencionan algunos archivos, pero una mejor referencia de las funciones y el nombre del archivo donde se localizan es en el Apéndice E.

Page 41: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

34

Figura 3.1 Funcionamiento del Monitor. La línea punteada indica que hay más procedimientos para

procesar un comando.

Cuando el usuario solicita una operación sobre la UAMI188EB por medio del D188.EXE, este lo traduce en un comando que es enviado a la UAMI188EB. El comando es recibido por el procedimiento de interrupción del puerto serie (ver Fig.

Page 42: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

35

3.2B), si el comando requiere pronta atención, es procesado por el mismo procedimiento, de otra forma será enviado al buffer de puerto serie. Como puede observarse el proceso es muy simple; sin embargo, no es muy estable debido a que si un programa ajeno al D188.EXE envía datos a la UAMI188EB o existen errores en la transmisión, es probable que se detenga la ejecución del Monitor si este dato concuerda con un comando.

Otro problema radica en el buffer donde se almacenan los comandos, ya que este tiene una capacidad de 14 bytes; si el buffer se llena los comandos que lleguen se perderán. Aunque es muy difícil que lleguen 14 comandos a la vez, ya que el D188.EXE sólo permite un comando a la vez. Para determinar que comando puede pasar, existe algo que se conoce como estados de la UAMI188EB, que se describe en la siguiente sección.

3.3 El estado de la UAMI188EB El programa D188.EXE sabe en que situación se encuentra la UAMI188EB por sus estados; cada estado tiene un significado y representa una acción que se esta realizando en la UAMI188EB. Se tienen 5 estados, los cuales son36:

• OK(0)37: La UAMI188EB se encuentra lista para recibir algún comando. Este estado es el que se asigna cuando la UAMI188EB ha sido iniciada.

• STP(1): Existe un programa cargado en la UAMI188EB y esta listo para ejecutarse.

• RUN(2): Un programa se esta ejecutando en estos momentos.

• DBG(4): Se esta trazando un programa, por lo que sólo se ejecuta una instrucción a la vez.

• DSC(8): La UAMI188EB se ha desconectado o no se puede establecer comunicación.

Según el estado en el que se encuentre, también será el comando que puede estar activo; es decir, no todos los comandos son válidos, ello depende del estado en que se encuentra la UAMI188EB. Los estados son almacenados en la memoria de la UAMI188EB, para ser precisos en la dirección 0000:05B0H, por lo que es de vital importancia que ningún programa modifique el contenido de esta localidad.

36 Estos estados también están presentes al usuario, ya que se muestran en la parte superior derecha de la interfaz del programa D188.EXE, ver Apéndice A. Por otra parte existe un estado adicional, este es el estado de desconocido (UKN); es decir, la UAMI188EB esta operando, pero el D188.EXE desconoce el estado. Ocurre generalmente cuando la UAMI188EB, al estar desconectada del D188.EXE, se intenta conectar. 37 El número entre paréntesis, representa el identificador asignado al estado.

Page 43: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

36

3.4 Los comandos Existen 21 comandos de comunicación entre la UAMI188EB y el Monitor, algunos comandos son de uso exclusivo por el programa D188.EXE, otros son compartidos, y algunos son exclusivos de la UAMI188EB. Los comandos sólo están disponibles dependiendo del estado del sistema; por ejemplo, CMSEND sólo es empleado por la UAMI188EB, y se usa cuando se esta ejecutando un programa, el estado del sistema debe ser RUN. Las Tablas 3.1 y 3.2, muestran la lista del comandos y que estado los activa.

Comando

UAMI188EB a D188.EXE

D188.EXE a UAMI188EB

Programa que lo recibe y procesa

CMSOK √ √ BIOS/D188.EXE

CMSRESET √ BIOS

CMSCARGA √ Monitor

CMSEJECUTAR √ Monitor

CMSPASO √ √ Monitor/D188.EXE

CMSEND √ D188.EXE

CMSERROR √ D188.EXE

CMSOBTENMEM √ Monitor

CMSMUEVEMEM √ Monitor

CMSOBTENREG √ Monitor

CMSDETENER √ BIOS

CMSDESCONECT √ D188.EXE

CMSCONECTAR √ D188.EXE

CMSOBTENRET √ Monitor

CMSOBTENERR √ Monitor

CMSOBTENPRG √ Monitor

CMSCARGAREG √ Monitor

CMSCARGAMEM √ Monitor

CMSACERCADE √ Monitor

CMSRESIDENTE √ Monitor

CMSFIJAHORA √ Monitor Tabla 3.1 Lista de comandos. Las columnas 2 y 3 muestran de donde parte el comando y hacia donde

llega. La última columna muestra el programa que procesa el comando en la UAMI188EB. La estructura del Monitor permite agregar más comandos, para ello es necesario asignarle un número y agregarlo a los archivos CONST.ASM y CM_SERIA.H. Para que el Monitor lo procese, su procedimiento deberá ser agregado al archivo MONITOR.ASM, dentro del procedimiento MONITOREO; observe que la estructura dentro de este procedimiento, es semejante a la instrucción switch del lenguaje C.

Page 44: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

37

Si el comando es para el D188.EXE, el proceso es un poco más complicado, ya que estos comandos son recibidos en el programa por medio de una interrupción dentro de una estructura de eventos38; el manejo de la interrupción es muy similar al proceso del Monitor, ya que también se tiene una cola circular (ver archivos PSERIE.H y PSERIE.CPP). Sin embargo, debido a la estructura de la interfaz, es posible dañar el programa si el código que atiende el comando es muy largo. En este caso, el comando es recibido por la función DUAMI188::handleEvent en el archivo EDIT188A.CPP; de igual manera es mediante un switch.

Estados Comandos OK STP DBG RUN DSC/UKN

CMSOK √ √ √ √ √

CMSRESET √ √ √ √

CMSCARGA √ √

CMSEJECUTAR √ √

CMSPASO √ √

CMSEND √ √

CMSERROR √ √

CMSOBTENMEM √ √ √

CMSMUEVEMEM √ √ √

CMSOBTENREG √ √ √

CMSDETENER √ √

CMSDESCONECT * √

CMSCONECTAR √

CMSOBTENRET √

CMSOBTENERR √

CMSOBTENPRG √ √ √

CMSCARGAREG √ √ √

CMSCARGAMEM √ √ √

CMSACERCADE √ √

CMSRESIDENTE √

CMSFIJAHORA √ Tabla 3.2 Estados en los que es posible ejecutar un comando. El símbolo * indica que no se debe

depurar un programa que se desconecta de la UAMI188EB, ya que el sistema lo permite.

3.5 Comunicación de comandos Cuando el usuario hace una solicitud al D188.EXE, por ejemplo cargar un programa a la UAMI188EB, este lo traduce en un comando. El primer paso que realiza el D188.EXE, es verificar el estado del sistema; de esta forma se sabrá si es

38 La interfaz del D188.EXE tiene su base de funcionamiento por medio de eventos; el mezclar esto con interrupciones puede provocar situaciones inesperadas. Una mejor exposición de lo anterior se encuentra en [8].

Page 45: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

38

posible ejecutar el comando. La Fig. 3.2 muestra el diagrama de flujo para obtener el estado del sistema, observe que este comando requiere atención inmediata, por lo que es procesado por el BIOS y no por el Monitor.

Figura 3.2 En A se muestra lo que ocurren en el depurador D188.EXE al solicitar el estado del sistema. En B se tiene el procedimiento de interrupción del BIOS para el puerto serie. Los procedimientos son

PROC_CMSOK en MONITOR.ASM e INTERRUPT_RX_SERIAL0 en SERIAL.ASM.

Una vez que se tiene el estado, el D188.EXE verifica si el comando puede ser procesado, esto se determina con ayuda de la Tabla 3.2. Observe que es el D188.EXE quien decide si el comando es válido, y no el Monitor; el comando se ejecuta por parte del Monitor independientemente de que este sea válido o no, por lo que el Monitor depende en gran medida del D188.EXE.

Si el comando es válido para el estado, entonces el programa D188.EXE envía el correspondiente comando (la acción deseada) y espera a que la UAMI188EB

Page 46: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

39

conteste con el comando CMSOK39; de esta forma la UAMI188EB y el depurador

D188.EXE proceden a intercambiar información. El intercambio de comunicación que se sigue después de cada comando, puede variar según el tipo de comando que se trate, en algunos casos el depurador D188.EXE sólo espera el comando CMSOK y listo, en otros casos es necesario establecer todo un proceso de intercambio de información. El Apéndice D muestra la lista de funciones y procedimientos de los programas BIOS, Monitor y D188.EXE, que se relacionan con cada uno de los comandos mostrados en la Tabla 3.2. 3.5.1 CMSOK

Este comando es empleado tanto por la UAMI188EB como por el depurador D188.EXE, de esta forma tiene tres funciones:

• Informar al D188.EXE que la UAMI188EB esta activa. En esta forma, la UAMI188EB sólo emplea este comando en el inicio, y cuando trata de establecer una conexión; es posible desconectar a la UAMI188EB del programa D188.EXE, y usar el puerto serie para otra aplicación; cuando se desea usar nuevamente el programa D188.EXE, la UAMI188EB envía el comando CMSOK, dejando en el depurador D188.EXE el estado UKN. El programa D188.EXE desconoce el estado, por lo que es necesario preguntar a la UAMI188EB acerca de su estado.

• Solicitar el estado a la UAMI188EB. El D188.EXE con este comando solicita el estado de la UAMI188EB, ver Fig. 3.1.

• Para informar que se recibió con éxito una serie de datos. La UAMI188EB emplea el comando de esta manera, para hacer saber al D188.EXE, que recibió los datos.

3.5.2 CMSRESET

Cuando se envía este comando, se reinicia la UAMI188EB; mientras tanto, el depurador D188.EXE espera por el comando CMSOK, lo cual indica que la UAMI188EB se ha reiniciado satisfactoriamente; esto es, siempre que se inicia el

39 En todas las comunicaciones, cuando se trata de esperar una respuesta por parte de la UAMI188EB o por parte del D188.EXE, se activa un contador de segundos. Este reloj permite definir cuantos segundos se puede esperar para una respuesta, si el tiempo se cumple y no se ha recibido respuesta, la operación que se estaba realizando se cancela. En el caso de la UAMI188EB, la cancelación hace que se regrese el control al Monitor, en el caso del D188.EXE se informa esta cancelación. El tiempo de espera se puede modificar para ambos, para la UAMI188EB el tiempo se espera se define en la dirección 0000:05B3H; en el D188.EXE el tiempo de espera se define en el menú de Opciones; para ambos es de 2 segundos por default.

Page 47: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

40

Monitor envía el comando CMSOK. El procedimiento en el Monitor es PROC_CMSRESET y se encuentra en el archivo MONITOR.ASM. 3.5.3 CMSCARGA

Este comando informa a la UAMI188EB que se prepare para recibir un programa, el procedimiento es PROC_CMSCARGA en MONITOR.ASM y se muestra en la Fig. 3.3. Observe que sólo se pueden recibir programas de a lo más 64Kb, ya que el tamaño de este sólo ocupa 2 bytes. Por otra parte, cuando el dato es recibido se le aplica un NOT y es enviado de regreso al D188.EXE, esta es una forma de verificar que los datos que se envían lleguen correctamente, el depurador D188.EXE compara el dato y si es correcto, continua con la carga, de otra forma interrumpe el proceso.

Figura 3.3 Comando CMSCARGA.

Page 48: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

41

La función PREPARA_MONITOR (archivo MONITOR.ASM) se encarga de

crear el ambiente para la ejecución del programa que se cargó, este realiza lo siguiente:

• Borrar el buffer de registros que se encuentra a partir de la dirección 0000:05BCH.

• Asigna a cada registro un valor de inicio, estos valores se almacenan el buffer de registros y se muestran en la Tabla 3.3.

• Limpia el display de la UAMI188EB y presenta el mensaje de “Esperando...”. Registro (Dirección) Valor inicial Registro (Dirección) Valor inicial

AX (0000:05BCH) 0000H SP (0000:05CAH) PILA_MONITOR

BX (0000:05BEH) 0000H DS (0000:05CCH) PROGRAMA_SEG

CX (0000:05C0H) 0000H ES (0000:05CEH) PROGRAMA_SEG

DX (0000:05C2H) 0000H SS (0000:05D0H) STACK_SEG

DI (0000:05C4H) 0000H CS (0000:05D2H) PROGRAMA_SEG

SI (0000:05C6H) 0000H IP (0000:05D4H) PROGRAMA_OFF

BP (0000:05C8H) 0000H FLAG (0000:05D6H) 0200H Tabla 3.3 Valores iniciales de los registros en el buffer de registros.

Algunos valores pueden cambiar, ello depende de la historia del Monitor. Otros valores son constantes que se pueden cambiar, pero que será necesario compilar de nuevo el BIOS y el Monitor. Las siguientes constantes están en el archivo BIOSVARS.ASM y sus valores son:

PROGRAMA_SEG = 0070H PROGRAMA_OFF = 0000H STACK_SEG = 0000H

En cuanto al registro SP, este valor no es una constante. PILA_MONITOR es una localidad en memoria (0000:05DEH) donde se almacena el offset donde inicia la pila. Este offset puede ser modificado para que cuando se cargue un nuevo programa se asigne un offset de pila diferente. Por default el valor es de 2000H (tamaño de la RAM), y cuando el BIOS toma el control, se encarga de fijar este valor, ver sección 3.6. Finalmente, todas la banderas del registro de banderas (FLAG) están desactivadas, excepto la bandera de habilitación de interrupción, que esta dado por el bit 9 de dicho registro. 3.5.4 CMSEJECUTAR y CMSPASO

El Monitor al recibir el comando CMSEJECUTAR ejecuta el programa (o el código) que se encuentra cargado en la memoria de la UAMI188EB, el proceso es

Page 49: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

42

realizado por el procedimiento PROC_CMSEJECUTAR en MONITOR.ASM; los pasos

son los siguientes:

• envía comando CMSOK.

• Coloca el estado RUN.

• Carga los registros con los datos del buffer de registros.

• Ejecuta el programa y cede el control. El comando CSMPASO es similar al comando CMSEJECUTAR; de hecho es el

mismo código, salvo por que después de cargar los registros con los del buffer, activa la bandera de trazado del registro de banderas (FLAG), esta bandera es controlada por el bit 8 del registro FLAG.

Otra diferencia es en cuanto a la forma en que se llama al código o procedimiento del comando, ya que en el caso del comando CMSPASO, el procedimiento es una interrupción, la número 64H. Esto ofrece la flexibilidad de que el usuario pueda cambiar el proceso que realiza este comando, ya que sólo hay que colocar el código correspondiente en el vector de interrupciones para la 64H. El procedimiento actual se llama INTERRUPT_INT64H y se encuentra en MONITOR.ASM.

3.5.5 CMSEND

Este es un comando empleado por la UAMI188EB, para informar al depurador D188.EXE que un programa ha terminado. Cuando se ejecuta un programa en la UAMI188EB, este de alguna forma debe terminar y no ejecutarse infinitamente. Para informar al BIOS y al D188.EXE que un programa ha terminado su ejecución, se emplea la interrupción 21H subfunción 4CH (Apéndice B y Sección 3.5.11); esta rutina envía el comando CMSEND al D188.EXE y cede el control al BIOS. Cuando el D188.EXE recibe el comando CMSEND, solicita a la UAMI188EB el número de retorno que el usuario asignó al finalizar el programa con la interrupción 21H, ya que la interrupción almacena en memoria este número, en la dirección 0000:05DAH. 3.5.6 CMSERROR

Este comando también es empleado por la UAMI188EB, y sirve para informar al D188.EXE que el programa en ejecución provocó un error. Los errores son capturados por medio de interrupciones y los más comunes son:

• División entre cero (INT 00H).

• Desbordamiento (overflow, INT 04H).

Page 50: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

43

• Error de límite (bound error, INT 05H).

• Código de instrucción no valido (unused opcode, INT 06H).

• Instrucción ESC40 (INT 07H). Cuando alguno de los errores anteriores ocurre, una interrupción detiene el programa en ejecución, almacena el código del error en la dirección 0000:05DBH, envía el comando CMSERROR al D188.EXE y retorna el control al BIOS. Al recibir el comando el D188.EXE, este solicita a la UAMI188EB el código de error y lo presenta en pantalla, este código de error ayuda a identificar cual de la lista anterior ocurrió. 3.5.7 CMSOBTENMEM y CMSOBTENPRG Ambos son el mismo comando, ya que comparten el mismo código, pero en este caso se hace una diferencia para versiones futuras. Estos comandos sirven para que el D188.EXE solicite cierta cantidad de bytes almacenados en memoria, a partir de una dirección inicial. La siguiente Fig. 3.4 muestra el diagrama de flujo de comunicación entre el D188.EXE y la UAMI188EB. Observe en la figura que los únicos datos necesarios son el segmento, el offset y el número de bytes que se leerán a partir de esa dirección. Los procedimientos que realizan lo anterior son PROC_CMSOBTENPRG y PROC_CMSOBTENMEM en MONITOR.ASM; sin embargo, aun cuando los procedimientos tienen un nombre diferente, apuntan al mismo código. El D188.EXE es el que se encarga de diferenciar este comando, ya que cuando aplica el comando CMSOBTENMEM, los bytes que recibe son cargado al buffer de volcado de memoria; en cambio cuando ejecuta el comando CMSOBTENPRG, los bytes recibidos son introducidos al buffer de depuración. 3.5.8 CMSMUEVEMEM

Este comando mueve bloques de memoria dentro de la UAMI188EB, el monitor no realiza ninguna comprobación acerca de la validez del bloque o el destino del bloque, en general cualquier dirección del origen y el destino son aceptados. El procedimiento es PROC_CMSMUEVEMEM en el archivo MONITOR.ASM. El proceso de comunicación es el siguiente:

• La UAMI188EB al recibir el comando CMSMUEVEMEM envía el comando CMSOK.

40 Este no es precisamente un error; sin embargo como es empleado en coprocesadores, se toma como un error debido a que la UAMI188EB no cuenta con este soporte.

Page 51: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

44

• Cuando el D188.EXE recibe el comando CMSOK, envía y en ese orden, segmento y offset destino, segmento y offset origen, y finalmente el número de bytes.

• Con los datos anteriores, el Monitor inicia el movimiento en memoria.

El D188.EXE al enviar los datos necesarios para mover el bloque de memoria, no espera ninguna respuesta por parte de la UAMI188EB; esta última al recibir el último byte de dato, realiza el movimiento de bloque con la instrucción MOVSB. Note que la instrucción en realidad no mueve un bloque de memoria, sólo copia los bytes de un lugar a otro.

Figura 3.4 Comandos CMSOBTENMEM y CMSOBTENREG. En A se muestra el flujo de lo que ocurre

en la UAMI188EB, mientras en B lo que ocurre en el depurador D188.EXE41.

41 Recuerde que cuando se trate de transferencia de datos, el programa que recibe espera cierta cantidad de segundos entre cada byte, antes de cancelar la operación. En los diagramas de flujo, para evitar que estos sean muy extensos ya no se hará mención de ello.

Page 52: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

45

3.5.9 CMSDETENER

Este es un comando que captura el BIOS, para detener la ejecución de un programa. Cuando el BIOS captura este comando, envía el comando CMSOK al D188.EXE y cede el control al Monitor. El procedimiento encargado de lo anterior es PROC_CMSDETENER y se encuentra en el archivo MONITOR.ASM. 3.5.10 CMSDESCONECT y CMSCONECTAR42

Este es un comando empleado por la UAMI188EB, es enviado cuando un programa ejecuta la instrucción INT 60H subfunción 10H (ver archivo INT60.ASM, procedimiento INT60H_10H) . En este caso, la UAMI188EB informa al D188.EXE que se desconecta o conecta. Cuando la UAMI188EB se desconecta, envía el comando CMSDESCONECT al D188.EXE, para que este desactive toda comunicación con la UAMI188EB; mientras que el BIOS de este ultimo, permite que el puerto serie sea empleado por alguna otra aplicación. De este forma, el D188.EXE ya no tiene ningún tipo control sobre la UAMI188EB. Si la UAMI188EB se conecta, envía el comando CMSCONECT, de esta manera el D188.EXE sabe que la UAMI188EB puede recibir comandos. Cuando la UAMI188EB se conecta de esta forma, el D188.EXE no tiene manera de saber su estado, por lo que el usuario esta encargado de ejecutar el comando Verificar conexión del menú del D188.EXE. 3.5.11 CMSOBTENRET

Todos los programas que son ejecutados en la UAMI188EB deben informar al BIOS, al Monitor y al D188.EXE que su ejecución ha terminado; esto se puede realizar de varias formas, ver Tabla 3.4.

Instrucción BIOS Monitor D188.EXE

INT 20H √ √ INT 21H subfunción 4CH √ √ √ INT 27H √ √

Tabla 3.4 Instrucción para informar que un programa ha terminado de ejecutarse. Unicamente la instrucción INT 21H, informa a los tres programas.

42 El empleo de esta característica de desconexión y conexión, debe ser empleada con precaución, ya que cuando la UAMI188EB esta desconectada, no puede hacer uso de procedimientos que se intentan conectar con el D188.EXE, ya que esto puede provocar que el sistema no funcione correctamente, un ejemplo de lo anterior, es la depuración.

Page 53: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

46

Con alguna de estas instrucciones debe finalizar un programa; la diferencia entre ellas se explica a detalle en la Sección 3.6. Por lo pronto, cuando alguna de las dos primeras instrucciones es ejecutada, se envía el comando CMSEND al D188.EXE; cuando el D188.EXE recibe este comando, envía el comando CMSOBTENRET a la UAMI188EB para obtener el código que retorno el programa. Este código es empleado por el programador para definir un estado o clave que identifique algún resultado de la ejecución del programa; por ejemplo cuando el programa termina con alguna clase de error, el programador puede emplear este código para informar el tipo de error que ocurrió. Cuando la UAMI188EB recibe el comando CMSOBTENRET, envía de inmediato este código de retorno, el cual se encuentra almacenado en la dirección 0000:05DAH. El procedimiento encargado de lo anterior es PROC_CMSOBTENRET en MONITOR.ASM. 3.5.12 CMSOBTENERR

Es el mismo caso del comando CMSOBTENRET; sin embargo, este comando lo envía el D188.EXE cuando ha recibido el comando CMSERROR (ver Sección 3.5.6). La UAMI188EB simplemente envía el código error, que especifica el tipo de error que ocurrió en la UAMI188EB. La siguiente tabla muestra el código asociado con el error.

Error Código

División entre cero. 1

Desbordamiento (overflow). 2

Error de límite (bound error). 3

Código de instrucción no valido (unused opcode). 4

Instrucción ESC. 5

Tabla 3.5 Códigos de error controlados por interrupciones. 3.5.13 CMSOBTENREG Este comando envía todo el contenido del buffer de registros dentro de la UAMI188EB. Cuando la UAMI188EB recibe este comando, envía el comando CMSOK y después de esto, envía todo el buffer de registros, en el orden en el que se encuentran en el buffer (ver Tabla 3.3). El depurador D188.EXE se encarga entonces de ordenar esta información y presentarla en la ventana del depurador. El procedimiento implicado es PROC_CMSOBTENREG en MONITOR.ASM.

Page 54: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

47

3.5.14 CMSCARGAREG

Este comando sirve para modificar el valor de algún registro en el buffer de registros de la UAMI188EB. Una vez que el programa D188.EXE recibe el comando CMSOK por parte de la UAMI188EB, este envía 3 bytes que representan el valor del registro (2 bytes) y el número de registro. Para calcular la posición del registro en el buffer, el programa multiplica el número de registro por 2 y lo suma al offset 05BCH, de esta forma se tendrá la dirección completa en donde se debe almacenar el valor. 3.5.15 CMSCARGAMEM

Este comando sirve para colocar información en la memoria de la UAMI188EB; el proceso es el siguiente:

• Cuando el D188.EXE recibe el comando CMSOK, envía el segmento, offset y número de bytes a cargar en memoria.

• El D188.EXE envía los bytes que serán almacenados en memoria.

• La UAMI188EB recibe cada byte, y los almacena a partir de la dirección especificada; retorna el control al Monitor.

3.5.16 CMSACERCADE

Manejado internamente por el depurador D188.EXE. Es ejecutado cuando se llama al comando Acerca de ... en el menú del D188.EXE, y presenta los créditos del BIOS y el Monitor. 3.5.17 CMSRESIDENTE

Este comando es enviado por la UAMI88EB cuando un programa ejecuta la instrucción INT 27H. Esta interrupción permite colocar código residente para otras aplicaciones o código que se esta ejecutando permanentemente en la UAMI188EB, ver Apéndice A y Sección 3.6. 3.5.18 CMSFIJAHORA

Este comando fija la hora en la UAMI188EB, y es empleado internamente por el depurador D188.EXE cuando es iniciado. Cuando la UAMI188EB recibe este comando realiza los siguientes pasos:

• Inhabilita las interrupciones por puerto serie

• envía comando CMSOK y espera por la hora.

Page 55: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

48

• Cuando el D188.EXE recibe CMSOK, envía 4 bytes que son de los que se compone la hora.

• La UAMI188EB cambia entonces la hora, activa interrupciones y regresa el control al Monitor.

3.6 Código residente En el sistema operativo MS-DOS, existía la opción de permitir ejecutar un programa residente; esto es, un programa que podía ejecutarse en segundo plano, mientras el sistema operativo (línea de comando) u otro programa se encontraba en ejecución. Para lograr esto, el programa residente se apropiaba de alguna interrupción. El caso más común es el de un reloj, mediante la interrupción 1CH43; sustituyendo el procedimiento de atención de interrupción por uno propio, este procedimiento se encargaba de imprimir la hora en pantalla. Cada programa residente, tenia la obligación de reservar cierta cantidad de memoria, e incluso reservar la parte de memoria donde se encontraba el código; esto se lograba con la interrupción 27H. En la UAMI188EB existe una opción semejante; sin embargo, el MS-DOS permite la administración de la memoria, cosa que el Monitor no realiza. Para evitar este problema, el Monitor recorre el valor del registro SP; en lugar de colocar 2000H44, se fija otro valor el cual depende del tamaño de memoria que se desee. Cuando se ejecuta un programa, el Monitor define el valor de los registros que empleara el programa (ver Tabla 3.3), uno de estos registros es el SP. Este registro junto con el registro SS, definen la dirección donde se almacenan los datos que se

introducen a la pila; en general la pila se define desde la última localidad de memoria. Al momento en que el Monitor fija el registro SP, lo hace tomando el valor de la localidad 0000:05DEH (PILA_MONITOR); el BIOS siempre fija el valor de esta localidad en 2000H, por lo que el monitor asignara el valor 2000H al registro SP. Cuando se inicia la UAMI188EB, al terminar de ejecutar un programa o en caso de error, el BIOS tomará el control y fijará el valor de la dirección 0000:05DEH en 2000H. Para evitar que el BIOS tome el control, se emplea la interrupción 27H, que recibe como parámetro el número de bloques de 16 bytes para reservar; si se reservan 10 bloques (160 bytes), entonces la interrupción cambia el valor de 2000H en la dirección 0000:05DEH, por el valor de 2000H – A0H = 1F60H. Cuando se ejecute un programa, el Monitor asignara en SP el valor 1F60H, dejando el resto de la memoria para el programa residente.

43 Esta interrupción es llamada unas 24 veces en un segundo, por el temporizador del sistema. 44 Este valor corresponde al tamaño de la memoria RAM; cada que se almacena un valor en la pila, el registro SP decrece en 2 y se introduce el valor en la dirección dado por SS:SP.

Page 56: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

49

Para crear un programa residente en la UAMI188EB se requiere de lo siguiente:

• El código que quedará residente, y que se coloca en la segunda ROM.

• El programa que deje residente el código, con la interrupción 27H. El primer programa es el código que estará residente en la UAMI188EB, este programa es “invisible” al Monitor, y puede ser descargado cuando se cede el control al BIOS por alguno de los mecanismos anteriores. El segundo programa es el que fija el código de la segunda ROM y ejecuta la interrupción 27H.

Como un ejemplo, el siguiente programa reserva 160 bytes (que es el valor máximo) para un programa residente.

Código residente en segunda ROM Programa que fija el código residente ... XOR AX, AX MOV DS, AX MOV BX, 01F60H ;Emplea la memoria MOV [BX], VAR1 ;reservada …

… ;Carga el código residente … MOV DX, 000AH ;10 bloques de 16 bytes. INT 27H ;Permite dejar el código residente.

Tabla 3.6 Ejemplo de carga de código residente.

Note que el programa que queda residente, emplea la memoria desde la posición que le fue asignada 1F60H hasta la posición 2000H. Una vez cargado el código residente, si se desea que ahí permanezca, aun cuando se ejecutan otros programas, estos deberán terminar con la interrupción 20H y no con la 21H; la interrupción 20H cede el control al Monitor y no al BIOS como lo hace la 21H, el ceder el control al BIOS implica eliminar el programa residente; pero ceder el control al Monitor, implica que la configuración que deje un programa perdurara. La interrupción 20H y 21H también pueden servir para fijar un programa residente, siempre y cuando este no utilice la memoria. Por ejemplo, el siguiente fragmento de código que se localiza en la segunda ROM: PROC MI_INTERRUPCION PUSH AX PUSH BX .... ;Operaciones ... POP BX POP AX IRET

Se desea fijarlo en el vector de interrupción 80H; el programa que fija el código

anterior, puede simplemente terminar con la interrupción 20H o 21H; en este caso no importa que el BIOS tome el control, ya que restaura los vectores de las

Page 57: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

50

interrupciones que se listan en el Apéndice B, pero no los demás. Por lo tanto, el código anterior podrá ser accedido por los programas mediante la instrucción INT

80H.

3.7 Trazado de programas Existen dos interrupciones para el trazado de un programa, la interrupción 01H y la interrupción 03H45. En el depurador, ambas interrupciones tienen el mismo objetivo, pero para llegar a el, lo realizan de diferente manera; esto se debe a la naturaleza de cada interrupción. Cuando el programa D188.EXE envía el comando CMSPASO, el Monitor activa la bandera de trampa46, cambia en estado de la UAMI188EB a RUN y ejecuta el programa cargado en memoria. Al activar esta bandera, el microprocesador ejecutará una instrucción e inmediatamente después aparecerá la INT01H. El procedimiento de la interrupción envía el mensaje de CMSPASO al D188.EXE, detiene el programa, almacena el valor de los registros y retorna el control al Monitor. Existen algunos casos en los que la INT01H no se activa; estos son:

• En la instrucción de fin de procedimiento como IRET.

• Instrucciones que modifiquen registros de segmento, por ejemplo POP DS.

• Instrucciones de prefijo, como REP.

• En instrucciones del tipo WAIT.

Cuando la instrucción es una interrupción (por software o hardware), el microprocesador permite que se “salte” a la dirección donde se encuentra el procedimiento de atención, e inmediatamente después envía la INT01H, sin permitir que se ejecute la primera instrucción del procedimiento de atención de interrupción. Debido a lo anterior, surgen algunos problemas por resolver; estos son:

1. Antes de que el microprocesador ejecute una instrucción, puede entrar una interrupción por hardware. La solución es permitir que se ejecute esa interrupción por hardware.

2. La primera instrucción puede ser una interrupción por software. En este caso nuevamente se permite que se ejecute todo el procedimiento de la interrupción por software.

3. Después de ejecutar una instrucción, puede entrar una interrupción por hardware. La solución es cancelar esta interrupción por hardware, y dar continuidad a la INT01H.

45 Estas interrupciones tienen baja prioridad. En adelante serán llamadas INT01H e INT03H respectivamente. 46 Ver Capitulo 1, Sección 1.2.6.

Page 58: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

51

3.7.1 Interrupción 01H

Cuando entra esta interrupción, el primer paso es verificar si el bit de trampa continúa activo; esto es, cuando se presente cualquier interrupción, el proceso es el siguiente:

1. Se introduce el registro de banderas a la pila. 2. Se introducen los registros CS e IP a la pila. 3. Se borran los bits de trampa e interrupción, del registro de banderas. 4. Se ejecuta el procedimiento de interrupción.

Por lo que la INT01H, verifica el registro de banderas almacenado en la pila, si el bit de trampa continua activo. Si el bit esta activo, indica que la INT01H entró después de una instrucción; si el bit esta inactivo, entonces la INT01H se activó en una interrupción por software o hardware. Para el primer caso, se permite que continué la ejecución de la INT01H. Pero en el segundo caso, hay que identificar que tipo de interrupción es. Para ver si la interrupción es por software o hardware, examinamos el registro

de interrupciones en servicio47; este registro informa que tipo de interrupción por hardware se esta ejecutando actualmente. Aun cuando al control se haya pasado a la INT01H, este registro informa que interrupción por hardware se esta atendiendo. Si algún bit de este registro está activo, entonces se esta atendiendo una interrupción por hardware; en caso contrario es de software. Cuando la interrupción es de software, no hace nada la INT01H y permite que termine la interrupción. Si la interrupción es de hardware, verifica el valor del registro IP; es decir, la INT01H revisa el valor del registro IP en el buffer de registros, y lo compara con el valor almacenado en la pila48. Si estos valores son iguales, no se ha ejecutado una instrucción, la INT01H termina y permite que se ejecute la interrupción por hardware; en otro caso, termina la interrupción por hardware y continúa con la ejecución del trazado, ver Fig. 3.5. 3.7.2 Interrupción 03H

Esta interrupción se le conoce como punto de ruptura, y es empleada para fijar un punto en donde se debe detener la ejecución. En el caso del Monitor y el programa D188.EXE, esto se debe realizar en forma manual; es decir, en el programa fuente el

47 Ver referencia [2], para un mejor detalle de este registro. 48 En este caso, en el buffer de registros el valor de IP corresponde a la siguiente instrucción, la que se debe ejecutar. En la pila se encuentra el valor del registro IP que introdujo la interrupción por hardware; si estos son iguales, indica que no se ha ejecutado la instrucción en cuestión.

Page 59: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

52

usuario debe decidir donde detener la ejecución, y en ese punto colocar la instrucción INT 03H. El procedimiento de la INT03H es muy semejante al de la INT01H, con la diferencia de que no se realiza ningún tipo de comprobación al inicio; la INT03H simplemente almacena el valor de los registros en el buffer, cambia el estado a DBG, envía el comando CMSPASO al D188.EXE, borra la bandera de trampa y cede el control al Monitor.

Figura 3.5 Proceso de la INT01H.

Page 60: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

53

Capitulo 4. El programa D188.EXE

4.1 Introducción El programa D188.EXE es la parte del sistema que el usuario puede observar; con este software, el usuario tiene la capacidad de escribir, crear y depurar programas que se ejecutarán en la tarjeta de experimentación UAMI188EB. El D188.EXE se divide en cuatro módulos, los cuales son: la interfaz visual, la interfaz de comunicación con la UAMI188EB, el ensamblador y el depurador. El primer módulo no forma parte propiamente del software, ya que las rutinas empleadas en la interfaz, fueron tomadas de bibliotecas que trae consigo el software de desarrollo, en este caso el lenguaje C++ de Borland5349, por lo que no extenderemos más allá el conocimiento de este módulo. Estas bibliotecas se les conoce con el nombre de Turbo Vision, y

pueden ser consultadas en [8] para un mejor detalle.

En este capítulo sólo examinaremos los dos primeros módulos, por lo que el resto será tema de un capitulo aparte, ya que son una pieza importante en todo el sistema para la tarjeta UAMI188EB. Finalmente, en el Apéndice D se muestra el nombre de todas las funciones y la localización de estas en los diversos archivos que comprenden el programa.

4.2 Estructura del programa D188.EXE El programa D188.EXE se ha diseñado de tal forma que cada uno de sus componentes represente un módulo; el objeto de esta configuración, es que cada módulo sea independiente de la interfaz, de esta forma el programa D188.EXE puede fácilmente transportarse a un ambiente tipo Windows50, ver Fig. 4.1. La función de cada componente o módulo del programa D188.EXE es la siguiente:

• Interfaz visual. Se encarga de presentar en pantalla la información generada por cada uno de los módulos; esto se logra a través de menús y ventanas, para los cuales proporciona las rutinas para su manejo.

• Interfaz de comunicaciones. Contiene todos los servicios que se encargan de enviar y recibir datos por medio del puerto serie.

49 El programa D188.EXE fue hecho en su totalidad con rutinas en lenguaje C y C++, este último principalmente para la interfaz visual. 50 Por ejemplo, se puede programar la interfaz en Visual Basic, y los módulos restantes se agregan como bibliotecas tipo DLL; sin embargo, la interfaz de comunicación deberá ser modificada para adecuarse a los requerimientos de Windows.

Page 61: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

54

• El ensamblador. Se encarga de traducir el programa fuente en lenguaje ensamblador a lenguaje maquina. Este componente sólo tiene comunicación con la interfaz visual, que básicamente es para presentar mensajes.

• El depurador. Contiene los procedimientos necesarios para la depuración de un programa; se relaciona con la interfaz de comunicación, ya que es capaz de enviar información a la UAMI188EB.

Figura 4.1 Estructura del programa D188.EXE. Los módulos encerrados en el cuadro de líneas

punteadas, son independientes de la interfaz, y entre ellos.

Según se observa en la Fig. 4.1, la interfaz visual tiene contacto en ambos sentidos con la de comunicación; es decir, la interfaz de comunicación recibe mensajes de la UAMI188EB vía una interrupción, la cual se encarga de almacenar en un buffer cada mensaje recibido, este buffer es monitoreado por una rutina propia de la interfaz visual, y se encarga de pasar el mensaje a su respectivo destinatario.

Page 62: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

55

4.3 La interfaz visual51 La función principal de este módulo, es la de presentar información en pantalla. Para ello, el módulo tiene comunicación con los demás por medio de pequeñas interfaces; sin embargo en algunos casos, se emplean servicios de la interfaz visual directamente. La interfaz se creó a partir de un conjunto de bibliotecas ya establecidas en el lenguaje C++, dichas bibliotecas forman parte del software de desarrollo de Borland en la versión 3.10 del C++ y se les conoce con el nombre de Turbo Vision. Turbo Vision52 son un conjunto de bibliotecas orientadas a objetos, que contienen las clases53 que proporcionan las funciones necesarias, para la creación de aplicaciones con ventanas. Con estas bibliotecas podemos crear una gran cantidad de objetos, que dan una mejor presentación a la aplicación, y que además la hacen muy intuitiva al usuario. Dentro de estos objetos destacan:

• Ventanas

• Botones

• Cuadros de diálogo

• Menús de ventana

• Barras de desplazamiento

• Manejo de ratón No son todos los objetos que se pueden emplear, ya que existen otros que pueden ser combinados con los anteriores para crear una mejor aplicación, por lo que se listan los más comunes. Dentro de una aplicación con TV, cooperan en una sociedad tres cosas:

• Las vistas (views), que son todos aquellos objetos que se pueden presentar en pantalla y que son los que nos interesan; por ejemplo un botón o una ventana.

• Los eventos, que son las “ocurrencias” o sucesos a las que la aplicación debe responder; por ejemplo el movimiento del ratón o la activación de una tecla.

• Los objetos “mudos” (mute objects), que son todos aquellos objetos que no están presentes en pantalla, pero que existen internamente en la aplicación.

51 Gan parte del material aquí presentado, fue tomado de [8]; por lo que sólo nos limitaremos a explicarlo con otro enfoque. 52 En adelante lo llamaremos TV. 53 Una clase es el esqueleto de un objeto; en tiempo de diseño, se tienen clase, en tiempo ejecución esas clases se convierten en objetos. Esto último se conoce como instanciación de la clase.

Page 63: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

56

4.3.1 Jerarquía y herencia entre clases

Dos de los aspectos fundamentales de la TV, es la jerarquía y la herencia entre clases, ver Fig. 4.2. La clase raíz de toda aplicación TV es la clase TObject; esta clase provee dos funciones54 importantes: destroy y shutDown. El objeto principal de estas funciones, es el asegurar la correcta destrucción de todos los objetos que se crean a lo largo de la ejecución de la aplicación.

Figura 4.2 Jerarquía y herencia entre las principales clases. La jerarquía se denota por el nivel de cada

clase; la herencia es indicada por la flecha, por ejemplo, TApplication hereda los miembros de TProgram.

Las clases derivadas a partir de TObject caen en dos tipos principalmente: las que son "visibles" y las que no; es decir, las clases visibles son todas aquellas que proporcionan las funciones necesarias para mostrar en pantalla los objetos, por ejemplo dibujar en pantalla una ventana o atender un evento de la misma. Las no visibles proporcionan algunas utilidades que no tienen que ver con el manejo de lo que se muestra en pantalla, aunque en algunas ocasiones proporcionan algunas funciones, pero no directamente; en otras palabras la clases no visibles se refiere a objetos no presentables en pantalla. Las clases visibles derivan de la clase TView, en donde esta permite crear objetos que serán dibujados en pantalla, algunas clases importantes se muestra en la Fig. 4.3. La importancia de TView, radica en que se encarga de informar al correspondiente objeto cuando debe dibujarse en pantalla55; es decir, TView le reserva

54 En realidad la palabra correcta es método, las clases contienen métodos, que definen el comportamiento de un objeto; sin embargo, nos referiremos a ellas también como funciones o funciones miembro. 55 Esto debido a que es posible tener en pantalla a múltiples objetos interactuando.

Page 64: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

57

al objeto un lugar en pantalla, y por medio del método virtual56 draw, el objeto podrá

presentarse en pantalla. La siguiente clase importante es TGroup, y proporciona las funciones para el manejo de cadenas de objetos. Cada objeto visible dentro de una aplicación en TV, es agrupado en una lista dinámica, la cual es de gran ayuda al navegar entre los objetos visibles, ya que es posible determinar el dueño de un objeto57 entre los objetos; sin embargo, es posible tener a los objetos fuera de este grupo, pero no recomendable.

Figura 4.3 Jerarquía y herencia de la clase TView.

Las últimas clases importantes son TProgram y TApplication. La primera clase, provee únicamente un conjunto de funciones virtuales para su clase derivada, TApplication. En cambio TApplication proporciona el punto de entrada de un programa en TV; la instanciación de esta clase es dueña del objeto menú (TMenuBar), el escritorio (TDesktop) y de la barra de estado (TStatusBar). La aplicación en este caso tiene su punto de partida con la función miembro Tapplication::run, la cual es heredada por la aplicación.

56 Los métodos virtuales son empleados fundamentalmente en la herencia entre clases; una clase puede cambiar el comportamiento de otra al emplear funciones virtuales. 57 Por ejemplo, en un cuadro de diálogo, una ventana puede ser propietaria de los objetos botón, línea de captura, etc. En este caso se dice que el objeto ventana es dueña del objeto botón.

Page 65: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

58

4.3.2 Estructura de una aplicación en Turbo Vision

Una aplicación en TV, es básicamente una clase la cual hereda las funciones miembro de TApplication; las funciones miembro de la clase de la aplicación son fundamentalmente, el constructor y una función virtual que maneja los eventos, la cual es heredada de TProgram. Así por ejemplo la clase de una sencilla aplicación en TV se ve como: Class MiAplicacion : public TApplication Virtual void handleEvent (TEvent &ObjetoEvento); //Manejador

static TMenuBar *ObjetoMenuBar (TRect); //Barra de menú static TStatusLine *ObjetoStatusLine (TRect); // Barra de estado

MiAplicacion () //Constructor TProgInit (&MiAplicacion::ObjetoStatusLine, //Ba rra de estado &MiAplicacion::ObjetoMenuBar, //menú &MiAplicacion::initDeskTop) //Escritor io

//Código de inicio de la aplicación

//Las demás funciones miembro //… ;

TMenuBar *MiAplicacion::ObjetoMenuBar (TRect r) //Se genera el menú de la aplicación r.b.y = r.a.y+1; return new TMenuBar(r, *new TSubMenu( "~A~rchivo", kbAltA ) + *new TMenuItem( "~S~alir", cmQuit, cmQuit, hcNoCo ntext, "Alt-S" ));

TStatusLine *MiAplicacion::ObjetoStatusLine (TRect r) //Se genera la barra de estado de la aplicación r.a.y = r.b.y-1; return new TStatusLine( r, *new TStatusDef( 0, 0xFFFF ) + *new TStatusItem( "~Alt-S~ Salir", kbAltS, cmQuit ) + *new TStatusItem( 0, kbF10, cmMenu ));

La clase de este pequeño programa, se encarga de iniciar una barra de menú y una barra de estado; observe que la función TProgInit (miembro de TProgram), permite colocar estos objetos con ayuda de las funciones ObjetoMenuBar y ObjetoStatusLine, que se pasan como argumento y que deben iniciar estos objetos. La función handleEvent, es una función miembro la cual recibe como argumento un objeto de tipo TEvent (un comando de menú, la activación de una tecla o el movimiento del ratón, son ejemplos de eventos), con este evento el objeto que lo

Page 66: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

59

recibe actuará o tendrá un determinado comportamiento58. La gran mayoría de los objetos visibles en TV contienen este método, con la finalidad de “hacer” algo ante un evento. En el caso del D188.EXE, la estructura es similar; sin embargo, a lo anterior habrá que agregarle dos funciones extra (además de algunos métodos que complementan el comportamiento), estas funciones se llaman idle y outofmemory, ambas funciones las hereda la aplicación de la clase TProgram. La primera función se ejecuta cada vez que la cola de eventos se encuentra vacía; el objetivo de esta función, es que el programa pueda realizar tareas en segundo plano, mientras espera que el usuario interactue con la aplicación. La función outofmemory es llamada cuando se detecta que existe muy poco espacio en memoria; con esta función, el programador puede definir la acción o el mensaje correspondiente. En el D188.EXE la función idle se encarga de activar/desactivar los comandos del menú, en función del estado de la tarjeta UAMI188EB. Además de esto, la función handleEvent de la clase principal de la aplicación, se encarga de monitorear el buffer de recepción del puerto serie (ver Sección 4.4.3), de esta forma el programa D188.EXE captura la información que es enviada por la UAMI188EB; además también se encarga de ejecutar los comandos provenientes del menú . Una estructura típica de la función handleEvent es el siguiente: void MiAplicacion::handleEvent(TEvent& psteEvent) TProgram::handleEvent(psteEvent); //Primero pro cesa la clase TProgram if(psteEvent.what!=evCommand) return; else switch(psteEvent.message.command) //Comando d el menu //Comandos ; clearEvent(psteEvent); //Elimina el vento

Observe que la variable pstEvent contiene el tipo de evento y su valor. La última función es de ayuda para indicar que el objeto que recibió el evento lo ha procesado, ya que de otra forma, ese evento podría ser procesado por otro objeto. 4.3.3 Los objetos visibles en Turbo Vision

Hasta el momento la aplicación sólo contiene un menú, una barra de estado y algunas funciones que manipulan algunos eventos; además de esto, dentro de TV existen clases que permiten crear objetos tales como ventanas, botones y cuadros de

58 Cada evento es almacenado en una cola de eventos, de esta forma, cuando ocurren simultáneamente varios eventos estos son almacenados en una lista.

Page 67: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

60

diálogo entre otros. Para crear una ventana, por ejemplo un cuadro de diálogo, se instancia una clase del tipo TDialog, en este caso la instrucción es la siguiente:

TDialog *pstdAux = new TDialog (TRect(9, 0, 70, 24) , "Dialogo");

La instrucción anterior crea una ventana con el titulo “Diálogo”, iniciando en la posición (9, 0)59 y terminando en la (70, 24). Si a esta ventana se le agrega un botón, se tiene:

pstdAux->insert(new TButton(TRect(9,21,21,23),"OK", cmOK, bfDefault));

Observe que en este caso el objeto botón es insertado al cuadro de diálogo; esta es la forma que toma la clase TGroup, al crear una lista de objetos para navegar entre ellos, y enviar los mensajes correspondientes que sucedan durante la ejecución del cuadro de diálogo. Finalmente, para mostrar el cuadro de diálogo se emplea la siguiente instrucción:

deskTop->execView (pstdAux);

En este caso, el objeto escritorio (deskTop) cede el control a la ventana de diálogo para su ejecución; TV manipula los cuadros de diálogo como si se trataran de pequeñas aplicaciones, pero es posible crear cuadros de diálogo propios; sin embargo, estos tendrán un comportamiento diferente a los cuadros de diálogo declarados ya en TV. En el caso de objetos más complejos, en los que se requiere que estos interactúen con los demás objetos de la aplicación, es necesario crear el objeto e insertarlo a lista de objetos (TGroup) del escritorio; por ejemplo, si se desea crear una ventana de edición, se tiene:

EDITWINDOW *pstewAux; //Se define el objeto ventan a de edición TRect r = deskTop->getExtent (); pstewAux = new EDITWINDOW (r, pcFileName, wnNoNumbe r); TView *p = validView(pstewAux); //Para ver si se c reo la ventana deskTop->insert (p); //Inserta la ventana al escri torio

La primer línea de código define el objeto ventana de edición a partir de la clase EDITWINDOW; la siguiente línea obtiene las dimensiones del escritorio y las almacenan en el objeto TRect, que básicamente define el tamaño de una ventana; la siguiente línea es la creación del objeto ventana de edición, en este caso se pasan como parámetros las dimensiones, el nombre del archivo (si es que existe) y un número de ventana (el cual no es necesario); la siguiente línea valida que el objeto se haya creado (si no creó el objeto, ejecuta la función outofmemory), de esta forma

59 El formato en pantalla es (COLUMNA, RENGLON).

Page 68: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

61

regresa el apuntador de la clase padre, en este caso TView; finalmente la ventana de

edición se inserta en el escritorio. La clase EDITWINDOW proporciona las funciones necesarias de un editor básico de archivos; esta función hereda los métodos de la clase TWindow, la cual proporciona el manejo de ventana, y los de la clase TView. El poder de la orientación a objetos radica en que es posible mejorar una clase y heredar las funciones de otras; así por ejemplo, si se desea cambiar la clase EDITWINDOW, es posible crear una clase con funciones nuevas, pero que se hereden algunas funciones de la clase padre EDITWINDOW.

4.4 La interfaz de comunicación Esta interfaz contiene diversos servicios para el envío y recepción de mensajes por medio del puerto serie. Los principales servicios que proporciona son:

• Activación, reinicio y desactivación del puerto serie.

• Manejo de la interrupción del puerto serie.

• Recepción de datos vía interrupción.

• Envío y recepción de datos.

Cada servicio involucra un conjunto de funciones que pueden ser empleadas en cualquier parte del programa; sin embargo, antes de emplear estas funciones se debe activar el puerto serie, ya que las funciones no verifican si el puerto se ha activado o no, esto puede llevar a resultados inesperados.

Además de los servicios antes mostrados, existen otros lo cuales se emplean

para informar el estado del puerto; por ejemplo, existen funciones para conocer si la interrupción del puerto serie esta activa, o funciones que cambian la velocidad del puerto; sin embargo, el objetivo principal de la interfaz de comunicación es proporcionar los servicios antes mencionados. 4.4.1 Activación, reinicio y desactivación del puerto serie

Este servicio es proporcionado principalmente por 3 funciones:

• vIniciaPuertoSerie

• vTerminaPuertoSerie

La primera función, la cual se debe emplear antes de cualquier otro servicio de la interfaz de comunicación, se encarga de activar y configurar el puerto serie. Esta función recibe como parámetros: el puerto, número de bits, bits de parada, paridad y velocidad del puerto. Además también se encarga de configurar la interrupción del

Page 69: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

62

puerto serie, la cual depende del puerto seleccionado; así para el COM1 la interrupción es la 04H60, y para el COM2 la interrupción es la 03H. Para configurar la interrupción, sólo hace uso de los registros del controlador de puerto serie; esto quiere decir, que en ningún momento se ha activado la interrupción, ya para esto se debe modificar los registros del controlador de interrupciones61. Además de lo anterior, modifica el vector de interrupción correspondiente; este vector se calcula con el número de interrupción asignado más 08H, el procedimiento de atención es viInterrupcionPtoSerie y sólo función en la

recepción de datos. Estrictamente no existe una función que reinicie el puerto serie; para lograr esto, se debe “cerrar” el puerto con ayuda de la función vTerminaPuertoSerie y reiniciarlo nuevamente con la función vIniciaPuertoSerie. 4.4.2 Manejo de la interrupción del puerto serie

Una vez que se ha iniciado el puerto serie, se han establecido los valores apropiados en los registros de control del 16550A, y se ha colocado el procedimiento de atención de interrupción en el vector apropiado, corresponde a la función vInterrupcionPtoSerie habilitar o deshabilitar la interrupción. Esta función modifica los registros en el 8259 y en el 16550A para activar o desactivar la interrupción del puerto serie; en el 8259 desenmascara el bit correspondiente a la interrupción seleccionada por el puerto, mientras que en 16550A, modifica el bit OUT2 del registro MCR. Existe además, una función que se encarga de informar el estado de la interrupción; esta función se llama vEstadoInterrupcion, e indica si la interrupción esta activa o no. 4.4.3 Recepción de datos vía interrupción

Cuando la interrupción esta activa, y el puerto serie ha recibido un dato, se dispara una interrupción por hardware que llama al procedimiento vInterrupcionPtoSerie; esta función únicamente recibe el dato y lo almacena en un

60 El número de interrupción para los puertos, no corresponde al del vector de interrupciones normal, ya que es el número de interrupción por hardware; para mapear esta interrupción se debe sumar 08H. Así entonces, para el COM1 la interrupción es 0CH; si se emplea la instrucción INT 0CH, se llamara al procedimiento de interrupción del COM1. 61 En este caso el 8259 para el controlador de interrupciones, y para el puerto serie se tienen dos chips principales con características similares, el 16450 y el 16550A/D para modelos de PC más reciente; este último es el que tomaremos de base, consultar [15].

Page 70: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

63

buffer (básicamente una cola), para su posterior proceso. El buffer de almacenamiento se llama sBCola, y tiene una capacidad de 64 bytes. Para manipular el buffer, existen una serie de funciones, estas son: bObtenDatoCola. Retorna el valor que hay en el buffer. bColaLlena. Indica si la cola esta llena o no. bColaVacia. Indica si la cola está vacía. bLimpiaCola. Elimina todos los elementos del buffer.

La función más importante es bObtenDatoCola, ya que es la función que emplea la interfaz visual (DUAMI188::handleEvent) para monitorear los datos que envía la UAMI188EB. Estrictamente, sólo se reciben comandos de la UAMI188EB por medio de la interrupción, ya que para entablar comunicación con la UAMI188EB, se emplea el servicio de envío y recepción de datos; debido a esto, es necesario desactivar el servicio de interrupción del puerto serie. 4.4.4 Envío y recepción de datos

Estos servicios se emplean para la transferencia de información entre el D188.EXE y la UAMI188EB; básicamente son dos funciones:

• bEnviaDato

• bRecibeDato

La primera función se encarga de enviar un byte por el puerto serie, e informar si se tuvo éxito. La segunda función recibe el dato capturado en el puerto serie, pero es necesario deshabilitar la interrupción, ya que de otro modo el dato enviado será capturado por el servicio de interrupción. Estas funciones son empleadas por la interfaz visual para envío y recepción, su uso depende en gran medida de la sincronización que existe entre el D188.EXE y la UAMI188EB. Cada comando62 que requiere transmitir o recibir un dato, emplea las funciones anteriores y lo realiza siguiendo un protocolo:

1. Se desactiva la interrupción del puerto serie en el D188.EXE 2. El D188.EXE envía el comando correspondiente a la UAMI188EB. 3. La UAMI188EB recibe el comando y envía el comando cmsOK. Si el comando

enviado requiere el envío de datos, la UAMI188EB queda en espera de estos.

62 Los comandos se listan en el Capitulo 3, Secciones 3.4 y 3.5

Page 71: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

64

4. Cuando el programa D188.EXE recibe el comando cmsOK, envía los datos; los

primeros bytes indican el tamaño de la información que será enviada, o en todo caso, envía la información; después se envía cada byte de información.

5. Cuando el D188.EXE ha terminado de enviar la información, la UAMI188EB puede emitir el comando cmsOK, de esta forma el D188.EXE determina que la UAMI188EB ha recibido toda la información.

6. La UAMI188EB realiza la función correspondiente, y el programa D188.EXE activa las interrupciones del puerto serie, para continuar con su ejecución normal.

El todos los pasos, cuando ambos programas esperan respuesta del otro, lo hacen fijando un cierto tiempo; si este tiempo se cumple abortan la transmisión.

Page 72: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

65

Capitulo 5. El ensamblador de la UAMI188EB

5.1 Introducción El programa D188.EXE tiene integrado un ensamblador, el cual traduce instrucciones en lenguaje ensamblador a lenguaje máquina; este último consiste de cadenas 1’s y 0’s que representan operaciones que el microprocesador puede realizar. Por su parte, el lenguaje ensamblador es una variante del lenguaje máquina, pero que el ser humano puede fácilmente interpretar, ya que son nemónicos del nombre de la instrucción en ingles. A grandes rasgos, el lenguaje máquina se compone de lo siguiente:

Prefijo Instrucción Argumento(s)

En donde el prefijo generalmente se compone de 1 byte, la instrucción y los

argumentos se pueden componer desde 2 bytes hasta 8 bytes. El prefijo es un modificador de instrucción que sólo se aplica en algunas; en general, este prefijo indica cuantas veces se debe ejecutar la instrucción. En el caso de los argumentos, estos pueden ser: un registro, un número, algún tipo de direccionamiento63 o la combinación de los anteriores, aunque claro, con ciertas reglas.

El objeto del lenguaje ensamblador, es que el usuario en lugar de trabajar con

bytes, emplee palabras que fácilmente puede recordar y manipular. Por su cercanía con el lenguaje máquina, el lenguaje ensamblador se dice que es de bajo nivel; existen otros lenguajes (por ejemplo el lenguaje C), los cuales tienen una estructura más compleja, pero que son aun más fáciles de manejar por su cercanía con el lenguaje del ser humano; estos lenguajes se les denomina de alto nivel.

El lenguaje ensamblador presenta algunas desventajas, comparado con un

lenguaje de alto nivel; por ejemplo, los programas pueden resultar extensos, e interpretar un programa en ensamblador puede no resultar una tarea fácil. Sin embargo, existen algunas ventajas, ya que es posible escribir rutinas optimizadas, y resulta fácil hacer programas en los que intervengan los puertos de entrada salida.

Cada microprocesador de Intel tiene asociado un conjunto de instrucciones

válido; sin embargo, el conjunto de cada nuevo microprocesador únicamente ha ido creciendo, lo que permite que procesadores más recientes puedan ejecutar instrucciones de procesadores anteriores. En el caso del ensamblador del D188.EXE,

63 Por direccionamiento se debe entender que lo que se define como argumento es la dirección en donde se encuentra el valor a usar.

Page 73: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

66

el conjunto de instrucciones por default es para el microprocesador 8086/808864, pero puede ser modificable, vía una instrucción65 para que el conjunto de instrucciones aumente, y se acepten instrucciones del 80186/80188.

5.2 Estructura y funcionamiento del ensamblador El ensamblador dentro del software D188.EXE se divide en 2 bloques:

• El convertidor de línea, proporcionado por la función wASM2MAQ, en COD2MAQ.CPP.

• Un ensamblador de código, dado por la función vCompilaArchivo, en

COMPILAE.CPP. El primer bloque es una parte esencial del ensamblador y del depurador, ya que se encarga de traducir cada instrucción en ensamblador a su correspondiente en lenguaje máquina. El siguiente bloque proporciona el soporte necesario para construir el programa, ya que se encarga de resolver las referencias66 de las etiquetas que están definidas en el código fuente. En un sentido estricto, el primer bloque esta contenido en el segundo, y ello se debe a que se tienen que resolver las referencias que hay en el código fuente de un programa en ensamblador. El ensamblador requiere de dos pasos para construir un programa, en ambos pasos se realiza el mismo procedimiento, pero la diferencia es que en el primer paso se resuelven todas las referencias que se emplean en el programa67. Por ejemplo, se tiene el siguiente código fuente en ensamblador:

MOV AX, 100H ;AX es un contador XOR BX, BX ;BX = 0 SALTA: ;Una etiqueta, hace la función de un ciclo. MOV [BX], AX ;A partir de la dirección 0H, se almac enan los INC BX ;valores que toma AX. DEC AX ;Se decrementa AX. JNZ SALTA ;Si AX = 0, el ciclo termina.

El primer paso es definir un offset, el cual es la dirección a partir de donde inicia el código máquina, en este ejemplo es igual a 0000H. Con el offset definido, el ensamblador examinara línea a línea, traduciendo cada una de estas en código máquina, como se muestra en la Tabla 5.1; esta es la función del primer bloque, que además proporciona el tamaño del código resultante. Con este tamaño, es posible

64 En términos estrictos, existe una diferencia (aunque pequeña) entre el conjunto de instrucciones del 8086 y el del 8088; en el caso del ensamblador, se omite esta diferencia y el código que manipula es para el 8088, permitiendo compatibilidad con el 8086. 65 Ver Apéndice A, Sección A.4.1. 66 Una referencia es la dirección o el offset de una etiqueta, el nombre de un procedimiento o una variable. 67 El problema se debe a que los saltos se calculan en base al número de bytes que debe saltar, no a una dirección.

Page 74: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

67

determinar el offset de la siguiente instrucción, el cual es controlado por el segundo bloque.

Pasos Código Acción del ensamblador Offset

1 MOV AX, 100H Traduce a B80001H 0000H

2 XOR BX, BX Traduce a 33DBH 0003H

3 SALTA: Inserta en una lista el salto y su offset. 0005H

4 MOV [BX], AX Traduce a 8907H 0005H

5 INC BX Traduce a 43H 0007H

6 DEC AX Traduce a 48H 0008H

7 JNZ SALTA Busca en la lista el salto, y coloca el offset. Traduce a 75FAH

0009H

8 - No hay más líneas, genera archivo. Tabla 5.1 Proceso de ensamblado en un solo paso.

En este caso, se requirió de un sólo paso para crear el archivo; conforme el segundo módulo recibe el código máquina, va almacenándolos en memoria, para después generar el archivo de salida; sin embargo, observe lo que sucede con el siguiente código:

CMP AX, 10H ;Se compara el valor de AX JE SALTA ;Si es igual a 10H salta, de otra forma c ontinua. MOV AX, 10H ;No es igual a 10H, entonces asignamos el valor 10H a AX. SALTA: ;Etiqueta de salto, continua con el resto de la ejecución.

En este caso, el ensamblador realizara el mismo proceso anterior, pero no podrá determinar el salto, ya que este aun no esta definido, no se ha introducido a la lista. Entonces con un sólo paso, el ensamblador no determinará el valor del salto y no podrá compilar el archivo; de ahí la necesidad de realizar un segundo paso. Entonces, en el primer paso el ensamblador realizara lo siguiente:

Pasos Código Acción del ensamblador (en hexadecimal) Offset

1 CMP AX, 10H Traduce a 3D1000H 0000H

2 JE SALTA No reconoce la palabra SALTA, almacena la instrucción y no cambia el offset.

0003H

3 MOV AX, 10H Traduce a B81000H 0003H

4 SALTA: Almacena el salto en la lista y su posible offset. 0005H

8 - No hay más líneas. Busca en la lista las instrucciones no traducidas, en este caso 1. Calcula el offset real del salto (la referencia), y regresa al paso 1. De esta forma, ya es posible generar el archivo en una segunda pasada al código.

Tabla 5.2 Proceso de ensamblado en dos pasos.

Page 75: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

68

El proceso de cálculo de referencia es un poco más complicado, y lo detallaremos en una sección posterior. 5.2.1 Listas de instrucción, de constantes y etiquetas

Existen cuatro elementos básicos en el lenguaje ensamblador del D188.EXE; estos son:

• Etiquetas: Las etiquetas hacen referencia a un offset, en donde se encuentra la siguiente instrucción posible a ejecutar. Se identifican por un número que indica una dirección en memoria.

• Constantes. Expresan un valor fijo durante el proceso de compilación; en lugar de trabajar con números, se asigna un “nombre” a ese número, de esta forma cuando hay necesidad de cambiarlo, simplemente se sustituye el valor en la constante, así ya no es necesario buscar en donde deben realizarse los cambios cuando se trabaja con números. En cualquier lugar del código es posible declarar una constante, ya sea que esta se use antes o después.

• Variables. Estrictamente no existen variables, en su lugar son las etiquetas, que hacen referencia a una dirección de memoria; en general el ensamblador no hace distinción entre etiqueta, variable o nombre de procedimiento, el programador es quien debe asignarle el contexto apropiado, ver Tabla 5.3.

• Nombres de procedimiento. Tienen el mismo significado que una etiqueta.

Código 1 Código 2 Código 3 MOV AX, SALTO ... SALTO: ...

VARIABLE: DB “HOLA” ... CALL VARIABLE ...

MOV DX, MIPROC ... MIPROC PROC ... ENDP

Tabla 5.3 Los tres códigos son correctos, el programador debe asegurarse de manejarlos adecuadamente, ya que los tres hacen referencia a direcciones de memoria.

Para manejar lo anterior, el ensamblador maneja dos tipos de listas dinámicas simplemente ligadas, estas son:

• Lista de instrucciones (LI). En esta lista se almacena la instrucción, el número de bytes de la instrucción, el offset, el número de línea en el archivo fuente y un contador. Basta con agregar una instrucción a la lista, para que todas las referencias ya no sean determinadas.

• Lista de constantes y etiquetas68 (LCE). En esta lista se almacenan constantes y etiquetas; los valores son: el nombre, el offset, el tipo (constante o etiqueta), y un contador.

68 Como las variables y los nombres de procedimiento son etiquetas, ya no se hará distinción alguna.

Page 76: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

69

En la primer lista se almacena la instrucción que no se pudo traducir a lenguaje máquina; el motivo principal de esto, es que la instrucción contiene una palabra no reconocida, que puede ser una etiqueta o una constante no declarada aún; sin embargo, si el proceso de compilación esta en la segunda pasada, entonces si se genera un error, ya que en el primer paso se supone se resolvieron todas las referencias. La siguiente lista, contiene las etiquetas o constantes que se encontraron durante el primer paso; de esta forma, cuando se ejecute el segundo paso, el ensamblador encontrara las direcciones de estas etiquetas, o en su caso el valor de la constante. Observe que el primer paso realiza una compilación mapeada en direcciones de memoria; es decir, determina la estructura del código en memoria, para en el segundo paso ensamblar con el mapa de memoria del programa. El ensamblador es capaz de generar este mapa en un archivo, aquí se indica el offset de cada etiqueta. El contador determina la aparición de la constante, etiqueta o instrucción en el código fuente; esta es un variable importante, ya que determina el orden de aparición y así calcular la referencia.

5.3 El convertidor de línea En la sección anterior, se ha dado un bosquejo de la función de este convertidor, la cual es básicamente traducir de ensamblador a código máquina. La función que realiza esto es:

word wASM2MAQ (char *pcText, byte *pbCod, word *pwR ef, word wLin);

En donde pcText es la instrucción en ensamblador; pbCod es el código máquina

de retorno; pwRef es el offset de la instrucción, el cual es actualizado dependiendo del tamaño de la instrucción; y finalmente wLin, el cual contiene el número de línea de la instrucción en el archivo, que es de ayuda para determinar donde ocurre un error. Esta función retorna un entero (2 bytes) mayor a cero en caso de error, con la siguiente estructura69:

69 En general, todas las funciones relacionadas con el proceso de compilación, manejan la misma estructura de error; así si una función llama a otra y esta última genera un error, la función que llama detectara el error (ya que el entero es diferente de cero), suspenderá su ejecución y retornara el error a la función que esta llamó. Todo esto ocurre en cadena.

Page 77: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

70

2 bytes

15 0

Línea en el archivo fuente donde ocurrió el suceso

Tipo

Tipo define la clase de mensaje y el número, que este caso pueden haber hasta

255 mensajes; las clases son las siguientes:

• Mensaje. Informa al usuario de algún suceso. En este caso se modifican los 8 bits más significativos, ya que puede no representar la línea donde ocurrió el suceso; en su lugar se coloca la siguiente estructura:

1 byte

8 0

Código de impresión Valor

Los códigos de impresión son tres: 0 - Trata a Valor como un número de línea; 1 - Elimina Valor e imprime simplemente el mensaje; 2 - Imprime Valor y luego el mensaje y 3 - Imprime el mensaje y luego Valor.

• Warning (precauciones). La instrucción es válida, pero puede ocasionar un comportamiento no deseado al momento de ejecutar; aun así se genera el programa.

• Errores. La instrucción a traducir no es válida. Se detiene la generación del programa, pero la compilación continua.

Cada clase de mensaje se diferencia por el Tipo; así por ejemplo, si Tipo esta entre 0 y 49, se asume que es un error, si es mayor a 52 se asume que se trata de un mensaje. Estos valores se pueden controlar por las constantes ERR_LSTERR y ERR_LSTWAR en el archivo DEFINE.H; de esta forma hay posibilidad de agregar más mensajes. Cada uno de los mensajes generados por wASMMAQ, son almacenados en una lista para su posterior presentación; debido a que el ensamblador es de dos pasos, sólo toma en cuenta los errores en la segunda pasada. Una vez que entra una instrucción a la función wASMMAQ, los pasos que sigue para traducirla a ensamblador son los siguientes:

1. Determina la longitud de la cadena, ya sea que esta termine con un salto de línea o por un comentario (los comentarios inician con “;”). La función encargada de esto es wm_LenCad en el archivo STRFUN.CPP.

2. Separa la cadena por sus elementos los cuales son llamados tokens, con ello genera una lista.

Page 78: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

71

3. Si el ensamblador detecta una palabra que no reconoce, la toma como una etiqueta o constante y agrega la instrucción a la LI; esto claro, si se encuentra en el primer paso, ya que de otra forma hay un error.

4. Si la cadena no es una instrucción, sino una etiqueta, una constante o un procedimiento, la agrega a la LCE; esta lista será útil al calcular las referencias.

5. Finalmente si se trata de una instrucción, ejecuta la función correspondiente para traducir la instrucción, y después regresar el código y terminar.

6. Al terminar, calcula el offset donde se localizara la siguiente instrucción, para ello toma en cuenta el número de bytes generados de la instrucción actual.

5.3.1 Separación en tokens

Cada elemento de la cadena, una palabra o un operador, es lo que se denomina un token. Cada token tiene asociado un número que lo identifica; y además, un índice que identifica al elemento dentro de un conjunto de tokens. La Tabla 5.4 muestra una lista de los identificadores de token.

Identificador (Valor) Descripción

ID_REG16 (1) Registro de 16 bit, sin incluir a los de dirección.

ID_REGDIR (2) Registro de 16 bits, empleado en direccionamiento: BX, Si, DI, BP.

ID_REG08 (3) Registro de 8 bits.

ID_SEG (4) Registro de segmento

ID_INOARG (5) Instrucción sin argumentos.

ID_IUNARG (6) Instrucción de un argumento.

ID_IDOSARG (7) Instrucción de dos argumentos.

ID_IESP (8) Instrucciones especiales.

ID_NUMERO (9) Numero.

ID_OPERADOR (10) Operador, los cuales son: “+”, “,”, “-“, “[“, “]”y “:”. Se les denomina operadores, porque pueden formar parte de una instrucción.

ID_REG32 (11) Registro de 32 bit70.

ID_RESWORD (12) Palabras reservadas71. Tabla 5.4 Identificadores.

70 Aunque los procesadores 8088/80188 no aceptan registros de 32 bits, el ensamblador puede manejar esta posibilidad para futuras versiones. 71 En general, las instrucciones y los registros son palabras reservadas, pero las que aquí se manejan son propias del ensamblador del programa D188.EXE y no pertenecen al lenguaje ensamblador.

Page 79: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

72

Como se observa en la Tabla 5.4, se hace una clasificación entre las instrucciones. Esta clasificación se formula tomando en cuenta el número de argumentos que estas pueden aceptar; así por ejemplo, instrucciones sin argumentos son STI, CLD, etc.; instrucciones de un argumento son INC, DEC, etc.; e instrucciones de dos argumentos son MOV, ADD, etc. Finalmente se tienen instrucciones especiales, estas son los prefijos de una instrucción o el conjunto de instrucciones de cadena; como ejemplo se tiene a REP, REPE, SCASB, MOVB, etc.

La función wObtenTokens en STRFUN.CPP, se encarga de la separación,

regresando una la lista de tokens, o otro caso un error. Por ejemplo, se tiene la siguiente instrucción: MOV AX, [BX+SI+10H]

Al separar cada elemento se tiene (cada columna es un elemento de la lista simplemente ligada):

7 1 10 10 2 10 2 10 9 10 MOV AX , [ BX + SI + 10H ]

8 0 0 91 3 43 6 43 0 93

El número en la parte superior, corresponde al identificador que se asigna a cada token, ver Tabla 5.4. El número en la parte inferior es el índice de elemento en el token. El asignar un identificador a cada token, asegura un mejor manejo de la instrucción, de esta forma no se trabaja con la instrucción en si, sino con la representación que ofrece cada identificador. Así entonces, la instrucción MOV tiene asociado el identificador de token 7 (instrucciones de dos argumentos), y de índice 8 el cual enumera a todas las instrucciones de dos argumentos; con estos dos números es posible identificar a MOV de otras instrucciones. El índice del identificador, se obtiene de una lista en donde se encuentran todas las instrucciones, registros y palabras reservadas, ver archivo ASM2MAQ.H72. Para los operadores, el índice corresponde al su código ASCII y para los números, el identificador es: 0 – Números de 8 bits, 1 – Números de 16 bits y 2 – Números de 32 bits. En el caso de que un token no es reconocido; es decir, no es posible asignar un identificador, en el primer paso pueden ocurrir dos situaciones:

1. Revisa que el token desconocido se encuentre en la LCE; de no ser así, se agrega la instrucción en la LI.

72 Debido al tamaño de estas listas, no serán presentadas en el documento, pero puede consultar el archivo en el Apéndice F.

Page 80: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

73

2. Si no reconoce el token, pero esta instrucción lo declara (es una constante o una etiqueta), agrega el token a la LCE.

Para el segundo paso lo anterior no ocurre, en ese caso se detecta un error y este es retornado. Debido a la naturaleza del lenguaje ensamblador, en la lista de tokens, el primer elemento siempre es alguno de los siguientes:

• Instrucción sin argumentos.

• Instrucción de un argumento.

• Instrucción de dos argumentos.

• Instrucción especial.

• Palabra reservada.

• Etiqueta o constante. El primer token da la pauta para traducir la instrucción a lenguaje máquina; si el token no pertenece a la lista anterior, existe un error. Con este token, seleccionamos que función debe analizar la lista de tokens. 5.3.2 Instrucciones sin argumentos

En este caso el primer token tiene como identificador ID_INOARG, y el índice dependerá de la instrucción; así por ejemplo, en la siguiente instrucción: STI

El identificador es 5 y el índice es 26. Para traducir esta instrucción, el ensamblador simplemente toma el índice y lo emplea para buscar el código en una tabla, llamada sBCodIntNoArgs; el primer elemento es el índice, y los siguiente bytes son el código máquina; así entonces el código en la lista con índice 26 será: FBH. El ensamblador en este caso, espera sólo un token, ya que de otra forma habrá un error. 5.3.3 Análisis de argumentos

Cuando se trata de instrucciones de uno o dos argumentos, estos deben analizarse individualmente (una “,” separa dos argumentos) para ver si son correctos; para ello se emplea un autómata. Si el argumento es un registro, no es necesario el análisis; pero si el argumento es un tipo de direccionamiento, es necesario hacerlo y para ello se emplea la siguiente matriz de adyacencias.

Page 81: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

74

ID_OPERADOR

ID_NUMERO

ID_REGDIR 91 ([) 43 (+) 45 (-) 93 (])

ID_NUMERO/ ID_REGDIR

-1 -1 -1 1 2 -2

ID_OPERADOR 91/43

0 0 -1 -1 -1 -1

ID_OPERADOR 45

0 -1 -1 -1 -1 -1

Matriz de adyacencias.

El autómata funciona de la siguiente manera:

1. Inicia en el estado 1 (renglón), el cual es forzosamente el operador paréntesis “[“. Si se trata de otro operador, hay un error.

2. Se revisa el siguiente elemento de la lista y si concuerda con alguna de las columnas de la matriz, se determina la posición renglón-columna; el contenido en esta posición será el nuevo estado.

3. Si el nuevo estado es –1 hay un error, si es –2 se termina el análisis, ya que es correcto.

4. Si hay más elementos se obtiene y se va al paso 2. El análisis de argumentos es una tarea fácil. Por ejemplo analicemos el siguiente argumento: [BX+SI+10]

Token Estado Columna

(siguiente elemento)

[ 1 1

BX 0 3

+ 1 1

SI 0 3

+ 1 0

10 0 5

] -2 - Tabla 5.5 Análisis de

argumentos.

El primer elemento es un “[“, por lo que el estado es 1. El siguiente elemento es BX, entonces la columna es 1 y el nuevo estado será 0, ver Tabla 5.5. En el segundo renglón, se observa que el estado es 0 y la columna será 3, debido a que el siguiente elemento es “+”, el cual corresponde a la tercera columna en la matriz de adyacencias; por lo que el estado es ahora 0, en el tercer renglón. El proceso continúa, hasta el último token, que en este caso tiene como estado –2, indicando que el argumento es válido.

Durante el análisis de un argumento de direccionamiento, por cada uno de ellos se llenan los bits del siguiente byte, llamado FLAGDIR:

Page 82: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

75

7 6 5 4 3 2 1 0

BX BP SI DI N8 N16 Signo N32

Los cuatro bits más significativos corresponden a los registros que aparecen en un argumento; N8, N16 y N32 indican que el argumento tiene un número (el desplazamiento) de 8, 16 o 32 bits; y finalmente un signo, que en el direccionamiento podemos sumar o restar un número, si es 1 el número se resta. En el ejemplo anterior, los bits del byte anterior son: 10101000b73. El byte anterior se emplea en el direccionamiento; pero en forma más general, hay una doble palabra (2 bytes) que describe totalmente a cualquier tipo de argumento, llamado IDARG; esta doble palabra se compone de:

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

- - - Im32 M32 R32 PRE FAR SEG P Im16 Im8 M16 M8 R16 R8

El significado de cada bit es el siguiente:

• ImXX. Indica que el argumento es un número de 8, 16 o 32 bits.

• MXX. El argumento es una dirección a memoria de 8, 16 o 32 bits, y que por lo tanto existe el byte FLAGDIR.

• PRE. En el direccionamiento se empleo la palabra BYTE PTR o WORD PTR.

• FAR. Se empleo el prefijo FAR en un salto, por ejemplo CALL FAR [BX].

• SEG. El argumento es un registro de segmento. • P. El argumento es una dirección del tipo SEGMENTO:OFFSET.

• RXX. Es un registro de 8, 16 o 32 bits. Así entonces, para la siguiente instrucción: MOV WORD PTR [BX+10], 100H

Tendrá para cada argumento lo siguiente:

Argumentos IDARG FLAGDIR

[BX+10] 0000001000001000b 10001000b

100H 0000000000100000b 00000000b

73 Los números terminados en “b”, indican que el número esta en binario; para no confundir con un número en hexadecimal, estos terminaran con “H” y se escribirán en mayúsculas.

Page 83: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

76

5.3.4 Notación de los argumentos en código máquina

En general, una instrucción se puede componer de 1 a 8 bytes; los primeros 2 bytes identifican el tipo de instrucción, por ejemplo la instrucción INC tiene los siguientes códigos que son de 1 byte: 40H, FEH y FFH; estos códigos se establecen en función del argumento que tenga la instrucción. El siguiente byte identifica al (o los) argumento(s), se conoce como MOD R/M,

y tiene la siguiente estructura:

7 6 5 4 3 2 1 0

Mod Reg R/M

• Mod determina si el direccionamiento es a memoria o a registro: los valores son:

Valor Función

00b Direccionamiento exacto, no hay desplazamiento.

01b Hay un byte de desplazamiento.

10b Existen dos bytes de desplazamiento.

11b Operación entre registros. Tabla 5.6 Valores en el campo Mod.

• Reg determina el registro a emplear, que puede ser de 8 bits o 16 bits. Los registros se numeran como:

Reg Registro 8 bits Registro 16 bits Reg Registro de segmento

000b AL AX 000b ES

001b CL CX 001b CS

010b DL DX 010b SS

011b BL BX 011b DS

100b AH SP

101b CH BP

110b DH SI

111b BH DI Tabla 5.7 Valores en el campo Reg, según el registro.

• R/M (registro/memoria), determina el otro argumento que en este caso puede ser otro registro o un direccionamiento a memoria. Si es a registro, se emplea la Tabla 5.7, de otra forma se emplea la siguiente tabla.

Page 84: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

77

R/M Argumento

000b [BX+SI]

001b [BX+DI]

010b [BP+SI]

011b [BP+DI]

100b [SI]

101b [DI]

110b [BP]

111b [BX] Tabla 5.8 Valores en el campo R/M por direccionamiento a memoria.

Por último, los siguientes bytes son el desplazamiento o el número que también puede ser un argumento. Por ejemplo, suponga las siguientes instrucciones: MOV [BX+SI+1000H], AX ;El desplazamiento es de 100 0H MOV AX, [BX+SI+1000H] ;Hay un desplazamiento de 10 00H

En este caso ambos tendrán el mismo byte MOD R/M; el cual es: 800010H = 10 000 000 0000 0000 0001 0000b El byte MOD /RM, se encuentra subrayado y separado en sus componentes: 10b ya que existen 2 bytes de desplazamiento (1000H); 000b debido a que se trata del registro AX; y finalmente 000b, ya que se trata de [BX + SI] (ver Tabla 5.8). Los últimos 2 bytes reflejan el desplazamiento, pero en este caso, se invierten los bytes; resultando el mas significativo ahora el menos significativo, y menos significativo ahora el más significativo. Sin embargo, lo que hace la diferencia es el código de instrucción, ya que en el primer el código, para la instrucción MOV es 89H, y en el segundo es 8BH; finalmente las instrucciones quedan de la siguiente manera:

MOV [BX+SI+1000H], AX -> 89800010H MOV AX, [BX+SI+1000H] -> 8B800010H

En este caso, la variable FLAGDIR hace un mapeo hacia la los valores de la Tabla 5.8. Esta es la forma en que se identifica un argumento de este tipo; sin embargo, FLAGDIR contiene más información, pero esta sólo sirve de control para generar el código máquina.

Page 85: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

78

Cuando el argumento no es un direccionamiento a memoria, la variable FLAGDIR tiene el valor de cero; en ese caso, la variable IDARG mapea hacia los valores de la Tabla 5.7; y de igual forma, esta variable contiene más información que sirve para generar el código fuente. 5.3.5 Instrucciones de un argumento

Al igual que en el caso anterior el ensamblador emplea el índice, pero no para acceder a una lista de código, sino a una lista de vectores, llamada sBDesIntUnArg. Esta lista es necesaria ya que cada renglón accedido por un índice, apunta a un descriptor74 que contiene las diferentes opciones que puede tener una instrucción de un argumento. Por ejemplo, tomemos la siguiente instrucción: CALL [BX]

La lista de tokens será entonces:

Instrucción CALL [ BX ]

Identificador 6 10 2 10

Indice 0 91 3 93

El primer token indica que se trata de una instrucción de un sólo argumento, los demás tokens describen este argumento. El argumento es analizado y de este se obtienen las siguientes variables:

IDARG75 = 0000000000001000b FLAGDIR = 10000000b Con el índice, obtenemos el vector que punta al descriptor, en este caso el

vector es 0 y se inicia la búsqueda en el descriptor llamado sBCodIntUnArg; los datos del descriptor son los siguientes (cada columna de un byte):

• Número de bytes por instrucción.

• El código máquina (que depende del anterior, por default son 2 bytes). • Constructor del byte MOD R/M.

• Comparador (2 bytes).

• Byte auxiliar del comparador.

74 Todos los descriptores de las instrucciones con más de un argumento y las tablas de código, se encuentran en el archivo CODINST.H. 75 Si no se especifica el tamaño de la dirección con BYTE PTR o WORD PTR, se asume que la dirección apunta a 16 bits.

Page 86: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

79

• Tipo de procesador válido para la instrucción76.

Dentro del constructor del MOD R/M, se tienen banderas de control las cuales son:

Bit Descripción

7 Si el argumento es un número se trata como una dirección, sólo se emplea en instrucciones del tipo JXX o CALL (RM_D).

6 Los registros se suman al código (RM_S).

5

4

3

Define los bits R/M del byte MOD /R/M, ya que sólo hay un argumento.

2 Se emplea el auxiliar del comparador (RM_B).

1 Se hace la comparación entre la variable IDARG y el comparador con un AND

(RM_A).

0 No existen bits R/M; se construyen a partir del argumento (RM_N). Tabla 5.9 Bits del constructor del byte MOD R/M. Las palabras entre paréntesis, corresponden a

constantes que activan los bits, están definidas en el archivo DEFINE.H

La variable IDARG es empleada por el comparador, de hecho realiza la comparación directa con un “igual”, o emplea la instrucción AND. La variable FLAGDIR ayuda a generar el MOD R/M. Entonces, en el ejemplo de la instrucción CALL [BX] se tienen los siguientes valores en el descriptor.

01H, E8H, 00H, RM_D|RM_N|RM_A, LCOD_NUMH16, HCOD_NU MH16, 00H, COD_P86, 01H, 9AH, 00H, RM_N, COD_PUNTERO, 00H, 00H, CO D_P86, 01H, FFH, 00H, RM_3, LCOD_FAR, HCOD_FAR, 00H, COD_P86, 01H, FFH, 00H, RM_2|RM_A, COD_rm16, 00H, 00H, COD_P 86,

En este caso, los comparadores son los siguientes77:

• LCOD_NUMH16 y HCOD_NUMH16. Número de 16 bits.

• COD_PUNTERO. Puntero de la forma SEGMENTO:OFFSET.

• LCOD_FAR y HCOD_FAR. Puntero FAR.

• COD_rm16. Registro o memoria de 16 bits.

IDARG contiene sólo activo el valor de memoria de 16 bits; los otros no son tomados en cuenta, por lo que la instrucción válida es FFH. Con la instrucción sólo falta determinar el byte MOD R/M, el cual se obtiene con ayuda de FLAGDIR y los bits R/M se agregan del constructor, resultando la instrucción completa como:

76 En este caso las constantes son COD_P86 para procesador 8086/8088, y COD_P186 para 80186/80188. 77 La lista de todos los comparadores se encuentra en el archivo DEFINE.H. Esta lista son todas las formas válidas posibles que puede tener la variable IDARG.

Page 87: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

80

CALL [BX] -> FF17H

Una vez que se traduce la instrucción, la función wASM2MAQ retorna el código máquina, el número de bytes del código (en este caso 2) y el nuevo offset para la siguiente instrucción. El auxiliar de comparador es empleado cuando sólo cierto argumento es permitido; por ejemplo para fijar que sólo se acepta el registro AX en la instrucción, en este colocamos el índice del registro AX para token IDREG16. De esta manera, la instrucción no sólo será válida para un registro de 16 bits, sino en especial para el registro AX.

5.3.6 Instrucciones de dos argumentos

Si la instrucción es de dos argumentos, se realiza el mismo procedimiento que ocurre con una instrucción de un argumento; sin embargo, en este caso se calculan dos variables IDARG y dos variables FLAGDIR (un par para cada argumento). Además, estas dos variables son de gran ayuda, ya que pueden indicar si los argumentos son válidos o no. Entonces, con el índice se obtiene el vector del arreglo sBDesIntDosArg, que apunta al descriptor en sBCodIntDosArg. Los datos de este nuevo descriptor son los siguientes:

• Número de bytes de la instrucción.

• Código máquina (a lo más 2 bytes). • Constructor del byte MOD R/M para el primer argumento.

• Constructor del byte MOD R/M para el segundo argumento.

• Comparador del primer argumento (2 bytes).

• Comparador del segundo argumento (2 bytes).

• Byte auxiliar del comparador para el primer argumento.

• Byte auxiliar del comparador para el segundo argumento.

• Tipo de procesador válido para la instrucción. El proceso es el mismo para instrucciones de un sólo argumento, sólo que ahora primero se hacen la comparación entre el primer comparador y el IDARG del primer argumento, y luego entre el segundo comparador y el IDARG del segundo argumento. Además, los bits R/M de la Tabla 5.9, son asignados por la segunda instrucción; aunque en ocasiones estos bits no se asignan, debido a que uno de los argumentos puede ser un número.

Page 88: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

81

5.3.7 Instrucciones especiales.

El caso de instrucciones especiales es el mismo que de instrucciones de un sólo argumento; sin embargo, existe una diferencia, con las instrucciones de un argumento, y es que el ensamblador sólo espera una sola palabra por instrucción; por el otro lado, el ensamblador puede esperar hasta dos instrucciones especiales. Por ejemplo REP MOVSB. La función encargada de analizar las instrucciones especiales es wCodIEsp, en COD2MAQ.CPP. En este caso la traducción entra en un ciclo, se analiza la primera instrucción especial, y si se detecta otra, se realiza de nuevo el análisis; esto claro, conservando la semántica de la instrucción, para no permitir códigos no válidos. De igual forma, la traducción de cada instrucción especial se logra con un índice, el cual apunta a una tabla donde se encuentra el código correspondiente a cada instrucción; con esto, el ensamblador simplemente sustituye la palabra por su código correspondiente. 5.3.8 Palabras reservadas

Las palabras reservadas sólo informan algún tipo de configuración al ensamblador, no retorna ningún tipo de código, excepto DW y DB. Al igual que las anteriores, la palabra reservada siempre va al inicio de la cadena de instrucción. La función encargada de estas operaciones se llama wCodResWord en COD2MAQ.CPP. En este caso, dado que cada palabra puede tener diferentes argumentos, no requieren de un compilador en sí; lo que se hace es direccionar cada palabra a su respectiva función y esta se encarga de determinar los argumentos. La siguiente tabla muestra la lista de las palabras reservadas y de la función que se realiza para interpretarla.

Palabra Descripción

DB Define un byte o una cadena de bytes; en este caso el ensamblador en lugar de código retorna la cadena de bytes, indicando el siguiente offset en pwRef donde se colocara la siguiente instrucción.

DW Define un word (2 bytes) o una cadena de words. El ensamblador realiza el mismo procedimiento que DB.

ORG Lleva de argumento un número, el cual es sumado al offset pwRef. Esta será la nueva posición para la siguiente instrucción.

EQU Define una constante; este es un caso especial, ya que la palabra reservada se declara después de un nombre. Ver Sección 5.3.9.

Page 89: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

82

Palabra Descripción (continuación)

INCLUDE Define un archivo para compilar. Cuando el ensamblador recibe esta palabra, abre el archivo e inicia su compilación; sin embargo el archivo actual permanece abierto, hasta que termine de compilar el archivo definido en el INCLUDE.

PROC/: Al igual que EQU, esta se declara después de un nombre. Ver sección 5.3.9.

*SETREF Su argumento es un número, e indica al ensamblador el nuevo offset de código.

ENDP Esta es una palabra muda, el ensamblador no hace nada; sólo sirve para indicar el final del código fuente de un programa en ensamblador.

*P8086

*P8088

Le indica al ensamblador que debe sólo aceptar instrucciones del 8086/8088; para ello, compara el último byte en las tablas de código y en los descriptores.

*P80186

*P80188

Igual que el anterior, le indica al ensamblador que sólo debe aceptar instrucciones para el 80186/80188.

Tabla 5.10 Palabras reservadas. Las palabras marcadas con * se deben emplear al inicio del código fuente, ya que de otra forma habrá un error.

5.3.9 Análisis de etiquetas o constantes

Si el primer token no resulta conocido, entonces puede tratarse de una etiqueta o constante; en este caso el ensamblador verifica del siguiente token:

• Si el siguiente token es el operador “:” o la palabra reservada PROC, entonces se define una etiqueta y se agrega a la LCE.

• Si el siguiente token es la palabra reservada EQU, entonces es una constante y

se agrega a la LCE.

• Si el siguiente token es cualquier otro no conocido, hay un error. La función que se encarga de agregar la constante o etiqueta se llama wCodEtiqueta en LABEl.CPP.

5.4 El ensamblador de código Esta función, llamada vCompilaArchivo en COMPILAE.CPP, se encarga de armar el programa ejecutable. La operación es la siguiente.

1. Fija el offset de código en 0000H, este es el valor por default; borra todas las listas empleadas por el ensamblador (función vIniciaCompilacion), y se fija el primer paso del proceso de compilación.

Page 90: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

83

2. Crea el controlador de programa fuente, llamado sefIn; este controlador

determina cual es el medio por el cual se van a obtener las instrucciones del programa fuente. Los medios son: un archivo o el buffer de edición.

3. Por medio del controlador, se obtiene una línea del programa fuente. Esta línea se transfiere a la función wASM2MAQ, para su traducción a código máquina o interpretación.

4. Después de esta función puede suceder lo siguiente: Si la instrucción es un INCLUDE, se crea un nuevo controlador de programa fuente y se pasa el control a este; si hay error, se agrega a la lista de errores, si no hay error, el código generado se agrega a un buffer.

5. Regresa al paso 2, hasta llegar al final del archivo. Si había archivo definido con INCLUDE, se cierra este y continúa en el paso 2 con el archivo anterior.

6. Termino de compilar, si es el primer paso, se llama a la función wResuelveRef en LABEL.CPP, para que determinar todas las direcciones de etiquetas y las constantes, y retorna al paso 1. Si es el segundo paso, continua.

7. Muestra los mensajes; en caso de no existir error, crea el archivo ejecutable78. Si las opciones lo permiten, también crea el archivo con el mapa de todas las referencias, ver Apéndice A, Sección A.3.6.

5.4.1 Cálculo de referencias.

Para determinar las direcciones que tendrán las etiquetas, es necesario dar una segunda pasada; la primera pasada no determina con exactitud la dirección u offset de una etiqueta. Para el cálculo es necesario emplear las listas de instrucciones (LI) y de constantes y etiquetas (LCE). El algoritmo es el siguiente (función wResuelveRef, en LABEL.CPP):

1. Si el ensamblador esta en el segundo paso, termina. 2. Se asume que existen todas las etiquetas en la LCE, y no tienen el offset

correcto. De las instrucciones en la LI sólo se conoce su posible offset. 3. Obtiene un elemento de la lista de instrucciones. En este punto sólo se conoce

su posible offset, ya que no pudo ser compilado y no se sabe el número de bytes de código.

4. La instrucción en LI se compila con la función wASM2MAQ; con esta función es posible determinar el tamaño del código, y por lo tanto el nuevo offset de la siguiente instrucción. Si la instrucción no se puede traducir79, asume un tamaño de código por default; esto no esta mal, ya que en la segunda pasada el error aparecerá y se notificara.

5. Con el tamaño de código se determina cuanto se debe incrementar los offset de los elementos en LCE. En este caso, si el número de bytes de la instrucción en

78 No siempre se crea el archivo, ello depende de la opción de compilación; si es a memoria, no se hace nada, ya que es el mismo buffer donde coloca el código; si es en archivo, vacía el buffer a un archivo con extensión .COM. 79 Debido a que la palabra no se declaro en ningún lado.

Page 91: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

84

la lista es diferente al que obtuvo wASM2MAQ, entonces se actualiza el offset

de todas las instrucciones y etiquetas cuyo contador sea mayor al del actual. 6. El proceso continua con el paso 3, hasta la última instrucción en la lista. 7. Si no se modificó ningún offset desde el principio de la lista hasta el último,

termina y las referencias fueron determinadas, de otra forma regresa a las listas desde el paso 3.

Cuando el algoritmo finaliza, en la LCE estarán todos los desplazamientos correctos, así en la segunda pasada, las palabras que desconocía en la primera, las podrá encontrar en la lista y sustituir por sus desplazamientos correspondientes. Por ejemplo, suponga el siguiente código (el offset inicia en 0000H):

Instrucción Acción del ensamblador Offset JNA SALTO2 No reconoce SALTO2, agrega la instrucción a la LI. 0000H SALTO0: Agrega SALTO0 a la LCE. 0000H CMP AX, 1000H Traduce a 3D0010H 0000H JNE SALTO1 No reconoce SALTO1, agrega la instrucción a la LI. 0003H SALTO2: Agrega SALTO2 a la LCE. 0003H JMP SALTO0 Existe SALTO0 en la lista, pero como hay elementos en la

LI, la referencia de SALTO0 no es correcta. Se agrega la instrucción a la LI.

0003H

SALTO1: Agrega SALTO1 a la LCE. 0003H MOV AX, 1000H Traduce a B80010H 0003H

Tabla 5.11 Primera pasada.

Después de la primera pasada, las listas tendrán la siguiente información:

LI LCE Instrucción: JNA SALTO2 Bytes de Código: 0 (No se compilo) Offset: 0000H Contador: 0

Etiqueta: SALTO0 Offset: 0000H Contador: 1

Instrucción: JNE SALTO1 Bytes de Código: 0 (No se compilo) Offset: 0003H Contador: 2

Etiqueta: SALTO2 Offset: 0003H Contador: 3

Instrucción: JMP SALTO0 Bytes de Código: 0 (No se compilo) Offset: 0003H Contador: 4

Etiqueta: SALTO1 Offset: 0003H Contador: 5

Tabla 5.12 Contenido de las listas LI y LCE. Observe que el Contador es un número consecutivo entre instrucciones y etiquetas; esto ayuda a determinar que apareció primero si la etiqueta o la instrucción.

Page 92: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

85

Para resolver todos las referencias, obtenemos las instrucciones de la LI y se compilan; esto es, para la primer elemento de la LI: JNA SALTO2 al traducirla se convierte en JNA 00003H, lo cual genera el código 7601H de 2 bytes. Como los bytes de código difieren de los de la lista, modifica todos las referencias de los elementos de ambas listas, para los que el Contador sea mayor al de la instrucción (en este caso 0)80. La Tabla 5.11 se convierte ahora en:

LI LCE Instrucción: JNA SALTO2 Bytes de Código: 2 Offset: 0000H Contador: 0

Etiqueta: SALTO0 Offset: 0002H Contador: 1

Instrucción: JNE SALTO1 Bytes de Código: 0 (No se compiló) Offset: 0005H Contador: 2

Etiqueta: SALTO2 Offset: 0005H Contador: 3

Instrucción: JMP SALTO0 Bytes de Código: 0 (No se compiló) Offset: 0005H Contador: 4

Etiqueta: SALTO1 Offset: 0005H Contador: 5

Tabla 5.13 Contenido de las listas LI y LCE.

Se toma la siguiente instrucción. JNE SALTO1 se convierte en JNE 0005H ya que SALTO1 existe en la lista; esto retorna el código 75FEH, con 2 bytes de código. Este último valor se compara con el de la lista y si es diferente, se modifican todos los desplazamientos de los elementos de LI y LCE cuyo contador sea mayor al de la instrucción actual (2); en este caso, las listas ahora tienen la siguiente información:

LI LCE Instrucción: JNA SALTO2 Bytes de Código: 2 Offset: 0000H Contador: 0

Etiqueta: SALTO0 Offset: 0002H Contador: 1

Instrucción: JNE SALTO1 Bytes de Código: 2 Offset: 0005H Contador: 2

Etiqueta: SALTO2 Offset: 0007H Contador: 3

Instrucción: JMP SALTO0 Bytes de Código: 0 (No se compiló) Offset: 0007H Contador: 4

Etiqueta: SALTO1 Offset: 0007H Contador: 5

Tabla 5.14 Contenido de las listas LI y LCE.

80 Estrictamente no es modificar, sino agregar los bytes que aumento del código; en este caso, el número de bytes de código es igual a 0, al compilar creció a 2 y la diferencia es el valor que habrá que agregar a cada offset.

Page 93: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

86

Se toma hora la siguiente instrucción, JMP SALTO0 el cual se convierte en JMP

0002H. Al compilarla, el código es EBF9H con 2 bytes de código; comparamos esto con la lista y actualizamos los desplazamientos de los elementos cuyo contador sea mayor a 4. Las listas ahora son:

LI LCE Instrucción: JNA SALTO2 Bytes de Código: 2 Offset: 0000H Contador: 0

Etiqueta: SALTO0 Offset: 0002H Contador: 1

Instrucción: JNE SALTO1 Bytes de Código: 2 Offset: 0005H Contador: 2

Etiqueta: SALTO2 Offset: 0007H Contador: 3

Instrucción: JMP SALTO0 Bytes de Código: 2 Offset: 0007H Contador: 4

Etiqueta: SALTO1 Offset: 0009H Contador: 5

Tabla 5.15 Contenido de las listas LI y LCE. Ya no hay instrucciones, pero hubo modificaciones en el offset de algunos elementos; repetimos el proceso desde la primera instrucción. JNA SALTO2 se transforma en JNA 0007H; sin embargo, el número de bytes de código es 2, el cual es el mismo y no se realiza modificación. JNE SALTO1 se transforma en JNE 0009H; el código es 7502H con 2 bytes de

código. No hay cambio en este último número, no se realiza ninguna acción. La última instrucción es JMP SALTO0, la cual se convierte en JMP 0002H. Al compilar el código es EBF9H, con 2 bytes; nuevamente no se realizan cambios. Ya no existen más instrucciones y no se hicieron modificaciones; termina el algoritmo y sigue el segundo paso. Las listas ya tienen todas las referencias correctas.

Instrucción Acción del ensamblador Offset JNA SALTO2 Reconoce SALTO2, traduce a 7605H. 0000H SALTO0: Segundo paso, no se agregan etiquetas ni constantes. 0002H CMP AX, 1000H Traduce a 3D0010H 0002H JNE SALTO1 Reconoce SALTO1, traduce a 7502H. 0005H SALTO2: Segundo paso, no se agregan etiquetas ni constantes. 0007H JMP SALTO0 Reconoce SALTO0, traduce a EBF9H. 0007H SALTO1: Segundo paso, no se agregan etiquetas ni constantes. 0009H MOV AX, 1000H Traduce a B80010H 0009H

Tabla 5.16 Segunda pasada.

Page 94: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

87

De esta forma se tiene el código máquina de todo el programa anterior. Un punto de vital importancia es el Contador; ya que sin este, es imposible asignar el nuevo offset a cada elemento de la lista.

Page 95: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

88

Page 96: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

89

Capitulo 6. El depurador de la UAMI188EB

6.1 Introducción En general, un depurador permite determinar los errores que contiene un programa. Cuando se desarrollan programas en lenguaje ensamblador (y en general en cualquier lenguaje de programación), aun cuando el análisis y el diseño del mismo sean muy buenos, estos no están exentos de errores que pueden deberse a muchas causas. Buscar un error en un programa, puede realizarse básicamente en dos formas:

1. Revisando el código fuente. 2. Examinando el programa en tiempo ejecución.

La primer forma puede resultar una ardua labor, y no permite que existe una

interacción entre el programa y el ambiente con el cual se rodeará. En cambio la segunda forma, permite detectar el error cuando el programa esta ejecutándose; pero requiere de contar con herramientas que permitan monitorear o trazar el comportamiento del programa durante su ejecución. Al trazar un programa, el usuario o programador, controla la ejecución de un programa, permitiendo su ejecución por bloques de código o línea a línea de código. En el caso muy particular del depurador de la UAMI188EB, la opción de trazado consiste en ejecutar instrucción por instrucción; también puede existir la posibilidad de ejecutar bloques de código, pero el programador deber encargarse de ello, más adelante se explicara este punto. El depurador de la UAMI188EB permite al usuario ejecutar un programa en la tarjeta de experimentación, y ver el comportamiento de este en la PC, por medio del programa D188.EXE. No sólo es posible ver el comportamiento, también es posible cambiarlo, modificando durante su ejecución el valor de las variables que este manipule; sin embargo, el depurador tiene sus limitaciones, y una de ellas es que no es posible corregir el código directamente, en su lugar, el programador tendrá que trasladarse al código fuente, corregir el error, cargar de nuevo programa a la UAMI188EB y regresar con el trazado del programa para buscar más errores.

6.2 Estructura del depurador El depurador se compone fundamentalmente de tres partes:

• Una interfaz de usuario.

• Un convertidor de línea de ensamblador a código máquina.

• Un convertidor de código máquina a ensamblador.

Page 97: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

90

La interfaz de usuario permite establecer comunicación entre el D188.EXE y el usuario; permite iniciar y continuar con el trazado de un programa, cambiar el valor de un registro o localidad de memoria, y modificar una instrucción81. El convertidor de línea de ensamblador a código maquina, es básicamente la función wASM2MAQ, que convierte una instrucción en su correspondiente código máquina. El convertidor de código máquina a ensamblador permite traducir los 0’s y 1’s, en instrucciones en lenguaje ensamblador; para ello emplea todas las estructuras y tablas que se usan para convertir instrucciones en ensamblador a código máquina.

6.3 La interfaz de usuario Consiste en un conjunto de ventanas, cuadros de dialogo y comandos, que permiten trazar un programa; la ventana principal es la siguiente:

Figura 6.1 Ventana principal del depurador.

Esta ventana se subdivide en 3; estas ventanas son: el área de programa, la lista de registros, y el área de volcado de memoria. El área de programa muestra las instrucciones en ensamblador y su correspondiente código máquina, así como también se muestra el offset de cada instrucción. Esta subventana se encarga de presentar el resultado de convertir instrucciones a partir del código máquina. Es posible cambiar una instrucción, pero

81 Esta opción no modifica la instrucción en la UAMI188EB, solo sirve de referencia al programador.

Page 98: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

91

este cambio solo se verá reflejado en el buffer del D188.EXE y no directamente en la UAMI188EB; aunque es posible cargar estos cambios a la tarjeta de experimentación, ya sea cargando directamente el programa del buffer del D188.EXE, o por medio del código fuente en el editor. La lista de registros muestra el valor de cada uno de estos en la tarjeta de experimentación; seleccionando un registro, es posible en todo momento cambiar su valor, el cual se verá inmediatamente reflejado en la UAMI188EB. El área de volcado de memoria es un buffer dentro del D188.EXE, el cual guarda los bytes provenientes de la memoria de la UAMI188EB. Esta interfaz es la encargada de manejar dos buffers, el de código y el de datos. En el buffer de código se encuentra lo que se muestra en el área de programa, y en el buffer de datos se localiza lo que se presenta en el área de volcado de memoria; ambos buffers son independientes. El buffer de código se llama pBCodMaq y el de datos pbBuffVolMem. Cargar el buffer de código puede realizarse de 3 formas:

• Compilando a memoria un programa fuente.

• Cargando el programa desde un archivo.

• Cargando un programa que se localiza en la UAMI188EB. Lo anterior solo carga código al buffer, pero no a la UAMI188EB; pero una vez que este código sea cargado a la UAMI188EB82, se configura para que pueda depurar un programa; aunque en realidad el D188.EXE tiene el control de esto. La UAMI188EB en todo momento puede recibir el comando de trazado cmsPASO (ver Capitulo 3, Secciones 3.5.4 y 3.7), y esto permite la ejecución de lo que tenga en memoria. En cambio, cargar el buffer de datos solo es posible cuando se obtienen datos de la UAMI188EB.

6.4 Convertidor de ensamblador a código máquina El depurador del D188.EXE permite en todo momento cambiar una instrucción por otra. Esto lo logra con ayuda de la función wASM2MAQ, a la cual simplemente se le pasa la instrucción; los demás datos como son el número de línea, y el offset no son necesarios, ya que sólo se necesita la representación en código máquina.

82 Cargar un programa a la UAMI188EB, siempre involucra una transferencia del buffer de código a la memoria de la UAMI188EB.

Page 99: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

92

En todo momento es posible acceder al depurador, aun cuando no este cargado un programa. Esta libertad permite que el usuario diseñe o construya su programa con el depurador, y después lo envíe a la UAMI188EB. El modificar una instrucción puede hacerse de dos formas:

• Insertando la instrucción

• Sustituyendo la instrucción La primera forma recorre los bytes que sean necesarios para introducir la nueva instrucción; la segunda forma sustituye los bytes necesarios por la nueva instrucción.

Una vez que la instrucción ha sido introducida, la función wASM2MAQ, se encarga de traducir la instrucción, se agrega al buffer de código, y se barre el buffer de código para convertir el código máquina a ensamblador; toda modificación produce que se relea el buffer código para traducir de código máquina a ensamblador.

6.5 Convertidor de código máquina a ensamblador Este convertidor esta implementado por la siguiente función en el archivo DEC2ASM.CPP:

wMAQ2ASM (char *pcTxt, char *pbCod, word wPos, word wRef, word wLen);

En donde pcTxt es la instrucción en ensamblador traducida, pbCod el código a traducir, wPos es el offset de la instrucción, wRef es el offset donde inicia el código y wLen es la longitud de pbCod. La función regresa el número de bytes de la instrucción. Esta función realiza la traducción línea a línea, tomando para ello los bytes que sean necesarios de pbCod, pero limitado a wLen. Ya que si no le es posible traducir, debido a que wLen limita el tamaño de código, retorna la instrucción DB. Para hacer la conversión a ensamblador, la función wMAQ2ASM, realiza lo siguiente:

1. Toma el primer byte de pcCod, y lo compara con las tablas de código de instrucciones especiales y de instrucciones sin argumentos; si el byte esta en alguna de las tablas, obtiene el índice, para después con el tipo de token, regresar el texto de la instrucción.

Page 100: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

93

2. Toma los primeros bytes (uno o dos), y los compara con los bytes en los descriptores de instrucciones con uno y dos argumentos; si encuentra concordancia, obtiene el índice, para después volver a la tabla de vectores y de ahí obtener la instrucción.

3. Si lo anterior falló, coloca simplemente la palabra DB seguido del primer byte. Este caso DB es para definir un byte con cierto valor.

Los casos interesantes son cuando se tiene que traducir códigos de instrucciones de uno y dos argumentos; aunque en general, simplemente se aplica el caso inverso de la compilación. 6.5.1 Instrucciones especiales y sin argumentos

En este caso, se obtiene el primer byte83 y se compara con los bytes que se encuentran en las tablas de código; esta búsqueda la realiza desplazándose por el índice de la tabla. Cuando encuentra el código, con ayuda del tipo de token (el cual es conocido, debido a la tabla de código), y del índice, es posible obtener la instrucción de la lista. La función entonces retorna la instrucción y el número de bytes asociados a esa instrucción, que en general es de un byte. Como puede observarse, este proceso es el inverso de la compilación y en todos los casos es el mismo proceso: comparamos código, obtenemos el índice y de ahí se obtiene la instrucción. En general el proceso de convertir código máquina a ensamblador es más sencillo que el proceso inverso. 6.5.2 Instrucciones de uno o dos argumentos

Para entender el principio, proponemos un ejemplo; suponga el siguiente código: B03A78232……..2323H84

El primer paso es verificar los descriptores para un argumento; revisando cada uno de estos se tiene que no existe correspondencia. En seguida se revisan los descriptores para instrucciones de dos argumentos; en esta tabla se encuentra85: 0x01, 0xB0 , 0x00, RM_S|RM_N, RM_N, COD_REG08, 0x00, COD_IMM08 ,0x00, 0x00, 0x00, COD_P86

83 En general puede tomar más de un byte, ello depende de lo que se indique en la tabla de códigos, para el caso de las instrucciones 8086/8088 y 80186/80188, solo se necesita un byte. 84 Se colocan todos los bytes, ya que en teoría no se sabe el número de bytes que tiene la instrucción. 85 La información de los descriptores de código se muestra en el Capitulo 5, Secciones 5.3.5 y 5.3.6.

Page 101: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

94

Donde el término subrayado corresponde al código de la instrucción; en seguida se revisan los constructores del byte MOD /RM86 en el descriptor. Ambos constructores tienen el bit 0 en 1 (RM_N)87, lo que indica que no existe el byte MOD

R/M y los bytes FLAGDIR de ambos argumentos son iguales a 0; pero existe la bandera RM_S para el constructor del primer argumento, que indica que al código se le sumó el valor de algún registro. Cada registro tiene asignado un número, el cual está dado por los bits REG del byte MOD R/M, ese valor es el que se suma al código de la instrucción; es decir:

Código del programa Código del descriptor REG

B0H B0H B0H - B0H = 00H

Entonces los bits REG están dados por el valor 00H. Se tiene un argumento, y

se sabe que es un registro, pero falta determinar cual es. Para esto, se analiza el descriptor de nuevo, pero en los bytes del comparador, ya que el comparador determina las variables IDARG de ambos argumentos; el comparador del primer argumento se encuentra la constante COD_REG0888, que indica un registro de 8 bits. Debido a lo anterior, se revisa la tabla de registros (ver Capitulo 5, Sección 5.3.4, Tabla 5.7), y en este caso resulta que el registro es AL. Ahora sólo falta examinar el siguiente argumento, para ello se revisa el comparador del segundo argumento, que en este caso es COD_IMM08; es decir, un número de 8 bits.

Resumiendo lo anterior se tiene:

• La instrucción es B0H, y no tiene byte MOD R/M, pero se forma de la suma del

valor de un registro. • Este registro es el primer argumento, y se trata del registro AL.

• El siguiente argumento es un número de 8 bits, y como no hay byte MOD R/M, entonces el siguiente byte debe ser ese número, en este caso 3AH, y la instrucción solo ocupa 2 bytes, el resto pertenece a otra.

Con la información anterior, se determina que la instrucción es la siguiente: MOV AL, 3AH

La función wMAQ2ASM regresa la cadena anterior, e informa que sólo ocupo dos bytes de pbCod, de esta forma cuando se llama de nuevo a la función wMAQ2ASM, se hace pero recorriendo el offset de pbCod 2 unidades.

86 En este caso hay dos constructores, ya que existen dos argumentos. 87 Ver Capitulo 5, Sección 5.3.5, Tabla 5.9. 88 Estas constantes están definidas en el archivo DEFINE.H

Page 102: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

95

El algoritmo para traducir de código máquina a ensamblador es el siguiente:

1. Se comparan los bytes de código de los descriptores. 2. Cuando se encuentra una correspondencia, se examinan los constructores del

MOD R/M, con esto se determinan los argumentos. Esta verificación regresa el byte FLAGDIR para ambos argumentos

3. Una vez conocido el tipo de argumento, se examinan los comparadores y determinan las variables IDARG de los argumentos.

4. Al determinar las variables FLAGDIR e IDARG, es posible construir la instrucción, ya que solo es obtener los símbolos correspondientes a estas variables.

El algoritmo función para instrucciones de un argumento o de dos argumentos; la diferencia esta en que para un argumento sólo se revisa un constructor MOD R/M, y un comparador. Debido a la estructura de la variable FLAGDIR, es fácil determinar el argumento cuando se trata de un tipo de direccionamiento, ya que esta variable, indica explícitamente el contenido del argumento. Por su parte IDARG, informa algunas características del argumento o en todo caso cual es el argumento; de igual forma, indica explícitamente el argumento.

Page 103: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

96

Page 104: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

97

Apéndice A. Manual de usuario

A.1 Introducción Este manual tiene la finalidad de explicar el uso del Ensamblador y depurador

para la UAMI188EB. Este sistema permite programar la UAMI188EB directamente sin hacer uso de las memorias EPROM como medio de programación. La aplicación consta de dos partes:

• Programa ejecutable bajo MS-DOS llamado D188.EXE.

• Programa BIOSM.COM.

La creación de un programa en ensamblador, su compilación, ejecución y depuración, ahora esta a cargo de un sólo sistema. La aplicación transfiere directamente a la memoria de la UAMI188EB, y desde la tarjeta de experimentación es ejecutado y depurado el programa.

La programación de la UAMI188EB con el nuevo sistema tiene muchas

ventajas en comparación del proceso de programación anterior; permite ahorrar tiempo, la depuración de los programas se puede realizar en tiempo de ejecución y no es necesario emplear más las EPROMs; sin embargo, tiene la desventaja de emplear el puerto serie, pero es posible evitar este problema, más adelante se mostrara un ejemplo. A.1.1 Programa D188.EXE

El programa D188.EXE es una aplicación que permite construir programas en lenguaje ensamblador, transferirlos a la UAMI188EB y depurarlos. Posee una interfaz amigable en modo texto basado en ventanas, que permite al usuario acceder fácilmente a las opciones del programa. A.1.2 Programa BIOSM.COM

Este programa contiene el BIOS y el Monitor de la UAMI188EB; básicamente se

encargan de controlar la tarjeta y de comunicarla con el programa D188.EXE. Este programa debe estar montado en una EPROM, y debe estar colocada en la primera base (al lado de la RAM) de ROM de la UAMI188EB.

El BIOS es el programa que activa todos los periféricos de la tarjeta para que

estén al alcance del usuario; el Monitor es el mediador entre la UAMI188EB y el programa D188.EXE. El BIOS tiene el control absoluto de la tarjeta, mientras que el monitor sólo tiene control sobre las comunicaciones entre la UAMI188EB y el programa D188.EXE.

Page 105: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

98

A.1.3 Requisitos del sistema

Para su funcionamiento el sistema de necesito lo siguiente: 386 IBM PC o compatible (o superior) MS-DOS 5.0 o superior89 640Kb de memoria 2Mb en disco duro Un puerto serie Cable de conexión, ver Fig. A.1.

Figura A.1 Configuración del cable de conexión entre la UAMI188EB y la PC.

A.2 Descripción del programa D188.EXE La interfaz del programa D188.EXE se muestra en la Fig. A.2. Esta interfaz en ocasiones también se conoce como desktop.

Figura A.2 Interfaz del programa D188.EXE

89 Es posible usar cualquier ambiente Windows; sin embargo, debido a problemas con Windows XP, es posible que aquí no funcione correctamente.

Page 106: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

99

En la parte superior se observa la barra de menú, la cual puede ser accedida mediante la tecla F10 y la teclas de dirección, o el ratón; en la parte inferior se localiza la barra de estado y el reloj, esta barra de estado muestra algunas teclas rápidas en rojo (hot keys) para acceder a comandos de una manera más fácil, también es posible usar el ratón para seleccionar; por último, en la parte superior derecha (en verde) se encuentra el icono de estado de la tarjeta. Existen 6 estados, que pueden ser mostrados en el icono:

• OK – La tarjeta esta lista para trabajar, nos existe ningún programa cargado en ella. Este estado es el que fija al iniciar o reiniciar la tarjeta.

• STP – La tarjeta tiene un programa cargado, pero no esta en ejecución; desde este punto, es posible ejecutar el programa cargado o trazarlo.

• DBG – Se esta trazando un programa, por el momento no se esta ejecutando el programa, pero desde este punto es posible ejecutar línea a línea del programa o ejecutarlo completamente.

• RUN – Se esta ejecutando un programa en la UAMI188EB

• DSC – El programa no puede establecer conexión con la UAMI188EB; esto puede ocurrir por dos razones, la UAMI188EB envió mensaje de desconexión, o el programa D188.EXE intento establecer la conexión con la UAMI188EB sin éxito.

• ??? – Hay comunicación con la UAMI188EB, pero se desconoce en cual estado de los anteriores se encuentra.

Observe que algunas letras en el menú están resaltadas, esto significa que si

presionamos la tecla ALT+letra90, se accede a esa opción en el menú; además, algunos comandos del menú también tienen teclas rápidas, estas se muestran del lado derecho de cada comando en el menú.

En general es de esperar que la UAMI188EB ya este encendida antes de iniciar

el programa D188.EXE, ya que este último puede verificar si la UAMI188EB se encuentra lista o no; si embargo, esto no es necesario, ya que para crear programas en D188.EXE la tarjeta no es indispensable. Por otra parte, si D188.EXE ya esta corriendo y se enciende la UAMI188EB, este ultimo envía una señal de listo, pero no el estado, de esta forma en el icono de estado se tendrá ???.

Es importante conocer que se esta mostrando en el icono de estado, ya que no

todos los comandos del menú estarán activos, ello depende del estado de la UAMI188EB; así por ejemplo, si la UAMI188 esta apagada el icono mostrara DSC y el comando

90 En este caso el símbolo + significa presionar las teclas al mismo tiempo.

Page 107: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

100

A.2.1 La barra de menú

Se tienen 7 opciones dentro de la barra, cada elemento de la barra del menú

despliega una ventana con un nuevo menú, en donde cada elemento representa una acción que puede realizar el programa D188.EXE. Algunos elementos del menú pueden estar en un color más tenue (gris), esto indica que la acción de ese menú no esta permitida por el momento. La descripción de los comandos del menú es:

• Archivo – Contiene los comandos para apertura y cierre de programas.

• Edición – Aquí se encuentran los comandos para el manejo del texto en las ventanas de edición.

• Búsqueda – Comandos para buscar y remplazar texto.

• Compilar – Esta opción permite ensamblar el código fuente y generar un programa.

• UAMI188EB – Estos comandos están destinados a realizar operaciones de comunicación con la UAMI188EB.

• Depuración – Comandos para depuración de programas.

• Ventanas – En este menú están contenidos los comandos para el manejo de ventanas.

A.2.2 Cuadros de diálogo

Los cuadros de diálogo permiten una mejor comunicación entre el programa y

el usuario; en general son empleados para informar al usuario, o para captura de datos, ver Fig. A.3.

Figura A.3. Cuadro de diálogo del programa D188.EXE

El cuadro de diálogo en la Fig. A.3 muestra varios objetos, como son: botones,

una línea de captura y una lista. Así mismo observe que cada objeto tiene un titulo, el cual hay una letra resaltada en un color diferente, esto ayuda a seleccionar el objeto presionando ALT+letra; por ejemplo si se presionan los botones ALT+F, se habrá

Page 108: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

101

seleccionado la lista de archivos en el cuadro de diálogo. Es posible navegar entre cada objeto presionando la tecla TAB o con ayuda del ratón.

Existen otros objetos que requieren de activar una casilla para activarlo, en este

caso, dicho objeto se selecciona y la casilla se activa con la tecla de Espacio. Por ejemplo, en la Fig. A.7 hay objetos que contienen casilla para su activación.

En algunos casos, para cerrar un cuadro de diálogo sin que se hagan cambios o

modificaciones al contenido de estos, es suficiente con presionar la tecla ESC.

A.2.3 Ventanas

Existen tres tipos de ventanas en D188.EXE: de edición, mensajes y depuración,

ver Fig. A.4.

Figura A.4 Ventanas de depuración y edición.

Todas la ventanas tienen una misma característica: el marco. En el marco se encuentra el icono para cerrar, en la parte superior izquierda; el icono para maximizar, en la parte superior derecha; la esquina inferior derecha para cambiar de tamaño y un titulo en la parte superior. Es posible mover una ventana con ayuda del ratón, sólo basta posicionar el ratón en el marco en su parte superior y mantener presionado el botón izquierdo.

Page 109: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

102

La ventana de depuración, ver parte superior de la Fig. A.4, en su interior existen 3 subventanas, una que muestra código en ensamblador (buffer de depuración), otra que muestra el valor de registros91 en la UAMI188EB y la última que muestra un área de memoria (buffer de volcado de memoria). Para navegar entre estas ventanas, sólo hay que presionar la tecla TAB; y dentro de estas es posible hacerlo con las teclas de dirección. La ventana de edición permite modificar el contenido de un archivo, el funcionamiento es semejante al de un procesador de palabras. Podemos desplazarlos por todo el texto con los botones de dirección, escribir texto, copiar y pegar texto, etc. La ventana de mensajes es similar a la ventana de edición, con la diferencia de que en ella se muestran los mensajes (errores, warnings e información) que sucedieron durante la compilación de un archivo fuente.

A.3 Comandos del menú La barra de menú siempre esta activa, salvo en el caso de cuadros de diálogo,

en donde no es posible acceder a la barra de menú. Es posible acceder a la barra de menú seleccionando la opción con el botón izquierdo del ratón, con la tecla F10 y las teclas de dirección, o con ALT+letra, donde letra es la primera letra del nombre de

cada elemento del menú, iluminada en otro color. Al seleccionar un elemento del menú, este desplegará un ventana (submenú)

con nuevos elementos o comandos de menú; se puede acceder a estos por medio de las teclas de función o el ratón. También es posible acceder a ellos, presionando simplemente la tecla de la letra que se encuentra iluminada en un color distinto; por ejemplo, en la Fig. A.5 si presionamos la tecla N, seleccionaremos el menú Nuevo. Esto no quiere decir que se ejecuta el comando Nuevo, sino que únicamente se selecciona, para ejecutarlo hay que presionar la tecla Enter.

Otra forma de seleccionar los elementos del submenú, es presionando la

combinación de teclas que se encuentra en el lado derecho de cada submenú; esta combinación puede ser aplicada en cualquier momento, excepto en cuadros de diálogo.

A.3.1 Archivo

Los comandos dentro del menú Archivo son:

91 Los registros que se presentan son: AX, BX, CX, DX, DI, SI, BP, SP, CS, DS, ES y SS.

Page 110: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

103

• Abrir – Abre un archivo con código fuente ya existente.

• Nuevo – Crea un nuevo archivo.

• Guardar – Guarda el archivo que se esta editando actualmente.

• Guardar como – Guarda el archivo con el mismo nombre o con un nuevo.

• Cerrar – Cierra el archivo actual.

• Cambio de directorio – Permite seleccionar otro directorio de trabajo; el directorio de trabajo es lugar en el disco donde se localizan los archivos para abrir o guardar, pero en general es posible seleccionar otro directorio al abrir o guardar un archivo.

• DOS Shell – Es una salida temporal al sistema operativo MS-DOS, para regresar sólo hay que teclear exit en la línea de comando.

• Salir – Termina la sesión con el programa D188.EXE

Figura A.5 menú Archivo.

Sólo en el caso de Abrir y Guardar como, se presenta un cuadro de diálogo, ver Fig. A.3, para seleccionar el archivo o proporcionar un nombre de archivo. Al momento de guardar, sólo es necesario dar el nombre de archivo sin extensión; por default el programa asigna la extensión ASM.

A.3.2 Edición

Estos comandos sólo afectaran a las ventanas de edición, las ventanas de depuración y mensajes no son afectadas por este menú. Los comandos del menú Edición son:

• Deshacer – Elimina la ultima acción sobre la ventana de edición, dejando la ventana como se encontraba antes de la acción.

• Cortar – Corta el texto seleccionado en el editor, y lo coloca en el portapapeles.

• Copiar – Copia el texto seleccionado en el editor, y lo coloca en el portapapeles.

• Pegar – Toma el texto que se encuentra en el portapapeles y lo pega en la ventana de edición actual.

• Mostrar portapapeles – Presenta el contenido del portapapeles.

• Opciones – Presenta el cuadro de diálogo de configuración del programa D188.EXE.

Page 111: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

104

Figura A.6 menú Edición.

Para seleccionar texto en el editor, se emplea la tecla SHIFT junto con las teclas de dirección; es decir, manteniendo presionada la tecla SHIFT y con ayuda de las teclas de dirección es posible seleccionar texto para cortarlo o copiarlo. Otra forma es con ayuda del ratón; en este caso, basta con mantener presionado el botón izquierdo y desplazando el ratón a través del texto deseado.

El menú de Opciones presenta un cuadro de diálogo, como el de la Fig. A.7. Estas opciones permite configuración personalizada el programa D188.EXE. Las opciones dentro de este cuadro de diálogo son: Editor: Opciones para la edición de archivos.

• Margen – Si esta casilla esta activa el editor, en cada nueva línea de texto, dejara un margen izquierdo de n espacios en blanco; estos n espacios se determinan por los n espacios de la línea anterior. Si la primera línea no contiene ningún espacio en blanco, entonces n = 0 y no habrá margen alguno, pero si se deja una línea con 2 espacios en blanco, entonces las siguientes líneas tendrán 2 espacios en blanco. Esto permite un cierta estructura en el código fuente.

• MAY/min – Si esta casilla esta activada, al colocar el carácter ; se cambia automáticamente a minúsculas; si seleccionamos una nueva línea, se cambiara a mayúsculas. Los comentarios en lenguaje ensamblador son iniciados con el carácter ;, lo que se busca es que las instrucciones sean escritas en mayúsculas

y los comentarios en minúsculas, esto ofrece una mejor presentación al código fuente.

• Resaltar – Si esta activa, cada palabra en el texto se ilumina de un cierto color, ello depende del significado que tenga palabra; por ejemplo, las instrucciones se iluminan en verde y los registros en azul, ver Fig. A.4. Si esta desactivada, todo el texto estará en amarillo con fondo azul.

Page 112: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

105

Figura A.7 Cuadro de diálogo de Opciones.

Puerto: Selecciona el puerto que empleara la PC para comunicarse con la UAMI188EB. Velocidad de Puerto: Selecciona la velocidad a la que se comunica la PC con la UAMI188EB, por default la velocidades 1920092. Dirección destino del .COM: Es el directorio donde se espera sea colocado el archivo ya ensamblado; si no hay directorio destino, el archivo es colocado en el actual directorio de trabajo. Seg. Espera: Es el tiempo que el programa D188.EXE espera a la UAMI188EB en una comunicación, antes de enviar el mensaje comunicación no establecida, el valor predeterminado es de 2 segundos. Manejo de memoria: Esta es una parte importante del programa, los valores que aquí se escriban, pueden afectar el desempeño del mismo. Para que los cambios surtan efecto, es necesario salir del programa y reiniciarlo.

• No. de bytes para compilar – Número de bytes necesario para compilar una línea de código; en general no es necesario mucha memoria, por default 512 bytes son más que suficientes.

• No. de bytes para variables – Esta es una parte importante, ya que para programas que tengan un número excesivo de constantes, etiquetas o

92 Para cambiar la velocidad hay que cambiar la velocidad también en la tarjeta; para ello, es necesario contar con el código fuente del BIOS y el Monitor.

Page 113: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

106

procedimientos es necesario mucha memoria; por default 17408 bytes son suficientes.

• No. de bytes para depurar – Es el tamaño de memoria donde se cargara el archivo para su depuración. En teoría la memoria RAM máxima de la UAMI188EB es de 8Kb, por lo que no es posible cargar un programa más grande, por lo tanto 17408 bytes son suficientes.

• No. de bytes para volcado – En esta memoria se colocan los datos extraídos de la UAMI188EB; en este caso, es posible leer lo que hay en la ROM de la UAMI188EB, que es de 16KB, por lo tanto 17408 bytes son suficientes93.

• No. máximo de mensajes – Al ensamblar un programa se generan menajes, ya sea de error, warnings (advertencias) o informativos; el numero de mensajes permitido es fijado por este valor; por default el numero es de 60 mensajes.

Video: Permite configurar la presentación del programa; existen tres opciones: Blanco y negro con una resolución de 80x25 caracteres, color con una resolución de 80x25 caracteres y color con una resolución de 80x43/50 caracteres94. Por default la opción es: color con resolución de 80x25. General: Algunas opciones para el programa D188.EXE

• Crear archivo .MAP – El archivo MAP contiene una lista de todas las etiquetas, constantes y procedimientos95, que se emplearon en el archivo fuente. El archivo es generado después de ensamblar el código fuente, y es muy útil para saber en que posición del programa esta cierta parte de código al momento de depurar.

• Verificar conexión – Si esta casilla esta activa, al iniciar el programa D188.EXE, este verificara el estado de la UAMI188EB.

Recuerde que algunas opciones necesitan de reiniciar el programa D188.EXE

para que los cambios hechos surtan efecto. Por otra parte, todas estas opciones están almacenadas en el archivo de configuración D188.OPT, por lo que se recomienda que este archivo se encuentre en el mismo directorio donde se localiza D188.EXE. Si el programa no encuentra el archivo de configuración, se activaran las opciones con sus valores por default. Es posible ejecutar D188.EXE con las opciones por default, para ello basta ejecutar el programa con el argumento /D.

A.3.3 Búsqueda

93 Es importante hacer notar, que el buffer para volcado de memoria y el buffer de depuración son distintos; aun cuando pueden compartir los mismos datos. 94 Si esta última opción esta activada, se puede ejecutar el programa D188.EXE con una resolución de 50x80 o 43x80, ello depende de la PC. 95 En general, una etiqueta y el nombre de un procedimiento tienen el mismo significado.

Page 114: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

107

Los comandos de Búsqueda sólo

afectan a las ventanas de edición, y proporcionan herramientas para localizar texto. Los comandos son los siguientes:

Figura A.8 menú Buscar.

• Buscar – Presenta el cuadro de diálogo donde se define el texto a buscar, Fig. A.9.

• Remplazar – Presenta el cuadro de diálogo donde se definen los textos que intervienen y se dan las especificaciones para el reemplazo, Fig. A.10.

• Buscar de nuevo – Una vez definido el texto en el comando Buscar, para una segunda búsqueda del mismo texto, no es necesario llamar de nuevo al cuadro de diálogo de Buscar, esta opción buscara el texto definido con anterioridad.

Figura A.9 Cuadro de diálogo de Buscar.

Figura A.10 Cuadro de diálogo de Remplazar.

Las opciones en los cuadros de diálogo de la Fig. A.9 y Fig. A.10 son:

• Mayúsculas/Minúsculas – Si esta casilla esta activada, el texto a buscar deberá coincidir exactamente como se coloca en la línea de captura Texto a buscar, en este caso, no es lo mismo buscar Texto1 que TexTo1.

• Sólo palabra completa – Si la casilla esta activada, el buscador sólo localizara palabras completas; es decir, buscar Tex en Texto1 no podrá localizarse.

• Preguntar al reemplazar – Si esta activada, solicitara confirmación antes de intercambiar los textos antes definidos.

• Reemplazar todo – Si la casilla esta desactivada, sólo intercambiará la primera ocurrencia de la palabra; en otro caso, se continua con todo el documento en el editor.

A.3.4 Compilar

Este menú proporciona acceso a los comandos que ensamblaran el archivo fuente y generar el ejecutable o archivo en código maquina. Los comando son los siguientes:

Page 115: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

108

• Compilar a disco – Ensambla el archivo actual en el editor, en caso de no ocurrir ningún error, genera el archivo con el nombre del actual en el editor, pero con extensión .COM.

• Compilar a memoria – Ensambla el archivo actual en el editor, en caso de no ocurrir ningún error, carga el código en la memoria del depurador, no genera ningún archivo.

• Archivo primario – Es de ayuda cuando se tienen muchos archivos, y uno de estos es el de entrada para ensamblar, este es precisamente el archivo primario; al ensamblar a memoria o disco, si se ha seleccionado un archivo primario, este será el ensamblado, no se toma en cuenta otro archivo en el editor.

• Cerrar primario – Cierra el archivo primario, y con esto, al ensamblar un archivo, siempre se tomara el actual en edición.

Figura A.11 menú Compilar.

El compilar directamente a memoria tiene la ventaja de que el programa esta listo para se enviado a la UAMI188EB, además de que la compilación resulta más rápida.

A.3.5 UAMI188EB

En este submenú, están contenidos todos los comandos para la trabajar con la UAMI188EB, Fig. A.12. Los comandos son:

• Verificar conexión – Establece conexión con la UAMI188EB y solicita el estado para mostrarlo en el icono de estado.

• Reiniciar UAMI188 – Reinicia la UAMI188EB (reset) y espera a que ésta este lista.

• Seleccionar programa a cargar – Esta opción permite seleccionar el programa que se cargara en un futuro a la UAMI188EB.

• Volcado de memoria – Solicita a la UAMI188EB N número de bytes, y estos son transferidos al buffer de volcado de memoria.

• Mover memoria – Solicita a la UAMI188EB mover N bytes de memoria a otra

dirección; el mover no afecta los datos de origen.

• Leer registros – Solicita a la UAMI188EB el valor de cada uno de los registros que se encuentran en el microprocesador; estos valores se muestran en la ventana de depuración.

• Leer programa – Lee el código dentro de alguna dirección de memoria en la UAMI188EB y lo carga al buffer de depuración; de esta forma el código esta listo para ejecutarse.

Page 116: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

109

• Cargar programa seleccionado – Se carga el programa seleccionado con el comando Seleccionar programa a cargar a la UAMI188EB; además también se carga al buffer de depuración96.

• Cargar programa del depurador – Traslada código del buffer de depuración a la UAMI188EB y lo deja listo para ejecutarse.

• Reinicia el puerto serie – Reinicia el puerto serie de la PC; sólo se emplea en casos de que exista un error en la comunicación.

Figura A.12 menú UAMI188EB.

El comando Seleccionar programa a cargar, presenta un cuadro de diálogo como el que se muestra en la Fig. A.3, sólo que aquí solicita programas con la extensión COM. En general es posible seleccionar otros archivos que no sean .COM, pero dichos archivos deben pertenecer a programas válidos que pueden ser ejecutados en la UAMI188EB. Al seleccionar Volcado de memoria, se presenta el cuadro de diálogo mostrado en la Fig. A.13, en este cuadro se observan líneas de captura para el Segmento y Offset donde se inicia la lectura de memoria en la UAMI188EB y el número de bytes que se leerán. Observe que Segmento y Offset tienen el texto (H), esto indica que el número a capturar esta en hexadecimal97; en cambio el número de bytes es capturado en decimal.

96 Todos los programas cargados a la UAMI188EB se ubican a partir de la dirección 0070:0000H. 97 La línea de captura automáticamente evita que se pueden teclear otros caracteres, cuando se trata de números; es decir, si la línea de captura es para números en hexadecimal, sólo se aceptaran los dígitos del 0 al 9 y las letras A a F.

Page 117: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

110

Figura A.13 Cuadro de diálogo para Volcado de memoria.

El comando Mover memoria también ofrece un cuadro de diálogo, Fig. A.14. En este caso, se presentan 5 líneas de captura, Segmento y Offset de inicio, Segmento y Offset destino y el Número de bytes a mover de la dirección origen a la dirección destino. Nuevamente, en segmento y el offset se espera un número en hexadecimal, mientrás que el numero de bytes es un número en decimal.

Figura A.14 Cuadro de diálogo para Mover memoria.

El comando Leer programa muestra un cuadro de diálogo (Fig. A.15), solicitando el segmento y el offset donde se localiza el programa, y el número de bytes que mide el programa. Esta acción prepara al depurador y a la UAMI188EB para que sea posible ejecutar el programa desde la dirección que se especificó98. Se debe tener cuidado de lo que se solicita a la UAMI188EB, ya que puede ser cargado como un programa, cualquier localidad de memoria de la UAMI188EB.

98 El programa que se carga del depurador a la UAMI188EB esta colocado desde la dirección 0070:0000H; si se carga un programa de la UAMI188EB al depurador, este programa se ejecuta desde donde se ubica y no en la dirección 0070:0000H

Page 118: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

111

Figura A.15 Cuadro de diálogo para Leer programa.

Cuando se carga un programa del depurador a la UAMI188EB, sólo se necesita el offset inicial y final dentro de la memoria del depurador; sin embargo, cuando el programa es ensamblado con el programa D188.EXE, estos valores se fijan automáticamente, que en general van desde 0000H hasta el número de bytes del programa generado.

Figura A.16 Comando Carga programa del depurador.

A.3.6 Depuración

En este submenú se encuentras los comandos que ayudaran a depurar un programa para corregirlo o mejorarlo. Los comandos son los siguientes:

Figura A.17 Comandos de Depuración.

• Cargar programa al depurador - Carga un programa a la memoria del depurador, este comando no carga el programa a la UAMI188EB, sólo transfiere el código al buffer del depurador; pero es posible transportar el código a la UAMI188EB con el comando Carga programa del depurador.

• Define lectura de memoria - Al momento de ejecutar instrucción por instrucción un programa (trazado), el D188.EXE después de cada instrucción

Page 119: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

112

ejecutada, solicita el valor de los registros en la UAMI188EB y en dado caso, el valor de un cierto rango de memoria. El solicitar la lectura de memoria, permite al programador no sólo ver el comportamiento de los registros, sino también el comportamiento de algunas localidades de memoria. Se recomienda que el tamaño de memoria que se va a leer sea pequeño, ya que esta acción se realiza por cada instrucción ejecutada.

• Ejecutar - Ejecuta un programa cargado en la UAMI188EB; después de ejecutar un programa, este continúa hasta su terminación o cuando se aplica el comando Detener ejecución.

• Ejecutar paso a paso - Este es el trazado de un programa, cada vez que se llama a este comando, en la UAMI188EB se ejecuta una sola instrucción; para más detalles ver Sección A.5.

• Agregar instrucción - Con este comando es posible modificar una instrucción en el buffer del depurador; los cambios no surten efecto en la UAMI188EB.

• Cambiar registro - Al seleccionar un registro en la ventana de depuración, es posible cambiar su valor por otro; en este caso, los cambios se ven reflejados en la UAMI188EB. No es posible cambiar el registro CS.

• Cambiar valor de memoria - Este comando afecta el contenido de cierto número de localidades de memoria en la UAMI188EB; si estas localidades están mapeadas en el buffer de volcado, no se verán aquí los cambios.

• Abrir mapa de referencias - Abre el archivo en donde están todas las direcciones de las etiquetas y procedimientos; y los valores de las constantes. Este archivo es importante para localizar un cierto valor o código dentro de la memoria del depurador.

EL comando para definir lectura de memoria, presenta un cuadro de diálogo,

como el que se muestra en la Fig. A.18.

Figura A.18. Cuadro de diálogo del comando

Define lectura de memoria.

Después de que la UAMI188EB haya ejecutado una instrucción, el programa leerá el contenido de los registros y si la casilla de Activar lectura esta señalada, el programa también leerá N bytes desde la dirección Segmento: Offset dados en el cuadro de diálogo. Es importante señalar que recomienda un número de bytes pequeño, para que el proceso no sea demasiado largo.

Si la ventana de depuración se encuentra activa, es posible cambiar el contenido de los registros o agregar/cambiar una instrucción. Para cambiar el contenido de un registro, sólo basta con posicionarse en el registro deseado, excepto

Page 120: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

113

el registro CS, y ejecutar el comando Cambiar registro. La Fig. A.20 muestra el cuadro

de diálogo para el cambio, en donde además se muestra el valor actual. El cambio de valor de un registro, afecta inmediatamente los registros de la UAMI188EB.

Figura A.19 Cuadro de diálogo para agregar o

cambiar un instrucción.

Figura A.20 Cambio de valor de un registro.

Para cambiar o agregar una instrucción es necesario posicionarse sobre la

instrucción en la ventana del depurador, y seleccionar el comando Agregar instrucción.

Al hacer lo anterior, se muestra un cuadro de diálogo como el de la Fig. A.19, en donde se teclea la nueva instrucción; observe que la casilla de Insertar instrucción debe estar activa si se desea conservar todo el código y simplemente agregar la instrucción desde la posición señalada. Los cambios o modificaciones que se realicen, no modifican la memoria de la UAMI188EB, por lo que el usuario debe cargar de nuevo el programa en la UAMI188EB; al hacer esto, se reinicia el programa cargado en la UAMI188EB.

Es posible cambiar de valor algunas localidades de memoria; el comando que

realiza esta acción es Cambiar valor en memoria. El cuadro de diálogo para este comando esta en la Fig. A.21; se debe fijar el segmento y offset desde donde se cambiará el valor, y en la línea de captura Valor, se teclean los nuevos valores en hexadecimal y sin separaciones. Por ejemplo, se desean cambiar 5 bytes en la memoria de la UAMI188EB por los valores: 01H, 10H, 05H, 0FH y 15H; entonces la cadena de valores se establece como 0110050F15. En otras palabras, cada dos caracteres, representan un byte de memoria.

Figura A.21 Para sustituir el valor de algunas localidades en memoria.

Page 121: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

114

A.3.7 Ventanas

Los comandos en este submenú afectan a todas la ventanas dentro de la UAMI188EB, ver Fig. A.22. Los comandos son:

• Tamaño/mover - Cambia el tamaño o mueve una ventana. Al seleccionar este comando, para mover la ventana simplemente se presionan las teclas de dirección; si se busca cambiar de tamaño, se presiona SHIFT más las teclas de dirección, al presionar ENTER se fijan los cambios; presionar ESC se cancelan los cambios.

• Zoom - Maximiza la ventana a todo el tamaño de la pantalla.

• Mosaico - Organiza las ventanas, de tal forma que todas estén a la vez en pantalla, ver Fig. A.23.

• Cascada - Organiza las ventanas, de tal forma que sólo una se ve completamente en pantalla, junto con los títulos de las demás, ver Fig. A.24.

• Siguiente - Cuando hay dos o más ventanas, este comando permite navegar entre ellas, pasando de una a otra. El orden que se sigue es: de la ventana más antigua a la más actual.

• Anterior - Al igual que Siguiente, este comando permite navegar entre las ventanas, pero en un orden contrario al de Siguiente.

• Cerrar todo - Cierra todas las ventadas del programa D188.EXE. • Mensajes - Muestra la ventana de Mensajes.

• Depuración - Muestra la ventana de Depuración.

• Acerca de - Presenta un cuadro de diálogo, donde se muestran los créditos del programa D188.EXE.

Figura A.22 Comandos de Ventanas.

Page 122: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

115

Figura A.23 Organización de las ventanas en cascada.

Figura A.24 Organización de las ventanas en mosaico.

A.4 Programación99 El lenguaje que maneja el programa D188.EXE es el Lenguaje ensamblador para

8086/8088 y para 80188. Son aceptadas todas las instrucciones de este lenguaje, más otras que se han denominado palabras reservadas del D188.EXE (PRD). Los ensambladores más comunes son el TASM de Borland y el MASM de Microsoft, ambos manejan un esquema un tanto similar; el esquema aquí empleado

99 El manual no pretende enseñar el lenguaje ensamblador, para ello el usuario tendrá que recurrir a otros textos.

Page 123: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

116

es un poco diferente. Los cambios en realidad no son fuertes, pero si hay que tomarlos en cuenta cuando se desea compilar un programa en el D188.EXE. Al igual que el TASM y el MASM lo números que el D188.EXE acepta son: en decimal, binario y hexadecimal; para cada uno de ellos existe una cierta sintaxis: Numero (12856) Comentario

12856 Este es el número en decimal.

11001000111000B El mismo número pero en binario, observe que finaliza con la letra B.

3238H Finalmente el número en hexadecimal, observe que finaliza en H. Si el primer carácter es una letra, se debe anteponer un 0.

Tabla A.1 Números aceptados en el ensamblador del D188.EXE

A.4.1 Palabras reservadas del D188.EXE

La siguiente tabla muestra las palabras reservadas del D188.EXE, algunas de estas palabras son también empleadas por los ensambladores TASM y MASM, pero se emplean en diferente forma o tienen otro significado.

Palabra reservada

Descripción

DB Define un byte o un conjunto de bytes; la sintaxis es: DB ARG, ARG, ARG, ... Donde ARG es un número en hexadecimal, decimal o binario, o una cadena de caracteres encerrada entre comillas.

DW Define una word; la sintaxis es: DW ARG, ARG, ARG, ... Donde ARG es un numero en hexadecimal, decimal o binario.

ORG Fija, a partir del punto de la declaración, un nuevo offset; el espacio entre el punto de la declaración y el nuevo offset, es rellenado con 0’s, su sintaxis: ORG OFFSET

EQU Define una constante, la sintaxis es: CONSTANTE EQU VALOR

INCLUDE Le informa al ensamblador que compile el archivo que tiene como argumento, su sintaxis es: INCLUDE “RUTA_NOMBRE_ARCHIVO”

Esta palabra es muy útil en grandes programas y se desea darles una estructura.

SETREF Fija al inicio del programa el nuevo offset; esta instrucción sólo puede ser usada antes de declarar cualquier instrucción, su sintaxis es: SETRET OFFSET

Page 124: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

117

PROC Define un procedimiento.

ENDP Le indica al ensamblador el fin del procedimiento, es opcional.

P8086 Habilita al ensamblador para que reconozca instrucciones para un procesador 8086/8088; esta opción es por default.

P80186 Habilita al ensamblador para que reconozca instrucciones del 80186/80188 o inferior.

Tabla A.2 Conjunto de palabras reservadas del programa D188.EXE

A.4.2 Esquema de programación

Un programa en ensamblador para el D188.EXE esta constituido principalmente de procedimientos, constantes y etiquetas. Los nombres de los procedimientos y las etiquetas son lo mismo para el ensamblador del programa D188.EXE. El esquema propuesto para el D188.EXE es el mostrado en la Fig. A.25.

Figura A.25 Esquema propuesto de

programación.

Este esquema no es estricto; sin embargo, se recomienda que el usuario lo adopte para una mejor organización de sus programas. En las opciones para ensamblar se define el tipo de procesador y el offset donde inicia el programa100, si no se define tipo de procesador ni offset, por default se toma procesador 8086/8088 y el offset será 0000H. La sección de código principal es la entrada al programa, y no requiere de instrucciones especiales.

En la sección de variables y procedimientos se definen todos los procedimientos y variables que el programa emplee, las variables se declaran con la instrucción DB o DW. Para una mejor organización, es posible crear un archivo donde se encuentre el

código principal, otro archivo para procedimientos y un archivo para variables, en esta forma, dentro del archivo de código principal se llama a los archivos restantes con la instrucción INCLUDE. A.4.3 Declaración de constantes

Las constantes se definen con ayuda de la PRD EQU. Por ejemplo,

supongamos que deseamos crear una constante con el valor de 100H, el código seria:

100 El offset donde inicia el programa, para la UAMI188EB deberá ser cero, o en su caso no definirlo; para archivos .COM, que son ejecutados bajo MS-DOS el offset debe ser 0100H.

Page 125: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

118

MI_CONSTANTE EQU 100H

Los nombres de etiquetas, procedimientos y constantes, pueden estar hechos de caracteres alfanuméricos101 y símbolos como son -, y _. El ensamblador hace diferencias entre mayúsculas y minúsculas; es decir, no es lo mismo Constante_1 que ConstantE_1. Es posible usar otros caracteres, el ensamblador no limita en ese sentido, pero el código se puede prestar a confusión. Las constantes pueden ser declaradas antes o después de ser usadas, no existe ninguna restricción; sin embargo, para evitar que el código sea difícil de leer se recomienda declararlas al principio o llevar un orden lógico. Otra característica de las constantes es que pueden ser anidadas; es decir, asignar a una constante el valor de otra, por ejemplo:

OTRA_CONSTANTE EQU MI_CONSTANTE

En este caso, el valor de OTRA_CONSTANTE será de 100H. A.4.4 Procedimientos y etiquetas

Los procedimientos son pequeñas rutinas que pueden ser llamadas por la instrucción CALL; las etiquetas son constantes que identifican una posición dentro del código. Cada procedimiento se identifica con un nombre, al que llamaremos nombre del

procedimiento. En general cada procedimiento inicia en una cierta posición dentro del código, y el nombre hace referencia a esta posición. En general un nombre de procedimiento se puede comportar como una etiqueta; el ensamblador no ofrece ninguna restricción a este hecho. Es posible declarar una etiqueta y usarla como un nombre de procedimiento; por ejemplo:

... CALL MI_ETIQUETA ... MI_ETIQUETA: ... RET

... CALL MI_ETIQUETA ... MI_ETIQUETA PROC ... RET ENDP

En ambos casos el código dará el mismo resultado; sin embargo, emplear nombres de procedimientos en saltos, puede llevar a errores graves en la ejecución del código, por lo que se sugiere emplear con cuidado esta característica.

101 El nombre no debe iniciar con un número.

Page 126: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

119

Una etiqueta se declara con el nombre seguido por :, un procedimiento se declara con su nombre, seguido de la PRD PROC, se coloca el código y se finaliza con la PRD ENDP (que es opcional).

Dentro del ensamblador, podemos usar los nombres de procedimientos o

etiquetas como si estas fueran constantes; es decir, la siguiente instrucción es totalmente valida

MOV AX, MI_ETIQUETA

En este caso, AX tendrá el offset de la etiqueta. A.4.5 Variables y cadenas

La declaración de variables están controladas por las instrucciones DB y DW, el nombre de la variable o cadena, es controlado por una etiqueta. Con DB es posible declarar cadenas y números de 1 byte; mientras que con DW sólo es posible declarar números de 2 bytes., a continuación se muestran algunos ejemplos:

Instrucción DB Instrucción DW

Declaración de una variable de una byte llamada MI_BYTE, iniciada en 0:

MI_BYTE: DB 00H

Declaración de una variable word (2 bytes) llamada MI_WORD, iniciada en 90: MI_WORD: DW 5AH

Declaración de una cadena de texto terminada en 0: MI_CADENA: DB “Esta es una cadena”, 00H

Declaración de una variable llamada MI_WORD2, que consta de 6 words (12

bytes): MI_WORD2: DW 01H, 02H, 03H, 04H, 05H, 06H

Declaración de un ARREGLO de bytes de tamaño 30 iniciada en 0: MI_ARREGLO: DB 0+30 ;INICIO+TAMAÑO

Tabla A.3 Ejemplos de declaración de variables.

Observe que es posible mezclar texto con números con la instrucción DB, pero con la instrucción DW no es posible declarar cadenas; además únicamente con la instrucción DB es posible declarar un arreglo, cuyo tamaño máximo es de 50 bytes, en el ejemplo se declarar un arreglo de tamaño 30 y se llena con 0. No es posible mezclar cadenas, números y arreglos con la instrucción DB.

Page 127: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

120

Una variable se define con una etiqueta; para usar dicha variable basta con emplear la etiqueta, por ejemplo el siguiente código asigna al registro AX el valor de la variable VAR1102: ... MOV BX, VAR1 ;BX contiene el offset de VAR1 MOV AX, [BX] ;AX = 10H … VAR1: DB 10H Con una cadena ocurre el mismo caso, la etiqueta contiene offset de dicha cadena, lo único de lo que hay que asegurarse es de que el segmento sea el adecuado. A.4.6 Empleo de varios archivos

Debido a la naturaleza del lenguaje ensamblador, los programas resultar ser muy largos, por lo que es necesario fragmentar el programa en varios archivos. La instrucción INCLUDE, permite unir todos los archivos en uno sólo al momento de

ensamblar. Por ejemplo, se tiene dos tres archivos, un archivo principal que es la entrada del ensamblador y dos archivos con procedimientos; el archivo principal es el que llama a los otros por medio INCLUDE, el código resultante es: ... INCLUDE “ARCHIVO1.ASM” INCLUDE “ARCHIVO2.ASM” … La instrucción INCLUDE hace transparente la compilación, es como tener un sólo archivo, ya que no los archivos no son ensamblados independientemente. A.4.7 Cambio de offset

En ocasiones resulta indispensable fijar una posición arbitraria en el programa. El ensamblador del D188.EXE puede crear programas que pueden ser ejecutados en cualquier PC; sin embargo, los programas que aquí se ejecutan por default inician en la posición 100H; no importa el segmento, pero el offset es default 100H. Esto resulta en un problema, ya que la etiquetas y procedimientos deben estar calculadas en base a este corrimiento. La solución es la instrucción SETREF, que fija este corrimiento, por

ejemplo en el caso anterior la instrucción es: P8086 SETREF 100H ...

102 Se asume que el segmento de datos (DS) contiene el segmento donde se localiza VAR1.

Page 128: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

121

El código anterior hace que el ensamblador calcule las etiquetas y procedimientos desde 100H; para que esto funcione, esta instrucción debe ir antes de cualquier instrucción en ensamblador, etiqueta o procedimiento. El depurador no puede determinar la base del desplazamiento, por lo que todo el código se toma en base al desplazamiento 0000H. Hay otras situaciones en que es necesario hacer más grande un programa, para colocar código en posiciones donde el tamaño del programa no lo permite, en caso de estos es el BIOS de la UAMI188EB. La ROM donde se almacena el BIOS es de 16Kb y esta colocada de tal forma que ocupa los últimos 16Kb de direccionamiento; esto es, de la dirección FC000H a la FFFFFH. Al encender la UAMI188EB esta ejecutara el código en la dirección FFFF0H, si el tamaño del BIOS no cubre hasta esa dirección, ocurrirá un error. La solución es recorrer el código hasta la posición FFFF0H y eso se logra con la instrucción ORG; de esta forma el código se vería como: ;código...

... ORG 3FF0H ...

Al encontrar el ensamblador la instrucción ORG, rellenara lo que haga falta con ceros, hasta llegar a la posición 3FF0H, para después continuar con la compilación.

A.5 Depuración de programas El proceso de depuración tiene como objetivo encontrar errores en el programa, o en el mejor de los casos, mejorar un programa. El D188.EXE permite depurar un programa una vez cargado en la UAMI188EB; para entender el proceso, se propone el siguiente ejemplo, en donde un programa contiene un error, el listado es el siguiente: ;************************************************** ************************ ;ARCHIVO: DEPURA.ASM ; ;PROGRAMA EJEMPLO PARA LA UAMI188EB (BIOS/MONITOR 1 .0.1) ;************************************************** ************************ P80186 ;Tipo de procesador a emplear ;En el inicio del programa ;CS = DS = ES = 0070H, SS = 0000H ;SP = TAMAÑO DE RAM (puede variar si hay un progr ama residente) ;************************************************** ************************ ;DECLARACION DE CONSTANTES ;************************************************** ************************ ;CODIGO PRINCIPAL

Page 129: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

122

CODIGO_PRINCIPAL PROC ;Entrada del código principal , es opcional MOV AH, 00H ;Con esto limpiamos la pantalla MOV AL, 01H ;Se fija display de 16x2 INT 10H ;Limpia pantalla CONTINUA: MOV BX, VAR1 MOV AX, [BX] MOV CX, [BX] CMP CX, 0001H JNE CONTINUA MOV AH, 4CH ;Para devolver el control al BIOS MOV AL, 00H ;código de retorno 0. INT 20H ;Termina programa ENDP ;Finaliza código principal ;************************************************** ************************ ;DECLARACION DE VARIABLES O CADENAS VAR1: DW 00H, 01H ;************************************************** ************************ ;DECLARACION DE PROCEDIMIENTOS ;************************************************** ************************

El error en el programa es que se queda en un ciclo infinito, ya que no se incrementa la variable BX. Se puede correr el programa y constatar que jamás termina, a menos que se use el comando Detener ejecución en Depuración. En lugar de

ejecutar, se llama a la ventana de depuración y se inicia el trazado.

Figura A.26 Ventana de depuración para el programa DEPURA.ASM.

Page 130: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

123

La Fig. A.26 muestra la ventana de depuración para el programa de ejemplo, observe que los registros están en sus valores iniciales, y la posición desde donde inicia la ejecución es 0000H, marcada con un cuadro a la izquierda de la dirección. Si ejecutan 3 instrucciones, con el comando Ejecutar paso a paso, la siguiente dirección será la 0009H103, ver Fig. A.27.

Figura A.27 Trazado del programa.

El valor de los registros ha cambiado según la ejecución del programa. Si se continua con el trazado, se puede observar que el programa sigue un ciclo entre las direcciones 0011H y 0006H. La variable VAR1 contiene el valor que detiene al ciclo, pero después de la dirección 0009H hay que incrementar el registro BX, para que el valor de CX sea 0001H. La corrección puede hacerse agregando la instrucción en la

ventana del depurador y cargando de nuevo a la UAMI188EB, o modificando directamente el programa. El programa corregido se muestra en la siguiente figura.

103 En realidad son 4 instrucciones, pero las instrucciones INT no cuentan; es decir, durante el trazado, cuando la siguiente instrucción a ejecutar es INT, el depurador se detendrá hasta la siguiente instrucción que no sea INT.

Page 131: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

124

Figura A.28 Programa corregido.

Al ejecutar el programa, este regresa el valor 0 al D188.EXE104. En el ejemplo sólo se vio el comportamiento de los registros, también es posible ver el comportamiento de la memoria; para ello se emplea el comando Define lectura de

memoria. Esta opción le indica al depurar que zona de memoria leer y presentarla cada vez que se ejecute una instrucción. Por otra parte, es posible definir puntos de ruptura; es decir, ejecutar el programa en forma normal, y detenerlo en ciertos puntos del código. Esto debe hacerse en forma manual con la instrucción INT3 (también funciona INT 03H), Para que el depurador detenga la ejecución del programa una cierta instrucción, basta con agregar INT3 antes de dicha instrucción. Finalmente, al depurar un programa, en todo momento podemos continuar con la ejecución normal, con sólo llamar al comando Ejecuta.

A.6 Ejemplos Se presentan ahora un serie de 6 ejemplos, se dará un breve descripción de cada uno de ellos y se presentara el código fuente. Sugerimos ya haber revisado la lista de todas la interrupciones en el apéndice B. El primer ejemplo se encuentra en el archivo HOLAMDO1.ASM, este programa presenta la cadena de texto “Hola MUNDO!” en el display por un par de segundos; este tiempo esta controlado por un ciclo con la instrucción LOOP. El código es:

104 El valor que regresa es por medio de una interrupción de software, ver apéndice B.

Page 132: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

125

;************************************************** ************************ ;ARCHIVO: HOLAMDO1.ASM ; ;PROGRAMA EJEMPLO PARA LA UAMI188EB (BIOS/MONITOR 1 .0.1) ; ;DESCRIPCION: MUESTRA UN MENSAJE ; ;************************************************** ************************ P80186 ;Tipo de procesador a emplear ;En el inicio del programa ;CS = DS = ES = 0070H, SS = 0000H ;SP = TAMAÑO DE RAM (puede variar si hay un progr ama residente) ;************************************************** ************************ ;DECLARACION DE CONSTANTES ;************************************************** ************************ ;CODIGO PRINCIPAL CODIGO_PRINCIPAL PROC ;Entrada del código principal , es opcional MOV AH, 00H ;Con esto limpiamos la pantalla MOV AL, 01H ;Se fija display de 16x2 INT 10H ;Limpia pantalla MOV AH, 03H ;Emplearemos las utilerías para impr imir una cadena MOV SI, HOLA_MUNDO ;Offset de la cadena. INT 60H ;Observe que no se necesita definir DS, ya esta asignado. MOV CX, 0FFF0H ESPERA: LOOP ESPERA ;Una espera para ver el mensaje. MOV AH, 4CH ;Para devolver el control al BIOS MOV AL, 00H ;código de retorno 0. INT 20H ;Termina programa ENDP ;Finaliza código principal ;************************************************** ************************ ;DECLARACION DE VARIABLES O CADENAS HOLA_MUNDO: ;Observe que el texto se declara con u na etiqueta DB "Hola MUNDO!", 00H ;************************************************** ************************ ;DECLARACION DE PROCEDIMIENTOS ;************************************************** ************************

El segundo programa se encuentra en el archivo HOLAMDO2.ASM, es similar al anterior, sólo que este programa emplea un temporizador interno, diferente a los que tiene el microprocesador. Este temporizador es controlado por la interrupción 1AH, y el tiempo se fija en segundos, en este caso el programa espera 10 segundos mostrando el mensaje y después termina; el código es el siguiente: ;************************************************** ************************

Page 133: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

126

;ARCHIVO: HOLAMDO2.ASM ; ;PROGRAMA EJEMPLO PARA LA UAMI188EB (BIOS/MONITOR 1 .0.1) ; ;DESCRIPCION: MUESTRA UN MENSAJE CON ESPERA ; ;EL PROGRAMA MUESTRA UN MENSAJE Y ESPERA 10 SEGUNDOS ANTES DE TERMINAR. ;ESTE PROGRAMA MUESTRA EL USO DEL TEMPORIZADOR INTERNO EN EL BIOS. ; ; ;************************************************** ************************ P80186 ;Tipo de procesador a emplear ;En el inicio del programa ;CS = DS = ES = 0070H, SS = 0000H ;SP = TAMAÑO DE RAM (puede variar si hay un progr ama residente) ;************************************************** ************************ ;DECLARACION DE CONSTANTES ;************************************************** ************************ ;CODIGO PRINCIPAL CODIGO_PRINCIPAL PROC ;Entrada del código principal , es opcional MOV AH, 00H ;Con esto limpiamos la pantalla MOV AL, 01H ;Se fija display de 16x2 INT 10H ;Limpia pantalla MOV AH, 03H ;Emplearemos las utilerías para impr imir una cadena MOV SI, HOLA_MUNDO ;Offset de la cadena. INT 60H ;Observe que no se necesita definir DS, ya esta asignado. MOV AH, 20H MOV BX, 0AH ;Se fijan 10 segundos de espera. INT 1AH ESPERA: MOV AH, 21H ;Leemos cuantos segundos faltan. INT 1AH ;En BX están los segundos restantes. PUSH AX ;Guardamos el registro AX MOV AH, 02H MOV DX, 0100H ;Colocar al cursor en Y = 1 (Ren) y X = 0 (Col) INT 10H MOV AH, 00H ;Se imprimen los segundos restantes INT 60H POP AX ;Recuperamos el valor del registro AX. AND AL, AL ;Ya se cumplió el tiempo? JZ ESPERA MOV AH, 4CH ;Para devolver el control al BIOS MOV AL, 00H ;código de retorno 0. INT 21H ;Termina programa ENDP ;Finaliza código principal ;************************************************** ************************ ;DECLARACION DE VARIABLES O CADENAS

Page 134: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

127

HOLA_MUNDO: ;Observe que el texto se declara con u na etiqueta DB "Hola MUNDO!", 00h ;************************************************** ************************ ;DECLARACION DE PROCEDIMIENTOS ;************************************************** ************************ El tercer ejemplo muestra como usar el generador de caracteres del display; el generador se controla mediante la interrupción 10H subfunción 11H. El programa

despliega el carácter Ω en toda la pantalla durante 5 segundos y después termina. El programa esta en el archivo CHAR.ASM y el código es el siguiente: ;************************************************** ************************ ;ARCHIVO: SERIE.ASM ; ;PROGRAMA EJEMPLO PARA LA UAMI188EB (BIOS/MONITOR 1 .0.1) ; ;DESCRIPCION: GENERADOR DE CARACTERES ; ;ESTE PROGRAMA GENERA EL CARACTER OMEGA Y LLENA CON ESTE MISMO EL ;DISPLAY, ESPERA 5 SEGUNDOS Y DESPUES TERMINA. ; ;************************************************** ************************ P80186 ;Tipo de procesador a emplear ;En el inicio del programa ;CS = DS = ES = 0070H, SS = 0000H ;SP = TAMAÑO DE RAM (puede variar si hay un progr ama residente) ;************************************************** ************************ ;DECLARACION DE CONSTANTES ;************************************************** ************************ ;CODIGO PRINCIPAL CODIGO_PRINCIPAL PROC ;Entrada del código principal , es opcional MOV AH, 00H ;Con esto limpiamos la pantalla MOV AL, 01H ;Se fija display de 16x2 INT 10H ;Limpia pantalla MOV AH, 11H MOV DL, 00H MOV BP, NUEVO_CARACTER INT 10H ;Se fija nuevo caracter. MOV CX, 01FH IMPRIME: ;Se va imprimir 31 veces MOV AH, 0EH XOR AL, AL INT 10H LOOP IMPRIME MOV AH, 20H MOV BX, 05H ;Se fijan 5 segundos de espera.

Page 135: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

128

INT 1AH ESPERA: MOV AH, 21H ;Leemos cuantos segundos faltan. INT 1AH ;En BX están los segundos restantes. AND AL, AL ;Ya se cumplió el tiempo? JZ ESPERA MOV AH, 4CH ;Para devolver el control al BIOS MOV AL, 00H ;código de retorno 0. INT 21H ;Termina programa ENDP ;Finaliza código principal ;************************************************** ************************ ;DECLARACION DE VARIABLES O CADENAS NUEVO_CARACTER: ;Esta es la letra Omega mayúscula. DB 00000000B ;Observe que los bits 7-5 no tienen DB 00000000B ;Ninguna utilidad; para una mejor DB 00001110B ;comprensión, consulte el manual DB 00010001B ;del display. DB 00010001B DB 00001010B DB 00011011B DB 00000000B ;************************************************** ************************ ;DECLARACION DE PROCEDIMIENTOS ;************************************************** ************************

El cuarto programa prepara el camino para el siguiente, muestra como usar el puerto serie sin que el programa D188.EXE intervenga. El puerto serie es empleado por D188.EXE para intercambiar información con la UAMI188EB, pero es posible “desconectar” la UAMI188EB, pero informando al D188.EXE este suceso; para ello, se emplea la interrupción 60H subfunción 10H. Al desconectar la UAMI188EB, el programa D188.EXE ya no enviara información105, pero estará en espera de recibir, básicamente espera a que la UAMI188EB envié el comando de conexión; durante este tiempo es posible desconectar la UAMI188EB y conectar otro programa para su comunicación. El programa se llama COMM.ASM y se muestra a continuación: ;************************************************** ************************ ;ARCHIVO: COMM.ASM ; ;PROGRAMA EJEMPLO PARA LA UAMI188EB (BIOS/MONITOR 1 .0.1) ; ;DESCRIPCION: MUESTRA EL USO DE LAS COMUNICACIONES CON EL DEPURADOR ; ;ESTE PROGRAMA SE DESCONECTA CON EL DEPURADOR POR 15 SEGUNDOS. ;EL OBJETIVO ES QUE EN ESE LAPSO DE 15 SEGUNDOS SE PUEDE RECIBIR INFORMACION ;POR EL PUERTO SERIE, PERO DE OTRO PROGRAMA Y NO DE L DEPURADOR. ;DESPUES DE 15 SEGUNDOS SE RESTABLECEN LA COMUNICION CON EL DEPURADOR.

105 Aun cuando envié información, la UAMI188EB no contestara.

Page 136: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

129

; ;************************************************** ************************ P80186 ;Tipo de procesador a emplear ;En el inicio del programa ;CS = DS = ES = 0070H, SS = 0000H ;SP = TAMAÑO DE RAM (puede variar si hay un progr ama residente) ;************************************************** ************************ ;DECLARACION DE CONSTANTES ;************************************************** ************************ ;CODIGO PRINCIPAL CODIGO_PRINCIPAL PROC MOV AH, 00H ;Con esto limpiamos la pantalla MOV AL, 01H ;Se fija display de 16x2 INT 10H ;Limpia pantalla MOV AH, 03H ;Emplearemos las utilerías para impr imir una cadena MOV SI, DESCONECTANDO ;Offset de la cadena. INT 60H ;Observe que no se necesita definir DS, ya esta asignado. MOV AH, 20H MOV BX, 0FH ;Se fijan 15 segundos de espera. INT 1AH MOV AH, 10H MOV AL, 00H ;Desconectando con el depurador. INT 60H ESPERA: ;código para recibir información .............. MOV AH, 21H ;Leemos cuantos segundos faltan. INT 1AH ;En BX están los segundos restantes. AND AL, AL ;Ya se cumplió el tiempo? JZ ESPERA MOV AH, 10H MOV AL, 01H ;Restableciendo la comunicación. INT 60H MOV AH, 03H ;Emplearemos las utilerías para impr imir una cadena MOV SI, CONECTADO ;Offset de la cadena. INT 60H ;Observe que no se necesita definir DS, ya esta asignado. MOV CX, 0FFF0H ESPERA1: LOOP ESPERA1 ;Una espera MOV AH, 4CH ;Para devolver el control al BIOS MOV AL, 00H ;código de retorno 0. INT 21H ;Termina programa ENDP ;Finaliza código principal ;************************************************** ************************

Page 137: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

130

;DECLARACION DE VARIABLES O CADENAS DESCONECTANDO: ;Observe que el texto se declara co n una etiqueta DB "Desconectado.", 0DH, 00h CONECTADO: DB "Conectado.", 00h ;************************************************** ************************ ;DECLARACION DE PROCEDIMIENTOS ;************************************************** ************************

El siguiente programa completa el programa anterior; en este caso después de la desconexión con el D188.EXE, hay que salir del programa y ejecutar el programa SERIE.EXE, este programa envía las teclas presionadas en la PC a la UAMI188EB, los caracteres se muestran en el display; se inicia la comunicación presionando la tecla A y se finaliza con la tecla Z. Los archivos empleados son SERIE.ASM y SERIE.C106, el código es: ;************************************************** ************************ ;ARCHIVO: SERIE.ASM ; ;PROGRAMA EJEMPLO PARA LA UAMI188EB (BIOS/MONITOR 1 .0.1) ; ;DESCRIPCION: COMUNICACIONES POR PUERTO SERIE CON LA PC ; ; ; ; ; ;************************************************** ************************ P80186 ;Tipo de procesador a emplear ;************************************************** ************************ ;DECLARACION DE CONSTANTES CHAR_INICIO EQU 65 ;Caracter de inicio A. CHAR_FIN EQU 90 ;Caracter de fin Z. ;En el inicio del programa ;CS = DS = ES = 0070H, SS = 0000H ;SP = TAMAÑO DE RAM (puede variar si hay un progr ama residente) ;************************************************** ************************ ;CODIGO PRINCIPAL CODIGO_PRINCIPAL PROC ;Entrada del código principal , es opcional MOV AH, 00H ;Con esto limpiamos la pantalla MOV AL, 01H ;Se fija display de 16x2

106 Hay que compilar este código en un compilador de lenguaje C.

Page 138: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

131

INT 10H ;Limpia pantalla MOV AH, 03H ;Emplearemos las utilerías para impr imir una cadena MOV SI, DESCONECTANDO ;Offset de la cadena. INT 60H ;Observe que no se necesita definir DS, ya esta asignado. MOV AH, 10H MOV AL, 00H ;Desconectando con el depurador. INT 60H MOV AH, 00H MOV AL, 11100011B ;Vel 9600, sin paridad, 8 bits. XOR DX, DX INT 63H ESPERA1: MOV AH, 02 ;Leemos el puerto. XOR DX, DX ;COM1 INT 63H AND AH, 80H ;Prueba el bit 7 JNZ ESPERA1 CMP AL, CHAR_INICIO ;Compara con el caracter de i nicio. JNE ESPERA1 MOV AH, 00H MOV AL, 01H INT 10H ;Borramos la pantalla ESPERA2: MOV AH, 02 ;Leemos el puerto. XOR DX, DX ;COM1 INT 63H TEST AH, 80H ;Prueba el bit 7 JNZ ESPERA2 CMP AL, CHAR_FIN ;Si es caracter terminal, sale. JE TERMINA MOV AH, 0EH ;En AL esta el caracter. INT 10H ;Escribe el caracter recibido en el disp lay. JMP ESPERA2 TERMINA: MOV AH, 10H MOV AL, 01H ;Restableciendo la comunicación. INT 60H MOV AH, 03H ;Emplearemos las utilerías para impr imir una cadena MOV SI, CONECTADO ;Offset de la cadena. INT 60H ;Observe que no se necesita definir DS, ya esta asignado.

Page 139: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

132

MOV AH, 4CH ;Para devolver el control al BIOS MOV AL, 00H ;código de retorno 0. INT 21H ;Termina programa ENDP ;Finaliza código principal ;************************************************** ************************ ;DECLARACION DE VARIABLES O CADENAS DESCONECTANDO: ;Observe que el texto se declara co n una etiqueta DB "Desconectado y", 0DH, "esperando.", 00h CONECTADO: DB "Conectado.", 00h ;************************************************** ************************ ;DECLARACION DE PROCEDIMIENTOS ;************************************************** ************************ /*PROGRAMA SERIE.C */ /*CONTIENE EL CODIGO PARA EL MANEJO DEL PUERTO SERI E*/ /*EL PUERTO SERIE MANEJA UNA INTERRUPCION PERO UNIC AMENTE RECEPCION*/ #include <lib.h> #include <stdio.h> #include <dos.h> #include <bios.h> #include <conio.h> /*Los puertos*/ #define COMM1 0 /*Puerto COM 1*/ #define COMM2 1 /*Puerto COM 2*/ #define DIRCOM1 0x03F8 /*Dirección del puerto COM1 */ #define DIRCOM2 0x02F8 /*Dirección del puerto COM2 */ #define IRQCOM1 0x04 /*IRQ para COM1*/ #define IRQCOM2 0x03 /*IRQ para COM1*/ /*Selección de bit de paridad y bit de parada*/ #define COM_SINPARIDAD 0x00 /*Sin paridad*/ #define COM_PARIDADPAR 0x18 /*Con paridad p ar*/ #define COM_PARIDADIMPAR 0x08 /*Con paridad i mpar*/ #define COM_PARIDADPARSTICK 0x38 /*Paridad par c on stick bit*/ #define COM_PARIDADIMPARSTICK 0x28 /*Paridad impar con stick bit*/ #define COM_STOPBIT 0x04 /*1 bit de para da*/ #define COM_NOSTOPBIT 0x00 /*0 bit de para da*/ /*Numero de bits*/ #define COM_6_BITS 6 #define COM_7_BITS 7 #define COM_8_BITS 8 /*Estas son algunas constantes para acceder a los registros de la UART*/ #define RBR 0 #define THR 0 #define IER 1 #define IIR 2 #define FCR 2 #define LCR 3

Page 140: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

133

#define MCR 4 #define LSR 5 #define MSR 6 #define SCR 7 #define DLL 0 #define DLM 1 #define BASE_IRQ 8 /*Se le agrega a la interrupc ión ya que es IRQ+8*/ /*Velocidad del puerto*/ #define COMVEL_1200 0 #define COMVEL_2400 1 #define COMVEL_4800 2 #define COMVEL_9600 3 #define COMVEL_19200 4 /*Algunas variables globales*/ word wDirPuerto; /*Dirección del puerto*/ byte bNumIRQ; /*Numero de interrupción IRQ + BASE _IRQ*/ void vIniciaPuertoSerie (byte bCOM, byte bNumBits, byte bStopBits, byte bParidad, byte bVel); void vTerminaPuertoSerie (void); byte bEnviaDato (byte bDato); /*Envía dato*/ byte bRecibeDato (byte *pbDato); /*Recibe dato s in interrupción*/ void vLimpiaPuerto (); /*Limpia el puerto de basu ra*/ byte bLeeEstado (); /*Estado del puerto serie*/ void vIniciaPuertoSerie (byte bCOM, byte bNumBits, byte bStopBits, byte bParidad, byte bVel) /*Inicia el puerto serie, inhabilita las interru pciones*/ int iDiv; long lVelocidad; byte bLCR, bAux; switch (bCOM) /*Coloca el puerto, por default es COM1*/ case COMM2: wDirPuerto = DIRCOM2; bNumIRQ = IRQCOM2; break; default: case COMM1: wDirPuerto = DIRCOM1; bNumIRQ = IRQCOM1; break; /*Ya tenemos los puertos*/ outportb (wDirPuerto+IER, 0x00); /*Deshabilita interrupciones en la UART*/ switch (bVel) case COMVEL_1200: lVelocidad = 1200; break ; case COMVEL_2400: lVelocidad = 2400; break ; case COMVEL_4800: lVelocidad = 4800; break ; case COMVEL_19200: lVelocidad = 19200; break ; default: case COMVEL_9600: lVelocidad = 9600; break;

Page 141: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

134

iDiv = (int)(1843200/(16*lVelocidad)); /*Calcul a la velocidad*/ outportb (wDirPuerto+LCR, 0x80); /*Para acceder al divisor (DLAB)*/ outport (wDirPuerto+DLL, iDiv); /*La fija*/ if ((bNumBits<5)||(bNumBits>8)) bNumBits = 8; / *Por default son 8*/ bLCR = bNumBits - 5; /*Se va colocar los bits d e paridad, stop, etc*/ bLCR = bLCR | bParidad | bStopBits; /*Coloca la paridad y bit de parada*/ outportb (wDirPuerto+LCR, bLCR); /*Coloca los v alores en el registro LCR*/ outportb(wDirPuerto+FCR, 0x00); /*Desactiva la característica FIFO*/ while (bRecibeDato(&bAux)); /*Quitamos la basur a*/ bAux = inportb (wDirPuerto+LSR); bAux = inportb (wDirPuerto+MSR); bAux = inportb (wDirPuerto+IIR); void vTerminaPuertoSerie () outportb (wDirPuerto+IER, 0); /*Desactiva inter rupción*/ outportb (wDirPuerto+MCR, 0); /*Desactiva Out2* / outportb (wDirPuerto+LCR, 0); /*Desactiva LCR*/ inportb (wDirPuerto+LSR); inportb (wDirPuerto+IIR); inportb (wDirPuerto+MSR); byte bEnviaDato (byte bDato) /*Retorna TRUE en caso de envío*/ byte bAux; bAux = inportb (wDirPuerto+LSR); /*Verificamos si hay error*/ if (bAux&0x0E) bAux = inportb (wDirPuerto+LSR); /*Lo leemos de nuevo*/ if (!TSTBITN(bAux, 5)) return (FALSE); outportb (wDirPuerto+THR, bDato); return (TRUE); byte bRecibeDato (byte *pbDato) /*Retorna TRUE en caso de recepción (NO usa inte rrupción)*/ byte bAux; bAux = inportb (wDirPuerto+LSR); if (bAux&0x0E) bAux = inportb (wDirPuerto+LSR); /*Lo leemos de nuevo*/ if (!TSTBITN(bAux, 0)) return (FALSE); *pbDato = inportb (wDirPuerto+RBR); return (TRUE); void vLimpiaPuerto () byte bAux; while (bRecibeDato(&bAux)); /*Quitamos la basur a*/ byte bLeeEstado () byte bAux;

Page 142: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

135

bAux = inportb (wDirPuerto+LSR); return (bAux); void main () word wKey; byte bChar; clrscr (); vIniciaPuertoSerie (COMM2, COM_8_BITS, COM_NOSTO PBIT, COM_SINPARIDAD, COMVEL_9600); printf ("Presione A para iniciar y Z para termin ar la comunicación.\n\n"); bChar = 0; while (bChar!=65) /*Inicia con A*/ wKey = bioskey (1); if (wKey) bChar = ((byte)getch ()); bEnviaDato (bChar); printf ("Inicia la transferencia...\n\n"); while (bChar!=90) /*Termina con Z*/ wKey = bioskey (1); /*Sólo nos quedamos con el caracter*/ if (wKey) /*Envía un dato*/ getche (); bChar = ((byte)wKey); bEnviaDato (bChar); /*Estos for es para dar tiempo a que envíe el ul timo caracter*/ for (wKey=0; wKey<0xFFF0; wKey++); for (wKey=0; wKey<0xFFF0; wKey++); for (wKey=0; wKey<0xFFF0; wKey++); vTerminaPuertoSerie ();

El último programa muestra como dejar código residente en la UAMI188EB. Esta característica permite dejar código que pueden compartir otros programas; por ejemplo, cargar una nueva interrupción de software. Cuando termina un programa, el control es pasado al BIOS para que restaure el sistema107, después el control es pasado al Monitor. Si el lugar de pasar el control al BIOS se pasa inmediatamente al Monitor, esto permite mantener código ya que el BIOS no lo “tocara”. En algunos casos no existe problema alguno y es posible dejar código, pero si este código requiere memoria, entonces es necesario dejar el control al Monitor.

107 El BIOS restaura el sistema dando un RESET, pero sin revisar la memoria.

Page 143: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

136

El programa es un reloj en el display, este reloj se actualiza por medio de la interrupción 1CH, la cual es llamada aproximadamente 24 veces en un segundo por la interrupción 12H, que es el temporizador del sistema. Se emplean dos archivos, el archivo RJ188ROM.ASM, que se carga en una ROM y se coloca en la segunda base, el código es: ;************************************************** ************************ ;ARCHIVO: RJ188ROM.ASM ; ;PROGRAMA EJEMPLO PARA LA UAMI188EB (BIOS/MONITOR 1 .0.1) ; ;DESCRIPCION: RELOJ RESIDENTE ; ;ESTE CODIGO MUESTRA LA RUTINA RESIDENTE DENTRO DEL MONITOR, ESTO SE ;LOGRA INTRODUCIENDO LA RUTINA EN LA INT 1CH. DEBE EMPLEARSE CON EL ;PROGRAMA RELOJ188.ASM. ; ; ;************************************************** ************************ P80186 ;Tipo de procesador a emplear MI_MEMORIA1 EQU 01FF0H;Tamaño de RAM reservada - 16 bytes. ;ESTA RUTINA SE ENCARGA DE MOSTRAR EL RELOJ DEBAJO DEL MENSAJE DE ;ESPERA... DEL MONITOR. ;NOTA: ESTE TIPO DE RUTINAS DEBEN DE TENER UN CODI GO MUY REDUCIDO DEL TAL ;MANERA QUE PUEDAN EJECUTARSE CON RAPIDEZ, DE ESTA FORMA PERMITIREMOS QUE ;OTRO CODIGO PUEDA EJECUTARSE, ESTA RUTINA SE LLAM A APROXIMADAMENTE 24 ;VECES EN UN SEGUNDO. RUTINA_RELOJ PROC PUSH AX ;Guarda todos los registros PUSH BX PUSH CX PUSH DX PUSH DS MOV AH, 03H INT 10H ;Lee posición del cursor. PUSH DX ;Guarda la posición. MOV AH, 02H MOV DX, 0100H INT 10H ;Posición del reloj. MOV AH, 02H INT 1AH ;Lee la hora del sistema CH=HORAS, CL=MI NUTOS, DH=SEGUNDOS ;Convierte de código BCD a texto; como cada digit o emplea 4 bits, ;simplemente transferimos de 4 en 4 bits a un reg istro de 8 bits y le ;sumamos 48; de esta forma en el registro se tien e el caracter del numero ;correspondiente. MOV AL, CH ;Estas son las horas SHR AL, 04H ADD AL, 30H PUSH AX

Page 144: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

137

MOV AH, 0EH INT 10H POP AX MOV AL, CH AND AL, 0FH ADD AL, 30H PUSH AX MOV AH, 0EH INT 10H MOV AH, 0EH MOV AL, 3AH INT 10H POP AX MOV AL, CL ;Estos son los minutos SHR AL, 04H ADD AL, 30H PUSH AX MOV AH, 0EH INT 10H POP AX MOV AL, CL AND AL, 0FH ADD AL, 30H PUSH AX MOV AH, 0EH INT 10H MOV AH, 0EH MOV AL, 3AH ;Coloca : INT 10H POP AX MOV AL, DH ;Estos son los segundos SHR AL, 04H ADD AL, 30H PUSH AX MOV AH, 0EH INT 10H POP AX MOV AL, DH AND AL, 0FH ADD AL, 30H PUSH AX MOV AH, 0EH INT 10H POP AX POP DX MOV AH, 02H INT 10H ;Restaura la posición del cursor. XOR AX, AX MOV DS, AX MOV BX, MI_MEMORIA1 PUSHF ;Ya que la instrucción IRET retorna PILA CALL FAR [BX] ;No debemos olvidar llamar al códi go de la interrupción anterior POP DS

Page 145: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

138

POP DX POP CX POP BX POP AX IRET ENDP

Y finalmente el archivo RELOJ188.ASM que es el que se encarga de dejar el reloj residente, el código es: ;************************************************** ************************ ;ARCHIVO: RELOJ188.ASM ; ;PROGRAMA EJEMPLO PARA LA UAMI188EB (BIOS/MONITOR 1 .0.1) ; ;DESCRIPCION: RELOJ RESIDENTE ; ;ESTE PROGRAMA CARGA UN RELOJ Y LO DEJA RESIDENTE D ENTRO DEL MONITOR. ;EL PROGRAMA LLAMA A UNA RUTINA PREVIAMENTE CARGADA EN LA SEGUNDA ROM, ;ESTA RUTINA ESTA EN EL ARCHIVO RJ188ROM.ASM. ; ;EL BIOS DE LA UAMI188EB INICIA UN RELOJ, EL CUAL L LAMA A LA INT 1CH ;APROXIMADAMENTE 24 VECES EN UN SEGUNDO. SE EMPLEA ESTA INTERRUPCION ;PARA PRESENTAR UN RELOJ EN PANTALLA, INTERCAMBIANDO EL CODIGO DE LA ;INT 1CH POR EL RELOJ. EL CODIGO DE LA INT 1CH ANTE RIOR ES LLAMADO ;DENTRO DEL RELOJ. ; ;UN PROGRAMA RESIDENTE EN EL MONITOR, PUEDE RESERVAR HASTA 256 BYTES ;DE MEMORIA. ESTOS BYTES SE ENCUENTRAN AL FINAL DE LA RAM, POR LO QUE ;ES NECESARIO REDEFINIR LA PILA. ; ;************************************************** ************************ P80186 ;Tipo de procesador a emplear ;************************************************** ************************ ;DECLARACION DE CONSTANTES INCLUDE "C:\EDIT188\BIOS\CONST.ASM" ;Archivo de constantes MI_MEMORIA EQU 01FF0H ;Tamaño de RAM - 16 bytes. INT_RELOJ EQU 1CH ;La interrupción del reloj es la 1CH ;En el inicio del programa ;CS = DS = ES = 0070H, SS = 0000H ;SP = TAMAÑO DE RAM (puede variar si hay un progr ama residente) ;************************************************** ************************ ;CODIGO PRINCIPAL CODIGO_PRINCIPAL PROC ;Entrada del código principal , es opcional MOV SP, MI_MEMORIA ;Primero reiniciamos la pila ;quitando el valor estimado que se v a a emplear ;en este caso, 16 bytes; este valor servirá mas ;adelante.

Page 146: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

139

MOV AH, 00H MOV AL, 01H ;Pantalla 16x2. INT 10H ;Borramos pantalla ;MOV AH, 03H ;Fijamos la hora ;MOV CH, 18H ;Horas ;MOV CL, 59H ;Minutos ;MOV DH, 00H ;Segundos ;INT 1AH MOV AH, 35H MOV AL, INT_RELOJ ;INT 1CH INT 21H ;Leemos el vector de interrupción ES:BX XOR AX, AX MOV DS, AX MOV SI, MI_MEMORIA MOV [SI], BX ;Se guarda el OFFSET INC SI INC SI MOV [SI], ES ;Ahora el SEGMENTO CLI ;Eliminamos las interrupciones MOV AX, ROM2_SEG ;Segmento donde se encuentra la segunda ROM MOV DS, AX MOV AL, INT_RELOJ ;INT 1CH MOV DX, ROM2_OFF ;Offset donde se encuentra la se gunda ROM MOV AH, 25H INT 21H ;Colocamos en el vector el código del re loj. STI MOV DX, 0001H ;Con esto se aseguran 16 bytes de memoria. INT 27H ;Termina y permanece el código residente . ENDP ;Finaliza código principal ;************************************************** ************************ ;DECLARACION DE VARIABLES O CADENAS ;************************************************** ************************ ;DECLARACION DE PROCEDIMIENTOS ;************************************************** ************************ ;************************************************** ************************ ;UNA VEZ CARGADO UN PROGRAMA RESIDENTE, LOS DEMAS PROGRAMAS DEBERAN ;FINALIZAR CON LA INT 20H EN LUGAR DE LA INT 21H. L A INT21H PASA EL ;CONTROL AL BIOS, ESTE REINICIA CASI TODO EL SISTEM A Y ELIMINA TODO ;PROGRAMA RESIDENTE. LA INT 20H PASA EL CONTROL AL MONITOR, Y SI HAY ;UN PROGRAMA RESIDENTE, PERMITE SU EJECUCION. ;ES POSIBLE QUE LO ANTERIOR NO SE APLIQUE A TODOS L OS PROGRAMAS RESIDENTES. ;************************************************** ************************

Page 147: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

140

Page 148: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

141

Apéndice B. Lista de interrupciones del BIOS.

B.1 Introducción La siguiente lista contiene una serie de interrupciones que están cargadas por default en el BIOS de la UAMI188EB; es posible usar el vector de la interrupción que no se encuentre en esta lista; sin embargo, sugerimos consultar [2] y [4] para una mejor referencia. Algunas interrupciones manejan subfunciones, cada una de estas es seleccionada mediante el registro AH; tomando en cuenta lo anterior, el formato de las interrupciones es:

Subfunción Descripción de la interrupción

Parámetros: Valores de los parámetros y algunos comentarios.

Retorno: Valores retorno y algunos comentarios.

En algunas interrupciones es necesario activarlas para que funcionen; en este caso, se asumen activas y sólo se describe la función. Finalmente, ninguna interrupción revisa los parámetros de entrada, de esta forma si los parámetros son incorrectos, es posible que el sistema no funcione adecuadamente.

B.2 Descripción de las interrupciones INT 00H Interrupción de división entre cero.

No subfunción Es llamada cuando una operación involucra una división entre cero. Envía información al depurador y regresa el control al BIOS.

Parámetros: Ninguno.

Retorno: Nada.

INT 01H Interrupción de trazado.

No subfunción Se llama después de haber ejecutado una instrucción108; informa al depurador y regresa el control al Monitor. Esta interrupción pertenece a las funciones del Monitor; puede ser sustituida, pero respetando el protocolo de comunicación con el depurador D188.EXE

Parámetros: Ninguno.

Retorno: Nada.

108 La instrucción IRET no se toma como instrucción, por lo que INT 01H se llama a la siguiente instrucción. Existen otras instrucciones con las cuales no funciona la INT 01H, se recomienda ver [4] para una mejor referencia.

Page 149: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

142

INT 03H Interrupción de punto de ruptura.

No subfunción A diferencia con la INT 01H, esta es llamada por el usuario en donde se desea que se detenga el programa para su depuración. En general realiza lo mismo que la INT 01H.

Parámetros: Ninguno.

Retorno: Nada.

INT 04H Interrupción de desbordamiento (overflow).

No subfunción Es llamada cuando ocurre un error de overflow, generalmente en operaciones que involucren números con signo. Retorna el control al BIOS e informa al depurador.

Parámetros: Ninguno.

Retorno: Nada.

INT 05H Interrupción de error de límite (bound error).

No subfunción Sucede durante la instrucción BOUND si el índice del arreglo esta fuera de los limites, consultar [4] para una mejor referencia. Retorna el control al BIOS e informa al depurador.

Parámetros: Ninguno.

Retorno: Nada.

INT 06H Interrupción de código no valido (unused opcode).

No subfunción Esta interrupción ocurre cuando se ha enviado al microprocesador un conjunto de bytes que no corresponden a una instrucción; un ejemplo es el código 0FH. Regresa el control al BIOS e informa al depurador.

Parámetros: Ninguno.

Retorno: Nada.

INT 07H Interrupción de ESC opcode (instrucción ESC).

No subfunción Es generada en la ejecución de los códigos 0D8H-0DFH (instrucción ESC), proporciona soporte a coprocesadores, consultar [4] para una mejor referencia. Retorna el control al BIOS e informa al depurador.

Parámetros: Ninguno.

Retorno: Nada.

INT 08H Interrupción del temporizador 0.

No subfunción Es llamada cada que se cumple un ciclo en el temporizador 0 cuando solo se hace una comparación, o es llamada dos veces en el ciclo cuando hay dos comparaciones.

Parámetros: Ninguno.

Page 150: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

143

Retorno: Nada.

INT 0CH Interrupción por hardware INT0.

No subfunción Es llamada cada que se recibe petición de interrupción por el pin INT0 del microprocesador.

Parámetros: Ninguno.

Retorno: Nada.

INT 0DH Interrupción por hardware INT1.

Es llamada cada que se recibe petición de interrupción por el pin INT1 del microprocesador.

Parámetros: Ninguno.

Retorno: Nada.

INT 0EH Interrupción por hardware INT2.

No subfunción Es llamada cada que se recibe petición de interrupción por el pin INT2 del microprocesador.

Parámetros: Ninguno.

Retorno: Nada.

INT 0FH Interrupción por hardware INT3.

No subfunción Es llamada cada que se recibe petición de interrupción por el pin INT3 del microprocesador.

Parámetros: Ninguno.

Retorno: Nada.

INT 10H Interrupción de display. (Valido para displays: AND491, AND481, AND471, AND501, AND731, AND721).

AH = 00H Selección del tipo de display.

Parámetros: AL = Modo del display. 00H - Display apagado. 01H - Display sin cursor 16x2 (AND491, AND481, AND471). 02H - Display sin cursor 16x4 (AND731). 03H - Display sin cursor 20x2 (AND501). 04H - Display sin cursor 20x4 (AND721). Cualquier otro valor, apaga el display.

Retorno: Nada.

AH = 01H Selección del tipo de cursor.

Parámetros: CL = Tipo de cursor. 00H – Sin cursor. 01H – Cursor parpadeando.

Page 151: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

144

02H – Cursor _. 03H – Cursor y_ parpadeando. Omite los bits 2 a 7.

Retorno: Nada.

AH = 02H Fija la posición del cursor.

Parámetros: DH = Posición Y (renglón). DL = Posición X (columna). Renglón: 0 a 1 para AND491, AND481, AND471 y AND501. Columna: 0 a 15 para AND491, AND481, AND471 y AND731. renglón: 0 a 3 para AND731 y AND721. Columna: 0 a 19 para AND501 y AND721. Cualquier otro valor, no realiza ninguna operación.

Retorno: Nada.

AH = 03H Lee la posición y el tipo de cursor.

Parámetros: Ninguno

Retorno: DH = Posición Y (renglón). DL = Posición X (columna). El resultado depende del tipo de display seleccionado, ver subfunciones 00H y 02H. CL = Tipo de cursor. Ver subfunción AH = 01H.

AH = 05H Selecciona la pagina de video activa.

Parámetros: Ninguno

Retorno: Nada. Esta subfunción no esta activada, solo es para compatibilidad.

AH = 08H Lee el carácter de la posición actual, no cambia posición del cursor.

Parámetros: Ninguno.

Retorno: AL = Carácter ASCII.

AH = 09H Escribe un carácter sin avanzar el cursor.

Parámetros: AL = Carácter ASCII. El carácter es escrito en la posición actual del cursor y no lo avanza.

Retorno: Nada

AH = 0AH Escribe un conjunto del mismo carácter desde la posición actual, avanzando el cursor.

Page 152: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

145

Parámetros: AL = Carácter ASCII. CX = Numero de caracteres a escribir.

Retorno: Nada.

AH = 0EH Escribe un carácter, avanza el cursor.

Parámetros: AL = Carácter ASCII. El carácter es escrito en la posición actual del cursor y lo avanza.

Retorno: Nada

AH = 0FH Obtiene el modo de display actual.

Parámetros: Ninguno

Retorno: AH = Numero de columnas en la pantalla. AL = Modo de display. BH = Pagina de video (siempre es cero). Estos datos se obtienen de la memoria, no es información que se pueda leer del display, ver subfunción 00H para el modo de display, y Apéndice C para los datos en memoria.

AH = 11H Generador de caracteres.

Parámetros: DL = Offset del carácter, de 0 a 7. ES:BP = Tabla de caracteres. Con esta subfunción es posible generar hasta 8 caracteres nuevos. Consultar la documentación [10] para ver la formación de un carácter.

Retorno: Nada

AH = 13H Escribe una cadena en el display.

Parámetros: AL = Modo de escritura. 00 – Cursor no se actualiza, el cursor queda fijo. 01 – Cursor se actualiza, queda al final de la cadena. CX = Longitud de la cadena. DH = renglón de inicio. DL = Columna de inicio. ES:BP Puntero a la cadena.

Retorno: Nada

INT 11H Interrupción por hardware INT4.

No subfunción Es llamada cada que se recibe petición de interrupción por el pin INT4 del microprocesador.

Parámetros: Ninguno.

Retorno: Nada.

Page 153: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

146

INT 12H Interrupción del temporizador 1.

No subfunción Es llamada con una frecuencia de 24Hz. Controla el temporizador del sistema y el reloj de tiempo real de la UAMI188EB.

Parámetros: Ninguno.

Retorno: Nada. Esta interrupción se encarga de incrementar en 1 el contador de 32 bits del temporizador, que se localiza en la dirección de memoria 0000:046CH. Además de esto, se encarga de llamar a la interrupción 1CH.

INT 13H Interrupción del temporizador 2.

No subfunción Es llamada cada que se cumple un ciclo en el temporizador 2.

Parámetros: Ninguno.

Retorno: Nada.

INT 14H Interrupción del puerto serial de recepción, canal 0.

No subfunción Es llamada cada que se recibe un dato por el puerto serial.

Parámetros: Ninguno.

Retorno: Nada.

INT 15H Interrupción del puerto serial de transmisión, canal 0.

No subfunción Es llamada cada que se transmite un dato por el puerto serial y el buffer de transmisión ha quedado vacío.

Parámetros: Ninguno.

Retorno: Nada.

INT 16H Interrupción del teclado109.

AH = 00H Lee un carácter del buffer de teclado.

Parámetros: Ninguno.

Retorno: AH = Código de escaneo. AL = Código ASCII. Lee un carácter del buffer de teclado; si el buffer esta vacío, espera hasta que se presione una tecla.

AH = 01H Lee un carácter del buffer del teclado.

Parámetros: Ninguno.

Retorno: AH = Código de escaneo. AL = Código ASCII. Lee un carácter del buffer de teclado; a diferencia de la subfunción anterior, si no hay nada en el buffer, retorna AX = 0000H, no

109 Este servicio solo maneja el buffer de teclado; es necesario usar el servicio INT 60 Subfunción 08H, ya que estas rutinas fueron construidas para una versión anterior de la UAMI188EB.

Page 154: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

147

espera a que se presione una tecla.

AH = 02H Retorna las banderas del teclado.

Parámetros: Ninguno

Retorno: AL = Banderas del teclado Los bits activos en este registro significan lo siguiente: 1 Tecla SHFT presionada. 2 Tecla CTRL presionada. 6 CAPS (mayúsculas/minúsculas).

AH = 05H Escribe en el buffer de teclado.

Parámetros: CH = Código de escaneo. CL = Carácter.

Retorno: AL = 1 si buffer esta lleno.

AH = 13H Reinicia el buffer de teclado.

Parámetros: Ninguno.

Retorno: Nada. Reinicia el buffer con las variables default, el buffer quedara vacío. No Disponible en un PC normal.

INT 19H Reset del sistema.

No subfunción Reinicia el sistema (Reset).

Parámetros: Ninguno.

Retorno: Nada.

INT 1AH Funciones del temporizador y del reloj de tiempo real del sistema.

AH = 00H Lee el reloj contador.

Parámetros: Ninguno.

Retorno: AL = Bandera de media-noche. CX = Palabra alta del contador. DX = Palabra baja del contador. Esta subfunción se encarga de leer el contador (de 32 bits) del temporizador del sistema, que finalmente funciona como un reloj para el mismo. La interrupción 12H del temporizador 1 se activa a una frecuencia de 24Hz, actualizando el contador que se encuentra ubicado en la dirección de memoria 0000:046CH; el valor de este contador es el que retorna la interrupción, además de borrar la bandera de media-noche.

AH = 01H Fija el contador del temporizador

Parámetros: AL = Bandera de media-noche. CX = Palabra alta del contador.

Page 155: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

148

DX = Palabra baja del contador.

Retorno: Nada. Esta subfunción se encarga de cambiar el valor del contador del temporizador del sistema.

AH = 02H Lee la hora en base al contador del temporizador del sistema.

Parámetros: Ninguno.

Retorno: CH = Horas. CL = Minutos. DH = Segundos. Esta subfunción, transforma el contador en el formato de horas minutos y segundos, finalmente esto es el reloj de tiempo real. Se emplea código BCD en los registros con el formato de 24 horas..

AH = 03H Fija la hora del reloj de tiempo real del sistema.

Parámetros: CH = Horas. CL = Minutos. DH = Segundos. Formato 24 horas en BCD.

Retorno: Nada. Esta subfunción, transforma las horas, minutos y segundos en el conteo del temporizador del sistema. Esta subfunción es muy semejante a la subfunción 01H. Además borra la bandera de media-noche.

AH = 20H Activa el contador de segundos.

Parámetros: BX = Numero de segundos (MAX 2000).

Retorno: AL = 1 si se activo. AL = 0 en otro caso. Esta subfunción ayuda a saber cuanto tiempo ha pasado en segundos. Cuando se ha cumplido el plazo, informa mediante la subfunción 21H.

AH = 21H Retorna el estado del contador de segundos.

Parámetros: Ninguno.

Retorno: AL = 1 Si se cumplió el tiempo. AL = 0 Si no se ha cumplido. BX = Segundos faltantes. Con la subfunción 20H se fija cuantos segundos se desean que transcurran, y con esta subfunción sabemos si el tiempo se ha cumplido o cuanto tiempo ha pasado. Si AL = 1, el valor de BX ya no es valido.

Page 156: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

149

INT 1CH Interrupción del temporizador del sistema.

No subfunción Es llamada por la INT 12H. Se agrega como complemento para programas residentes.

Parámetros: Ninguno.

Retorno: Nada.

INT 20H Tipo MS-DOS.

No subfunción Termina el programa en ejecución, retorna al depurador el código de retorno y regresa el control al Monitor. Ver interrupción 21H, subfunción 4CH.

Parámetros: AL = Código de retorno.

Retorno: Nada.

INT 21H Tipo MS-DOS. Proporciona interrupciones semejantes al servicio INT 21H del MS-DOS.

AH = 01H Entrada de teclado con ECHO.

Parámetros: Ninguno.

Retorno: AL = Carácter ASCII. Regresa la tecla presionada, espera hasta que se presione una tecla; el carácter recibido es impreso en pantalla.

AH = 02H Imprime un carácter en display.

Parámetros: DL = Carácter ASCII.

Retorno: Nada. Esta subfunción escribe un carácter en pantalla e incrementa el cursor.

AH = 09H Imprime una cadena de texto en el display.

Parámetros: DS:DX = Cadena de texto terminada en el carácter $.

Retorno: Nada.

AH = 25H Coloca un vector de interrupción.

Parámetros: AL = Número de interrupción. DS:DX = Puntero al código manejador de la interrupción.

Retorno: Nada.

AH = 30H Versión del BIOS.

Parámetros: Ninguno.

Retorno: AL = Número entero de la versión. AH = Fracción de la versión. Esta subfunción regresa la versión del MS-DOS, en este caso

Page 157: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

150

regresa la versión del BIOS, que es una localidad dentro de la EPROM, localizada en la dirección FC00:3FFC. La versión se compone de AL.AH.

AH = 35H Obtiene el vector de interrupción.

Parámetros: AL = Número de interrupción.

Retorno: ES:BX = Puntero al código de la interrupción.

AH = 4CH Detener programa con código de retorno.

Parámetros: AL = Código de retorno.

Retorno: Nada. Esta subfunción termina el programa en ejecución, regresa el control al BIOS e informa al depurador el valor de retorno. Al tomar el control el BIOS, restablece todo el sistema, algo semejante al dar un reset, pero sin verificar memoria y sin borrar el programa cargado; después regresa el control al Monitor. En AL se almacena el código que se pasa al depurador. Puede servir como una manera de saber si el programa cumplió algún cometido.

INT 27H Tipo MS-DOS. Proporciona interrupciones semejantes al servicio INT 27H del MS-DOS.

No subfunción Para mantener programas residentes.

Parámetros: DX = Número de bloques de 16 bytes; el número máximo es 10.

Retorno: Ninguno. Con esta interrupción finalizamos un programa y reservamos cierta cantidad de bytes de memoria. Esta función se emplea cuando se desea dejar un programa residente, ya que al finalizar el programa, el control es tomado por el Monitor y no por el BIOS.

INT 60H Utilerías. Proporciona algunas utilerías empleadas por la tarjeta. Se asume que las cadenas empleadas terminan en CERO como en lenguaje C; los números que maneja son todos sin signo.

AH = 00H Imprime un número de 16 bits en hexadecimal, desde la posición actual del cursor en el display.

Parámetros: BX = Número a imprimir.

Retorno: Nada.

AH = 01H Imprime un número de 8 bits en binario, desde la posición actual del cursor en el display.

Parámetros: BL = Número a imprimir.

Retorno: Nada.

Page 158: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

151

AH = 02H Imprime un número de 16 bits en decimal, desde la posición actual del cursor en el display.

Parámetros: BX = Número a imprimir.

Retorno: Nada. La impresión emplea los 5 caracteres de los que es posible se componga el número, los lugares no ocupados se rellenan con cero.

AH = 03H Imprime una cadena de texto, desde la posición actual del cursor.

Parámetros: DS:SI = Texto a imprimir en el display.

Retorno: Nada.

AH = 04H Mide la longitud de una cadena.

Parámetros: DS:SI = Dirección de la cadena a medir.

Retorno: CX = Longitud de la cadena.

AH = 05H Convierte una cadena de números en decimal a un entero.

Parámetros: DS:SI = Cadena de números.

Retorno: BX = Entero. No se hace ninguna verificación del contenido de la cadena, se supone que se esperan números ASCII entre 48 y 57, que corresponden a los caracteres 0 a 9.

AH = 06H Convierte un entero a una cadena de números.

Parámetros: BX = Entero. CL = Base. ES = Segmento destino de la cadena. DI = Offset destino de la cadena.

Retorno: ES:DI = Cadena de números. En lugar de esta subfunción se deben usar las primeras subfunciones, ya que por lo general solo es necesario para imprimir números, sin embargo esta subfunción no rellena con CEROS.

AH = 07H Lee una cadena de texto de a lo más 19 caracteres (depende del tamaño de pantalla), hasta que se presione un ENTER. Nota: se debe activar el servicio INT 60H subfunción 08H, para que esta interrupción funcione.

Parámetros: DH = Renglón. DL = Carácter de prompt. ES = Segmento destino de la cadena.

Page 159: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

152

DI = Offset destino de la cadena.

Retorno: ES:DI = Cadena de números. CX = Número de caracteres escritos. El buffer donde se va almacenar la cadena, debe tener al menos 20 bytes. Solo sirven las teclas alfanuméricas y la tecla de RETROCESO con la que borran los caracteres anteriores. Si DL es cero, no se coloca prompt; el carácter recomendado es 03EH (>).

AH = 08H Activa el 8279110.

Parámetros: AL = Número de Chip-Select (0 - 7). BH = Divisor de frecuencia (0 - 31). BL = Modo del teclado (ver hojas del 8279). CH = Número de INT empleado por el 8279 (0 - 3).

Retorno: Nada. Para hacer uso de los servicios, en todo lo referente al teclado, es necesario llamar esta interrupción. Una vez realizado esto, todo funciona como en una PC normal. El sistema no detecta si ya se ha iniciado el teclado. Si se usa un servicio de teclado sin antes iniciarlo, puede provocar un error en el sistema. Inicia el buffer de teclado. Para cambiar la matriz del teclado ver interrupción 60H subfunción 0AH.

AH = 09H Desactiva el 8279.

Parámetros: Ninguno.

Retorno: AL = Chip-Select. AH = Número de INT. Desactiva el 8279, ya no es posible usar el teclado.

AH = 0AH Cambia la matriz de caracteres del teclado.

Parámetros: DS:SI = Dirección donde están los 128 caracteres de la matriz del teclado (64 para mayúsculas y 64 para minúsculas).

Retorno: CX = 0 si se tuvo éxito. Esta subfunción es para compatibilidad con otros teclados, que tengan una matriz diferente a la establecida. La matriz nueva debe tener especial atención en las teclas: ENTER (0DH), BACK (08H) y CAPS (OBH).

AH = 0BH Retorna la INT de hardware que emplea el teclado.

110 Esta subfunción fue hecha para la versión anterior a la UAMI188EB.

Page 160: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

153

Parámetros: Ninguno.

Retorno: AL = Valor de la interrupción. Esta subfunción es para localización de la interrupción por hardware del teclado.

AH = 0CH Imprime un número de 8 bits en hexadecimal en el display.

Parámetros: BL = Número a imprimir.

Retorno: Nada.

AH = 0DH Controla la ejecución del temporizador 1 del microprocesador.

Parámetros: AL = 0 Termina la ejecución. AL = 1 Inicia la ejecución.

Retorno: Nada. Esta subfunción inhabilita/habilita la interrupción por hardware del temporizador 1; no cambia el vector ni modifica el contador del temporizador o el reloj de tiempo real del sistema. Se debe tener cuidado al usar esta subfunción, ya que el BIOS y el Monitor hacen uso del temporizador 1 para sincronizar algunos procesos.

AH = 0EH Convierte un numero de 8 bits, en su representación en BCD.

Parámetros: AL = Número a convertir.

Retorno: AL = Numero a BCD. Esta subfunción convierte un numero de 8 bits a su representación en BCD; observe que el número máximo permitido es 99. (No verifica los datos).

AH = 0FH Convierte un numero en formato BCD a un numero de 8 bits.

Parámetros: AL = Número en BCD.

Retorno: AL = Numero de 8 bits. Esta subfunción convierte un numero en formato BCD a un número de 8 bits; observe que el número máximo permitido de entrada es 99H, el cual es en realidad 99. (No verifica los datos).

AH = 10H Activa/Desactiva las comunicaciones con el depurador.

Parámetros: AL = 1 Activa. 0 Desactiva.

Retorno: Nada. Esta subfunción debe emplearse con mucho cuidado, ya que desactiva toda comunicación con el depurador; sólo debe emplearse en programas que utilizan el puerto serie para otra aplicación.

Page 161: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

154

INT 61H Estado del equipo. En la PC normal, esta interrupción es la 11H.

No subfunción Obtiene información del equipo.

Parámetros: Ninguno

Retorno: AX = Estado del equipo. Los bits empleados son los siguientes: 2 – 3 Memoria RAM del sistema. 00 – 08K 01 – 16K 10 – 32K 11 – 48K 4 – 5 Modo inicial de video, indica cual es el modo default, no el actual. 00 – 16x2 01 – 20x2 10 – 16x4 11 – 20x4

INT 62H Memoria del sistema. En la PC normal, esta interrupción es la 12H.

No subfunción Informa sobre el tamaño de memoria del sistema.

Parámetros: Ninguno.

Retorno: AX = Numero de bloques de 1Kb.

INT 63H Interrupción del puerto serial. (Esta interrupción no es, ni activa la interrupción por hardware del puerto serial, solo es un servicio para manejo del puerto serial). En la PC normal, esta interrupción es la 14H111.

AH = 00H Inicia el puerto de comunicaciones.

Parámetros: AL = Parámetros de inicio. Los bits empleados son los siguientes: 0 – 1 Longitud de palabra. 10 – 7 bits. 11 – 8 bits. 3 – 4 Paridad 00 – Sin paridad. 01 – Paridad impar. 10 – Sin paridad. 11 – Paridad par. 5 – 7 Velocidad. 000 – 110 baud. 001 – 150 baud. 010 – 300 baud.

111 Para usar esta interrupción en alguna aplicación, se recomienda usar antes la interrupción 60H subfunción 10H para desactivar la comunicación con el depurador.

Page 162: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

155

011 – 600 baud. 100 – 1200 baud. 101 – 2400 baud. 110 – 4800 baud. 111 – 9600 baud. DX = Numero de puerto. 00 – COM1. 01 – COM2 02 – COM3 03 – COM4

Retorno: AX = Estado del puerto, cambia del original PC; ver hojas de especificaciones del 188EB.

AH = 01H Escribe un carácter al puerto.

Parámetros: AL = Carácter a enviar. DX = Numero de puerto. 00 – COM1. 01 – COM2 02 – COM3 03 – COM4

Retorno: Si es éxito: Bit 7 de AH = 0 AL = Carácter enviado. Si falla: Bit 7 de AH = 1 los demás bits son: AX = Estado del puerto, cambia del original PC; ver subfunción 03H.

AH = 02H Recibe un carácter por el puerto serie.

Parámetros: DX = Numero de puerto. 00 – COM1. 01 – COM2 02 – COM3 03 – COM4

Retorno: Si es éxito: BIT 7 de AH = 0 AL = Carácter recibido. Si falla: BIT 7 de AH = 1 los demás bits son: AX = Estado del puerto, ver subfunción 03H.

AH = 03H Lee el estado del puerto.

Parámetros: DX = Numero de puerto.

Page 163: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

156

00 – COM1. 01 – COM2 02 – COM3 03 – COM4

Retorno: AX = Estado del puerto, los bits son: Los bits siguientes están activos cuando 9 Ocurrió un break (ruptura) de 2M+3 bits. 8 Ocurrió un break de M bits (M según la longitud de bits). 7 Error de paridad. 6 Dato recibido y en buffer. 5 Se ha transmitido un carácter (solo se usa cuando se ha enviado). 4 Error de marco, cuando no se ha detectado un bit de parada valido. 3 Buffer de corrimiento y transmisión vacíos. 2 Sobrecorrimiento, no se ha leído un carácter del buffer de recepción y otro carácter ha llegado. 1 CTS es el complemento del valor en el pin CTF del 188EB.

INT 64H Usada por el Monitor para depurar programas.

No subfunción Se encarga de activar el modo de depuración de la UAMI188EB, esta interrupción sólo puede ser llamada por el programa D188.EXE vía el Monitor.

Parámetros: Ninguno.

Retorno: Nada.

INT 70H Timers. Controla los temporizadores del 188EB. Es un servicio no es posible configurar del todo las interrupciones112.

AH = 00H a 02H Programación de los temporizadores del temporizador 0 al temporizador 2, recuerde que el temporizador 1 es empleado por el BIOS y el Monitor.

Parámetros: AL = Banderas del temporizador. Los bits son los siguientes: 0 Activa el temporizador. 1 Alterna entre los registros de conteo, ver manual del 188EB. 2 Emplea un reloj externo para la sincronización. 3 Preescala con el temporizador 2. SI = Conteo. En general este registro es cero, es decir, el conteo inicia en cero. BX = Comparador A. CX = Comparador B. No se emplea en el temporizador 2, la señal de este temporizador siempre es cuadrada.

112 En la PC normal, esta es una interrupción empleada por la interrupción del reloj de tiempo real.

Page 164: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

157

Para obtener la frecuencia deseada, se recurre a la siguiente formula:

COMP = ((FCPU / 4) / FREC_DESEADA)

Donde: FCPU es la frecuencia del CPU, en nuestro caso 12MHz. FREC_DESEADA es la frecuencia que se persigue en el

temporizador. Si buscamos una señal cuadrada simétrica, en cada comparador deberá ir el número COMP / 2; sin embargo, si no se busca una señal simétrica, se puede jugar con el valor de los comparadores (A y B), pero siempre respetando que:

BX + CX = COMP

Retorno: Nada. Para una mejor referencia acerca del uso de los temporizadores del 80C188EB, ver [2]

Page 165: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

158

Page 166: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

159

Apéndice C. Mapa de memoria de la UAMI188EB.

C.1 Introducción En la UAMI188EB existe una zona de memoria reservada para almacenar algunas variables y constantes que son empleadas por el BIOS, el Monitor y el propio microprocesador, esta zona de memoria se localiza entre las direcciones 00000H a 006FFH. La memoria de la UAMI188EB esta dividida en 3 secciones (ver Fig. C.1):

• Area de vectores de interrupción. Están almacenados las direcciones (segmento:offset) de los procedimientos de cada interrupción. Cuando ocurre una interrupción, ya sea de hardware o software, el microprocesador calcula un desplazamiento en esta área en base al número de interrupción, obtiene la dirección y ejecuta lo que ahí exista. Algunas direcciones ya están empleadas por el BIOS y el Monitor, pero muchas otras pueden ser usadas por el usuario (ver Apéndice B).

• Area para el BIOS y el Monitor. Esta reservada para el BIOS y el Monitor, aquí se almacenan algunos parámetros de la configuración del sistema y memoria para los procesos del Monitor. Ni esta zona de memoria ni la anterior, deberá ser modificada por el usuario, ya que puede ocasionar que la UAMI188EB no funcione adecuadamente.

• Area para programas y pila. A partir de la dirección 00700H hasta la 01FFFH se localiza la memoria que comparten programas y pila. Por regla sólo puede existir un programa, pero es posible ejecutar dos programas; sin embargo, si hay dos programas o más empleando el procesador, entonces esos programas deberán compartir una sola pila.

Figura C.1 Esquema básico de memoria.

El usuario puede administrar la memoria del programa y de la pila como mejor le convenga, pero cuando el programa termine y le cede el control al BIOS, pila se restaura al valor default, el cual es SS = 0000H y SP = 2000H. Si el programa retorna el control al BIOS, este no restaura la pila, pero ejecutar un nuevo programa si provoca esto; por lo que se recomienda permitir que el Monitor sea quien administre la pila.

Page 167: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

160

C.2 Mapa de memoria

Offset

113 Bytes Descripción

0400H 2 Se localiza la dirección en el peripheral control block (Bloque de control de periféricos o PCB) del puerto serie 0, en la UAMI188EB se le denomina COM1 y es empleado para comunicarse con el depurador D188.EXE. El valor aquí almacenado es 0FF60H.

0402H 2 Dirección del PCB para el COM2, en este caso el puerto serie 1. Valor almacenado 0FF70H.

0404H 2 Sin uso, destinado al COM3.

0406H 2 Sin uso, destinado al COM4.

0410H 2 Banderas que indican el estado del equipo, ver Tabla C.1.

0413H 2 Tamaño de memoria en Kilobytes.

0417H 2 Banderas del teclado, sólo se emplea un byte, ver Tabla C.2.

041AH 36 Buffer de teclado, la estructura se muestra en la Tabla C.3.

0449H 1 Modo actual del display, ver interrupción 10H subfunción 00H en Apéndice B.

044AH 2 Tamaño de pantalla; en 044AH número de columnas y en 044BH el de renglones. En la PC original, aquí se indica el número de columnas de la pantalla.

0450H 2 Posición del cursor; en 0450H están las Columnas y en 0451H los renglones.

0460H 2 Modo actual del cursor. Sólo se emplea la dirección 0460H, interrupción 10H subfunción 01H en Apéndice B.

0462H 1 Número de pagina de video activa, en este caso siempre es cero.

046CH 2 Palabra baja del contador del sistema.

046EH 2 Palabra alta del contador del sistema.

0470H 1 Bandera de media noche. Puesta en 1 si la media noche (24:00 hrs) ha pasado desde la ultima lectura con las interrupción 1AH.

0480H 2 Inicio del área de datos del teclado, sólo se almacena el offset; por default es 041AH.

0482H 2 Fin del área de datos del teclado, sólo offset; por default es 043DH.

04F0H 16 Area de comunicaciones con el depurador D188.EXE, ver Tabla C.4.

0500H 130 Tablas de caracteres del teclado. Son dos tablas, cada una de 64 bytes; una tabla esta destinada para letras minúsculas y otra para mayúsculas. En el byte 129 (0580H) se almacena el Chip-Select empleado y en el byte 130 (0581H) la interrupción por hardware empleada.

0582H 2 Contador de segundos del sistema, indica cuantos segundos faltan

113 El segmento para todas estas variables es, por default 0000H.

Page 168: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

161

cuando se ha activado con la interrupción 1AH. Offset Bytes Descripción

0584H 1 Bandera del contador de segundos, es uno si la variable anterior es cero.

0588H 40 Buffer de pantalla; no tiene ninguna función por el momento.

05B0H 1 Estado del monitor, ver Tabla C.5.

05B1H 2 Velocidad de comunicación con la UAMI188EB y el depurador. Es posible cambiar este valor, para modificar la velocidad de comunicación con el D188.EXE.

05B3H 1 Número de segundos de espera. Este número indica cuantos segundos debe esperar la UAMI188EB antes de abortar cualquier comunicación con el depurador.

05B4H 2 Offset de entrada del BIOS.

05B6H 2 Segmento de entrada del BIOS.

05B8H 2 Offset de entrada del Monitor.

05BAH 2 Segmento de entrada del Monitor.

05BCH 28 Buffer de registros, en esta zona se almacenan los valores de los registros, ver Tabla C.6.

05DAH 1 Se almacena el código de retorno al finalizar un programa.

05DBH 1 Código de error generado por un programa.

05DDH 1 Tipo de display, ver interrupción 10H subfunción 00H en Apéndice B.

05DEH 2 Offset de la pila empleada por el Monitor.

0600H 256 Memoria para el Monitor.

0700H 6400 Inicia la memoria disponible para programas.

Bits Descripción.

2 – 3 Memoria RAM del sistema. 00 – 08K 01 – 16K 10 – 32K 11 – 48K

4 – 5 Modo inicial de video. Indica cual es el modo default, no el actual. 00 – 16x2 01 – 20x2 10 – 16x4 11 – 20x4

Tabla C.1 Banderas de equipo, los demás bits son cero.

Page 169: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

162

Bits Descripción.

0 (- 1) Tecla SHFT presionada, en realidad se usa un bit para SHFT derecho y otro para el izquierdo, sólo se emplea el bit 1.

2 Tecla CTRL presionada.

6 Si es 1 están activadas las mayúsculas (CAPS). Tabla C.2 Banderas del teclado, los demás bits son cero.

Offset Descripción

041A Fin de cola del buffer. Dirección del ultimo elemento introducido.

041C Inicio de cola de buffer Dirección del primer elemento introducido. El inicio de la cola puede alcanzar al fin de la cola, pero el fin de la cola no puede alcanzar al inicio de la cola.

041E Inicia del buffer de teclado, el buffer es de 16 palabras (2 bytes por palabra).

Tabla C.3 Estructura del buffer de teclado.

OFFSET Descripción

04F0 Fin de cola del buffer (offset del último elemento introducido).

04F1 Inicio de cola de buffer, offset del primer elemento introducido. El inicio de la cola puede alcanzar al fin de la cola, pero el fin de la cola no puede alcanzar al inicio de la cola (cola circular). El Offset de inicio y fin de cola, son con respecto a 04F2H; es decir, al inicio la cola esta vacía y el contenido de estas dos direcciones es 0.

04F2 Inicia del buffer de comunicaciones con el depurador. Tabla C.4 Estructura del buffer de comunicación con el depurador.

OFFSET Descripción

05B0 El monitor maneja 5 estados:

• OK. Primer estado cuando se inicia la tarjeta UAMI188EB.

• STP. Estado de alto, se ha cargado un programa en la UAMI188EB, pero no se ha ejecutado.

• RUN. La UAMI188EB se encuentra ejecutando un programa.

• DBG. La UAMI188EB se encuentra en modo de depuración.

• DSC. Este estado ocurre cuando un programa ejecutándose en la UAMI188EB ha decidido desconectarse del depurador; este programa es responsable de conectarse nuevamente.

Cualquier otro estado se maneja como desconocido en el depurador. Tabla C.5 Estado del monitor.

Page 170: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

163

Offset Registro Offset Registro

05BCH AX 05CAH SP

05BEH BX 05CCH DS

05C0H CX 05CEH ES

05C2H DX 05D0H SS

05C4H DI 05D2H CS

05C6H SI 05D4H IP

05C8H BP 05D6H FLAG Tabla C.6 Buffer de registros.

Page 171: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

165

Apéndice D. Lista de interrupciones del BIOS.

D.1 Introducción A continuación se presenta una lista de todos los procedimientos y funciones, que

están relacionados con la lista de comandos mostrados en el Capitulo 3, Tabla 3.1; de igual manera, se presenta una lista de la localización de los procedimientos y funciones, en cada uno de los archivos, los cuales pueden ser consultados en los Apéndices E y F.

D.2 Procedimientos y funciones relacionados con Comandos

Funciones y/o procedimientos Comando Monitor D188.EXE

CMSOK1 INTERRUPT_RX_SERIAL0 DUAMI188::bChkConexion DUAMI188::handleEvent

CMSRESET INTERRUPT_RX_SERIAL0 DUAMI188::vReiniciaUAMI CMSCARGA MONITOREO

PROC_CMSCARGA DUAMI188::vCargaProgramaArchivoUAMI

DUAMI188::vCargaProgramaUAMI CMSEJECUTAR MONITOREO

PROC_CMSEJECUTAR DUAMI188::vEjecutar

CMSPASO MONITOREO INTERRUPT_INT64H

DUAMI188::vEjecutaPasoPaso

CMSEND INT21H_4CH INTERRUPT_INT20H

DUAMI188::handleEvent DUAMI188::vLeerRetorno

CMSERROR PROCESA_ERR_INT DUAMI188::handleEvent DUAMI188::vLeerError

CMSOBTENMEM MONITOREO PROC_CMSOBTENMEM

DUAMI188::vLeerMemoriaUAMI188

CMSMUEVEMEM MONITOREO PROC_CMSMUEVEMEM

DUAMI188::vMoverMemoriaUAMI188

CMSOBTENREG MONITOREO PROC_CMSOBTENREG

DUAMI188::vLeerRegistrosUAMI188

CMSDETENER INTERRUPT_RX_SERIAL0 PROC_CMSDETENER

DUAMI188::vDetenerEjecucion

CMSDESCONECT INT60H_10H DUAMI188::handleEvent CMSCONECTAR INT60H_10H CMSOBTENRET MONITOREO

PROC_CMSOBTENRET DUAMI188::vLeerRetorno

CMSOBTENERR MONITOREO PROC_CMSERR

DUAMI188::vLeerError

CMSOBTENPRG MONITOREO PROC_CMSOBTENPRG

DUAMI188::vLeerMemoriaUAMI188

1 En general todas las funciones de la tabla emplean el comando CMSOK; las funciones aquí asociadas, emplean este comando para verificar el estado de la UAMI188EB.

Page 172: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

166

Funciones y/o procedimientos Comando Monitor D188.EXE

CMSCARGAREG MONITOREO PROC_CMSCARGAREG

DUAMI188::vCargaRegistro

CMSCARGAMEM MONITOREO PROC_CMSCARGAMEM

DUAMI188::vCargaMemoria

CMSACERCADE MONITOREO PROC_CMSACERCADE

DUAMI188::handleEvent

CMSRESIDENTE INTERRUPT_INT27H DUAMI188::handleEvent CMSFIJAHORA MONITOREO

PROC_CMSFIJAHORA DUAMI188::vFijaHoraUAMI188EB

Tabla D.1 Procedimientos y funciones que manejan los comandos.

D.3 Localización de los procedimientos dentro de los archivos del Monitor A continuación se muestra una lista de todos los procedimientos, y el archivo en donde se localizan. INITVEC.ASM

COLOCA_VECTORES INT01Y03.ASM

INTERRUPT_INT01H INTERRUPT_INT03H INT04.ASM INTERRUPT_INT04H INT05.ASM INTERRUPT_INT05H INT06.ASM

INTERRUPT_INT06H INT07.ASM

INTERRUPT_INT07H

INT10.ASM

INTERRUPT_INT10H INT10H_00H INT10H_01H INT10H_02H INT10H_03H INT10H_05H

INT10H_08H INT10H_09H INT10H_0AH INT10H_0EH INT10H_0FH INT10H_11H DSP_WAITFLAG DSP_MOVE_UP_ROW DSP_CAL_ROWCOL INT16.ASM INTERRUPT_INT16H INT16H_00H

INT16H_01H INT16H_02H INT16H_05H

Page 173: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

166

INT16H_13H INT19.ASM INTERRUPT_INT19H PROC INT1A.ASM

INTERRUPT_INT1AH INT1AH_00H INT1AH_01H INT1AH_02H INT1AH_03H INT1AH_20H

INT1AH_21H INT1C.ASM

INTERRUPT_INT1CH INT20.ASM INTERRUPT_INT20H PROC INT21.ASM

INTERRUPT_INT21H INT21H_01H INT21H_02H INT21H_09H INT21H_25H INT21H_30H INT21H_35H INT21H_4CH INT27.ASM

INTERRUPT_INT27H INT60.ASM INTERRUPT_INT60H INT60H_00H

INT60H_01H INT60H_02H INT60H_03H INT60H_04H INT60H_05H INT60H_06H INT60H_07H INT60H_08H INT60H_09H INT60H_0AH INT60H_0BH INT60H_0CH INT60H_0DH INT60H_0EH INT60H_0FH INT60H_10H INT61Y62.ASM INTERRUPT_INT61H INTERRUPT_INT62H INT63.ASM

INTERRUPT_INT63H INT63H_00H INT63H_01H INT63H_02H INT63H_03H INT70.ASM INTERRUPT_INT70H INT70H_00H INT70H_02H

KEYBOARD.ASM INICIA_KEYBOARD INTERRUPT_KEY_8279 RET_INT_KEYBOARD RELOJ.ASM

Page 174: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

167

INTERRUPT_RELOJ_T1 RELOJ_REAL SERIAL.ASM SER0_INICIA SER0_SEND SER0_RECEV

INTERRUPT_RX_SERIAL0 SER0_COLAVACIA SER0_OBTENDATO SER0_INTERRUPCIONEDO SER0_LIMPIACOLA SER0_LIMPIAPUERTO INICIA_COM_DEPURADOR SER0_SENDE MONITOR.ASM MONITOREO PROC_CMSOK PROC_CMSRESET PROC_CMSCARGA

PROC_CMSEJECUTAR CARGA_BUFFER2REG PROC_CMSOBTENREG PROC_CMSDETENER PROC_CMSOBTENRET PROC_CMSOBTENERR PROC_CMSOBTENPRG PROC_CMSOBTENMEM PROC_CMSMUEVEMEM PROC_CMSCARGAREG PROC_CMSCARGAMEM PROC_CMSACERCADE PROC_CMSFIJAHORA PREPARA_MONITOR ERRINT.ASM

PROCESA_ERR_INT DEPURA.ASM

NUMERO_DEPURA

D.4 Localización de funciones y procedimientos del programa D188.EXE A continuación se muestra una lista de las funciones más importantes del programa D188.EXE, y los archivos en donde se localizan. COD2MAQ.CPP word wASM2MAQ (char *pcText, byte *pbCod, word *pwRef, word wLin);

int iIniciaASM (word wMEM, word wLBLCTE, word wMaxMsg); void vTerminaASM (); byte bFinCompilacion (); void vIniciaCompilacion (); byte bEsSegundoPaso (); byte bEsSETREF (); char *pcEsArchivoINCLUDE (); word wCodINoArg (byte *pbCod, byte bNumTipo); word wCodIEsp (nodo *psnLista, byte *pbCod); word wCodIUnArg (nodo *psnLista, byte *pbCod, word wRef); word wCodIDosArgs (nodo *psnLista, byte *pbCod, word wLin);

Page 175: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

166

word wCodResWord (nodo *psnLista, byte *pbCod, char *pcText, word *pwRef, word wLin); word wCodEtiqueta (nodo *psnLista, char *pcText, word wRef); word wChkCOMA (nodo **psnAux); word wAnalizaArgs (nodo **psnAux, word *pwFlagDir, word *pwIdArg, dword *pdNum, byte *pbSeg, byte *pbReg); word wAnalizaIEsp (nodo **psnAux, word *wFlag); word wAnalizaModoDir (nodo **psnAux, word *pwFDir, dword *pdNum); byte bObtenRegDirFlag (byte bNumTipo); byte bObtenModoDir (word wFDir); word wChkIdArgs (word wIdArg, word *pwFlagDir, dword *pdNum); word wChk2IdArgs (word *pwIdArg, word *pwFlagDir, dword *pdNum); byte bByteRM (word *pwIdArg, word *pwFlagDir, byte *pbReg, byte *pbSeg); byte bChkSalto (nodo *psnAux); byte bChkIOPort (byte bTipo, byte bNumTipo); void vBorraLBLCTE (); STRFUN.CPP word wM_LenCad (word *pwLen, char *pcText); int iBuscaChar (char *pcText, int iIni, char cC); word wObtenTokens (nodo **psnRet, char *pcText, word wLen); void vObtenNombreArch (char *pcFile, char *pcIn, byte bFlag, word wLen); void vObtenNombreDir (char *pcDir, char *pcIn); char cChkStr (char *pcText1, word wLen, char *pcText2, char cMay); word wAnalizaCadena (char *pcText, word wIni, word wLen, dword *pdNum); char cEsNumero (char *pcText, word wIni, word wLen); MEMORIA.CPP

int iIniciaMem (word wMEM, word wLBLCTE, word wMaxMsg); void vTerminaMem (void); void *pvMemoria (word wMem); void vLiberaMem (void); void *pvMemLBL (word wMem); void vLiberaMemLBL (void); ERROR.CPP void vImprimeMensajes (); int iAddMensaje (word wMsg, word wLin); void vResetMensajes ();

Page 176: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

167

LABEL.CPP

void vAddRefLBL (label *pslAux, inst *psiAux, byte bAdd); void vAddRefInst (inst *psiAux, byte bAdd); word wAddEtiqueta (char *pcText, word wPos, word wLen, byte bTipo, byte bNumTipo, word wRefVal); label *pslBuscaEtiquetaConstante (char *pcText, word wPos, word wLen); word wAddInstruccion (char *pcText, word wLen, word wRef, word wLin);

word wCodEtiqueta (nodo *psnLista, char *pcText, word wRef); byte bEsInstruccion (nodo *psnAux); void vAddRefInst (inst *psiAux, byte bAdd); void vAddRefLBL (label *pslAux, inst *psiAux, byte bAdd); void vLiberaLBLCTE (); word wResuelveRef (); word wSustituyeLBLCTE (nodo *psnAux, char *pcText); word wAddINCLUDE (char *pcFile, word wLin); byte bCreaMAP (char *pcFile); label *pslOrdenaLBLCTE (label *pslAux); MAQ2ASM.CPP

word wMAQ2ASM (char *pcTxt, char *pbCod, word wPos, word wRef, word wLen); byte bIniciaMAQ (word wMemoriaMAQ); void vTerminaMAQ (); word wDecodINoArg (char *pcTxt, char *pbCod, word wPos, word wLen); word wDecodIEsp (char *pcTxt, char *pbCod, word wPos, word wLen); word wDecodIUnArg (char *pcTxt, byte *pbCod, word wPos, word wLen, word wRef); word wDecodIDosArg (char *pcTxt, char *pbCod, word x, word wLen); void vFijaDB (char *pcTxt, byte bCod); word wChkCodigo (byte *pbCod, byte *pbCodArgs, word wPos); void vAgregaNum (char *pcTxt, dword dNum, word wTipo, char cPlus); byte bObtenArgumento (byte bArg, byte bTipo); byte bObtenArgumentoSeg (byte bArg); word wAgregaArg (char *pcTxt, byte *pbCod, word wCod, word wCMP, byte bArg, byte bPTR, byte bCOMA); DESENA.CPP

dword dCargaCODIGO (char *pcFile); void vColocaCODIGO (byte *pbCod, word wPos, byte bInsert); GRAL_AM.CPP

Page 177: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

168

void vCargaDescriptores (void); word wNumOpcDescriptor (byte bDesc); int iObtenPosDescriptor (byte bDesc, word wPos); dword dObtenNumero (char *pcText, word wLen, byte bTipo); EDIT188A.CPP DUAMI188 (int iArg, char **pscArg);

virtual void handleEvent (TEvent &psteEvent); virtual void idle (); ~DUAMI188 (); EDITWINDOW *pstewAbrirEditor (const char *fileName, Boolean visible); void vAbrirArchivo (); void vNuevoArchivo (); void vCambiarDir (); void vDOSShell(); void vMostrarClip (); void vMosaico (); void vCascada (); EDIT188B.CPP

ushort usEjecutarDialogo (TDialog *pstdD, void *pvData); TDialog *pstdBuscarDialogo (); TDialog *pstdReplazarDialogo (); EDIT188C.CPP

static TMenuBar *initMenuBar (TRect); static TStatusLine *initStatusLine (TRect); virtual void outOfMemory(); void vAcercaDe(); ushort usDialogosEdicion (int dialog, ...); FUNCION.CPP

byte bIniciaASMMAQ (); TView *pstvPrimeraVentana (Boolean (*bFun)(TView *, void *), void *pvArgs); TView *pstvBuscaVentanaArch (char *pcArch); EDITWINDOW *pstewObtenTopEditor (); void vCompilar (byte bDisk); int iSetArchivoPrimario (); void vCerrarTodo ();

Page 178: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

169

void vGuardarTodo (); COMPILAE.CPP void vCompilaArchivo (char *pcFile, efile *psefAux, byte bDisk); void vCompilaArchivo (char *pcFile); void vCompilaPantalla (); byte bObtenLineaCod (FILE *psfIn, char *pcText, word *pwLin);

DIALOGOS.CPP void vOpcionesDialog (); void vActualizaEditores (); void vAgregaInstruccionDialog ();

void vCambiaRegistroDialog (); void vLeerMemoriaUAMI188Dialog (); void vLeerProgramaUAMI188Dialog (); void vMoverMemoriaUAMI188Dialog (); void vCargaMemoriaUAMIDialog (); void vSetLeerMemoriaDialog (); void vCambiaMemoriaDialog (); UAMI188.CPP byte bChkConexion (); void vReiniciaUAMI (); void vSelecCargaUAMI (); void vLeerMemoriaUAMI188 (word wSeg, word wOffSet, word wNBytes, void

*pvMem); void vLeerRegistrosUAMI188 (); void vMoverMemoriaUAMI188 (word wISeg, word wFSeg, word wIOffSet, word wFOffSet, word wNBytes); void vCargaProgramaArchivoUAMI (); void vCargaProgramaUAMI (word wInicio, word wFinal); void vEjecutaPasoPaso (); void vEjecutar (); void vLeerRetorno (); void vLeerError (); void vDetenerEjecucion (); void vCargaRegistro (byte bReg); void vCargaMemoria (word wSeg, word wOff, word wNBytes, byte *pbDatos); void vFijaHoraUAMI188EB (); byte bEnviaEsperaDato (byte bSend);

Page 179: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

170

void vFalloConexion (); byte bEsperaTransDato (byte *pbDato); byte bEnviaComandoEstado (byte bDatoSend); byte bEsperaDatoCola (byte *pbDato, word wTmp); void vDepuradorVolcado (word wSeg, word wOffSet); void vContadorEspera (); FUNDEBUG.CPP

void vCargaFileDebug (); void vAbrirMAP (); COMPILAE.CPP

byte bObtenLineaCod (char *pcText, FILE *psfIn, efile *psefIn, word *pwLin); byte bCreaEditFile (efile *psefF, EDITWINDOW *pstewAux); void vAsignaEditFile (efile *psefF1, efile *psefF2); char *pcEditFile (efile *psefF); byte befof (efile *psefAux); byte bEFValido (efile *psefAux); char cGetc (efile *psefAux); void vResetPunteros (FILE *psfIn, efile *psefIn); FUNCION.CPP void vEsperaEvento (); REGISTRO.CPP

void vIniciaRegistros (); void vCambiaRegistro (byte bReg, word wVal); word wObtenRegistro (byte bReg);

Page 180: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

175

Apéndice E. Código fuente del BIOS y el Monitor

E.1 BIOSM.ASM ;ESTE ES EL PUNTO DE ENTRADA DEL BIOS (MONITOR). ;************************************************** ********************** ;NOTAS: SI SE DESEA ENSAMBLAR LA VERSION PARA TECLA DO, ES NECESARIO ;MODIFICAR LOS ARCHIVOS SIGUIENTES BIOSM.ASM, INITV EC.ASM Y ;BUSCAR POR KEYB. ; ;************************************************** ********************** P80186 ;Tipo de Procesador ;****************************** CONSTANTES ******** ********************** INCLUDE "CONST.ASM" ;Las contantes usadas por el BIOS (monitor). INCLUDE "BIOSVARS.ASM" ;Las variables en la mem oria usadas por el BIOS. ;************************************************** ********************** DELAY EQU 0FFFFH ;Primera espera DELAY2 EQU 07FFFH ;Segunda espera DISPLAY EQU 01H ;Display de 16x2 por default CLI ;Se desactiva toda interrupcion. ;******************************** INICIO ********** ********************** ;Primero se definen los Chip-Select. INCLUDE "CHIPSEL.ASM" ;Se activan los Chip-Select . (SOLO UAMI188EB ACTUAL) ;Se inicia el display. INCLUDE "INITDSP.ASM" ;Se inicia el display para los mensajes. ;Se verifican ambas memorias ROM Y RAM. INCLUDE "CHKMEM.ASM" ;Si existe un error, hasta a qui llega. ;************************** TIEMPO DE ESPERA ****** *********************** MOV CX, DELAY ;A la memoria le da m s tiempo. INICIO_LOOP00: LOOP INICIO_LOOP00 MOV CX, DELAY INICIO_LOOP01: LOOP INICIO_LOOP01 ;*************************** SE INICIA PILA ******* *********************** MOV SP, TAM_MEMORIA_RAM ;Se usa todo el tama¤o de la RAM. XOR AX, AX MOV SS, AX MOV AX, CS MOV DS, AX ;Fijamos el registro DS. MOV ES, AX ;Y el ES. ;************************************************** ********************** MOV AL, DISPLAY ;Definimos el display, por defau lt es 16x2. CALL INT10H_00H ;******************* SE INICIAN LAS VARIABLES DEL B IOS******************* MOV AH, 03H MOV SI, INICIO_MSG01 CALL INT60H_03H INCLUDE "INITVARS.ASM" MOV CX, DELAY INICIO_LOOP04: LOOP INICIO_LOOP04 MOV CX, DELAY2 INICIO_LOOP05: LOOP INICIO_LOOP05 ;**************** SE COLOCAN LOS VECTORES DE INTERR UPCION *************** MOV SI, INICIO_MSG00 CALL INT60H_03H CALL COLOCA_VECTORES ;************************************************** ********************** MOV CX, DELAY INICIO_LOOP02: LOOP INICIO_LOOP02 MOV CX, DELAY2 INICIO_LOOP03:

Page 181: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

176

LOOP INICIO_LOOP03 ;******************* SE INICIA EL HARDWARE DEL SIST EMA ****************** MOV AH, 03H MOV SI, INICIO_MSG02 CALL INT60H_03H INCLUDE "INITHARD.ASM" MOV CX, DELAY INICIO_LOOP06: LOOP INICIO_LOOP06 MOV CX, DELAY2 INICIO_LOOP07: LOOP INICIO_LOOP07 ;************************* MENSAJES DEL BIOS ****** ********************** MOV AH, 03H MOV SI, INICIO_MSG03 CALL INT60H_03H JMP INICIO_JMP_MSG INICIO_MSG00: DB KENTER, "Vectores...", 0 INICIO_MSG01: DB "Variables...", 0 INICIO_MSG02: DB KENTER, "Hardware...", 0 INICIO_MSG03: DB KENTER, "BIOS 1.0", 28H, "2005", 29H, KENTER, 0H INICIO_JMP_MSG: ;Desde este punto es posible usar las interrupcio nes de software. ;************************************************** *********************** ;AQUI INICIA EL CODIGO PRINCIPAL DEL PROGRAMA ;************************************************** *********************** PUSH CS POP AX XOR BX, BX MOV DS, BX MOV BX, BIOS_SEG MOV [BX], AX ;Segmento del BIOS. MOV BX, MONITOR_SEG MOV [BX], AX ;Segmento del Monitor. MOV BX, BIOS_OFF MOV WORD PTR [BX], ENTRADA_BIOS ;Offset del BIOS. MOV BX, MONITOR_OFF MOV WORD PTR [BX], ENTRADA_MONITOR ;Offset del Mo nitor. ENTRADA_BIOS: ;ENTRADA DEL BIOS CLI ;Primero elimina todas las interrupciones y activa las necesarias. ;Desactiva todos los Chip-Select que se pudieron haber empleado XOR AX, AX MOV CX, NUM_CS MOV DX, INI_GCS0 ;Elimina Chip-Select 0 ELIMINA_CHIP_SELECT: INC DX INC DX IN AL, DX AND AX, 0FFF7H ;Los deshabilita OUT DX, AX INC DX INC DX LOOP ELIMINA_CHIP_SELECT MOV DX, INI_GCS1 ;Chip-Select GCS1 (DISPLAY ) MOV AX, 004FH ;Inicio: 40h, 15 edos. de espera. OUT DX, AL INC DX INC DX MOV AX, 0088H ;Fin: 80h. OUT DX, AL ;Fin de GCS1.

Page 182: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

177

MOV DX, INI_GCS0 ;Chip-Select GCS0 (SEGUNDA ROM) MOV AX, 040FH ;Inicia en 4000H con 15 edos de es pera. OUT DX, AL INC DX INC DX MOV AX, 080AH ;Termina en 8000H. Ciclos de MEM. OUT DX, AL ;*************************** SE REINICIA PILA ***** *********************** MOV SP, TAM_MEMORIA_RAM;Se usa todo el tama¤o de la RAM. XOR AX, AX MOV SS, AX MOV DS, AX ;************************************************** *********************** MOV DX, INT_MASK MOV AX, 00FFH ;Desactiva todas las interrupcione s. XOR AX, AX MOV DX, INT_INSERV OUT DX, AL ;Ninguna interrupcion en servicio. MOV DX, INT_INT_REQ OUT DX, AL ;Ninguna interrupcion en espera. MOV DX, SER0_CTRL OUT DX, AL ;Quitamos puerto serie 0 MOV DX, SER1_CTRL OUT DX, AL ;Quitamos puerto serie 1 MOV AX, 4000H MOV DX, TEMP_TMP0_CTRL OUT DX, AL ;Quitamos temporizador 0 MOV DX, TEMP_TMP1_CTRL OUT DX, AL ;Quitamos temporizador 1 MOV DX, TEMP_TMP2_CTRL OUT DX, AL ;Quitamos temporizador 2 CALL COLOCA_VECTORES ;Coloca los vectores por def ault. CALL RELOJ_REAL MOV BX, VELOCIDAD_DEPURADOR MOV BX, [BX] ;Velocidad con el depurador, por de fault 9600 CALL INICIA_COM_DEPURADOR CALL SER0_LIMPIAPUERTO CALL SER0_LIMPIACOLA MOV CX, DBGREG_NUMREG MOV BX, REGISTRO_AX XOR AX, AX LIMPIA_REGS: ;Borra el buffer de registros. MOV [BX], AX INC BX INC BX LOOP LIMPIA_REGS MOV BX, REGISTRO_SS MOV [BX], STAK_SEG ;Se fija el segmento de la pi la MOV BX, REGISTRO_SP MOV [BX], STAK_OFF ;Ahora el offset de la pila MOV BX, REGISTRO_CS MOV [BX], PROGRAMA_SEG ;Coloca el segmento MOV BX, REGISTRO_IP MOV [BX], PROGRAMA_OFF ;El offset de un programa MOV BX, REGISTRO_ES MOV [BX], PROGRAMA_SEG ;Coloca el segmento MOV BX, REGISTRO_DS MOV [BX], PROGRAMA_SEG ;Coloca el segmento MOV BX, REGISTRO_FLAG XOR AX, AX OR AX, BIT_INTERRUP MOV [BX], AX MOV BX, PILA_MONITOR ;Guarda el Offset de la Pil a. MOV [BX], STAK_OFF

Page 183: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

178

MOV BX, DISPLAY_BIOS MOV AL, [BX] MOV AH, 00H INT 10H ;Se limpia la pantalla Pantalla 16x2 p or default ;************************************************ ******************* ;KEYB ******************************************* ******************* ;SOLO PARA LA VERSION ANTERIOR DE TECLADO, SE USA BA CHIPSELECT0 ;INCLUDE "INITKEYB.ASM";Activa el teclado, solo p ara versi¢n anterior de la UAMI188EB ;************************************************ ******************* ;************************************************ ******************* MOV SP, TAM_MEMORIA_RAM;Se usa todo el tama¤o de la RAM. XOR AX, AX MOV SS, AX MOV AX, CS MOV DS, AX ;Fijamos el registro DS. MOV ES, AX ;Y el ES. MOV SI, MSGMONITOR_01 MOV AH, 03H INT 60H MOV BL, CMSOK CALL SER0_SENDE ;Se envia mensaje de cmsOK para i ndicar que esta listo ;************************************************** ******************** ;Las siguientes lineas son el nucleo del MONITOR ;************************************************** ******************** ENTRADA_MONITOR: ;ENTRADA DEL MONITOR STI ;Se activan interrupciones por hardware. CALL SER0_COLAVACIA ;La cola esta vacia? CMP AL, 01H JNE CONTINUA_MONITOREO;Llego un comando. JMP ENTRADA_MONITOR CONTINUA_MONITOREO: CALL SER0_OBTENDATO CALL MONITOREO ;Se procesan los comandos por el monitor JMP ENTRADA_MONITOR ;************************************************** ******************** ;AREA DE MENSAJES MSGMONITOR_01: DB "Esperando...", 00H ;************************************************** *********************** ;FIN DEL CODIGO DE MONITOREO ;************************************************** *********************** ;**************** CODIGO DE INTERRUPCIONES Y FUNCIO NES ******************* INCLUDE "INT00.ASM" ;Division entre CERO INCLUDE "INT01Y03.ASM" ;Para depuracion INCLUDE "INT04.ASM" ;Overflow INCLUDE "INT05.ASM" ;BOUND INCLUDE "INT06.ASM" ;Unused opcode INCLUDE "INT07.ASM" ;Escape opcode INCLUDE "INT10.ASM" ;Display INCLUDE "INT16.ASM" ;Teclado INCLUDE "INT19.ASM" ;Reinicio INCLUDE "INT1A.ASM" ;Reloj del sistema INCLUDE "INT1C.ASM" ;Ticks del reloj INCLUDE "INT20.ASM" ;MS-DOS INCLUDE "INT21.ASM" ;MS-DOS INCLUDE "INT27.ASM" ;MS-DOS INCLUDE "INT60.ASM" ;Utilidades INCLUDE "INT61Y62.ASM" ;Estado de equipo y memori a del sistema INCLUDE "INT63.ASM" ;Puerto serie INCLUDE "INT70.ASM" ;Temporizadores INCLUDE "INITVEC.ASM" ;Vectores de interrupcio n INCLUDE "KEYBOARD.ASM" ;Teclado (Solo para 8279) INCLUDE "RELOJ.ASM" ;Reloj (Temporizador 1) INCLUDE "SERIAL.ASM" ;Funciones de puerto seri e para el monitor

Page 184: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

179

INCLUDE "MONITOR.ASM" ;Funciones del monitor INCLUDE "ERRINT.ASM" ;Funcion para el error por INT INCLUDE "DEPURA.ASM" ;Funciones para depuracion ;************************************************** *********************** ACERCA_DE: DB "BIOS 1.00 Este programa contiene las rutinas de entrada-salida", 00H DB "(BIOS) y el programa de monitoreo (MONITOR), para comunicacion", 00H DB "con el programa D188.EXE. Desarrollado para l a UAMI188EB II. ", 00H DB "Agosto 2005.", 00H ;************************************************** *********************** ;El siguiente codigo es para una ROM de 16Kb ORG 03FF0H ;A los ultimos 16 bytes MOV DX, INI_ROM ;Inicio de la ROM. MOV AX, 0FC0FH ;En FC00:0000, con 15 estados de e spera. OUT DX, AL DB 0EAH DW 00000H DW 0FC00H DW 00100H ;Version del BIOS 1.00. DW 0E28DH ;Word de comprobacion de la ROM, SUMA DE ENTEROS. ;************************************************** *********************** ;************************************************** *********************** ;EL siguiente codigo es para una ROM de 8Kb ;ORG 01FF0H ;A los ultimos 16 bytes ;MOV DX, INI_ROM ;Inicio de la ROM. ;MOV AX, 0FE0FH ;En FC00:0000, con 15 estados de espera. ;OUT DX, AL ;DB 0EAH ;DW 00000H ;DW 0FE00H ;DW 00100H ;Version del BIOS 1.00. ;DW 0E66FH ;Word de comprobacion de la ROM, SUM A DE ENTEROS. ;************************************************** *********************** ;********************** FIN DE TODO EL CODIGO ***** *********************** ;************************************************** *********************** ;************************************************** ***********************

E.2 CONST.ASM ;EN ESTE ARCHIVO ESTAN CONTENIDOS LAS CONSTANTES EMPLEADAS ;POR TODO EL PROGRAMA BIOS (MONITOR), SOLO SE INCLU YEN COSAS GENERALES. ;SE ASUME QUE LA PILA YA NO SE HA INICIADO. ;************************************************** ********************** ;NOTAS: ; ; ; ;************************************************** ********************** ;CONSTANTES PARA CHIP-SELECT INI_ROM EQU 0FFA4H END_ROM EQU 0FFA6H INI_RAM EQU 0FFA0H END_RAM EQU 0FF42H INI_GCS0 EQU 0FF80H END_GCS0 EQU 0FF82H INI_GCS1 EQU 0FF84H END_GCS1 EQU 0FF86H INI_GCS2 EQU 0FF88H END_GCS2 EQU 0FF8AH NUM_CS EQU 00007H ;Numero de Chip-Select ;DIRECCIONES DE LOS REGISTROS DE INTERRUPCION DEL P CB INT_END_INT EQU 0FF02H INT_POLL EQU 0FF04H

Page 185: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

180

INT_POLL_ST EQU 0FF06H INT_MASK EQU 0FF08H INT_PRI_MSK EQU 0FF0AH INT_INSERV EQU 0FF0CH INT_INT_REQ EQU 0FF0EH INT_STATUS EQU 0FF10H INT_TIMER EQU 0FF12H INT_SERIAL EQU 0FF14H INT_INT4 EQU 0FF16H INT_INT0 EQU 0FF18H INT_INT1 EQU 0FF1AH INT_INT2 EQU 0FF1CH INT_INT3 EQU 0FF1EH ;CONSTANTES DE REGISTROS DE INTERRUPCION BITS_INSERV EQU 000FDH ;Bits del registro en serv icio. ;CONSTANTES EMPLEADAS POR EL DISPLAY. DSP_DATAREAD EQU 43H ;Lectura de datos. DSP_DATAWRITE EQU 41H ;Escritura de datos. DSP_COMMWRITE EQU 40H ;Escritura de comando. DSP_COMMREAD EQU 42H ;Lectura de comando. DSP_ON EQU 0CH ;Enciende display sin cursor . DSP_OFF EQU 08H ;Apaga el display. DSP_CLS EQU 01H ;Limpia display. DSP_DDRAM EQU 80H ;Direccion de la DDRAM, 1er r englon. DSP_INC EQU 06H ;Incrementa la CG o DD RAM . DSP_DEC EQU 04H ;Decrementa la CG o DD RAM . ;CONSTANTES DE LA MEMORIA TAM_MEMORIA_RAM EQU 2000H ;Si este valor cambia, cambiar la pila TAM_MEMORIA_RAMM EQU 1000H ;La mitad de la RAM ;Para una ROM de 16Kb TAM_MEMORIA_ROM EQU 4000H ;Para ROM 16Kb TAM_MEMORIA_ROM2 EQU 3FFEH ;Para ROM 16Kb INICIO_ROM EQU 0FC00H ;Para ROM 16Kb ;Para una ROM de 8Kb ;TAM_MEMORIA_ROM EQU 2000H ;Para ROM 8Kb ;TAM_MEMORIA_ROM2 EQU 1FFEH ;Para ROM 8Kb ;INICIO_ROM EQU 0FE00H ;Para ROM 8Kb ;NUMERO DE VECTOR DE INTERRUPCION PARA EXTERNAS VINT_TMR0 EQU 08 ;08H Temporizador 0 VINT_TMR1 EQU 18 ;12H Temporizador 1 VINT_TMR2 EQU 19 ;13H Temporizador 2 VINT_SRX EQU 20 ;14H Recepci¢n serial VINT_STX EQU 21 ;15H Transmisi¢n serial VINT_INT4 EQU 17 ;11H Int4 por hardware VINT_INT0 EQU 12 ;0CH Int0 por hardware VINT_INT1 EQU 13 ;0DH Int1 por hardware VINT_INT2 EQU 14 ;0EH Int2 por hardware VINT_INT3 EQU 15 ;0FH Int3 por hardware ;NUMERO DE VECTOR DE INTERRUPCION PARA INTERNAS O SOFTWARE VINT_00H EQU 00H ;Division entre CERO. VINT_01H EQU 01H ;Interrupcion de depuracion . VINT_03H EQU 03H ;Punto de ruptura. VINT_04H EQU 04H ;Overflow. VINT_05H EQU 05H ;BOUND VINT_06H EQU 06H ;Unused opcode. VINT_07H EQU 07H ;Escape opcode. VINT_10H EQU 10H ;Para el del display. VINT_16H EQU 16H ;Teclado. VINT_19H EQU 19H ;Reinicio del sistema. VINT_1AH EQU 1AH ;Funciones de reloj del sis tema. VINT_1CH EQU 1CH ;Ticks del reloj. VINT_20H EQU 20H ;Funciones tipo MS-DOS.

Page 186: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

181

VINT_21H EQU 21H ;Funciones tipo MS-DOS. VINT_27H EQU 27H ;Funciones tipo MS-DOS. VINT_60H EQU 60H ;Utilerias. VINT_61H EQU 61H ;Banderas de equipo. VINT_62H EQU 62H ;Tama¤o de memoria. VINT_63H EQU 63H ;Para el puerto serie. VINT_64H EQU 64H ;Procesa el comando "paso a paso" VINT_70H EQU 70H ;Para los temporizadores. ;TECLAS ESPECIALES KBACKSP EQU 08H ;Tecla retroceso (backspace). KENTER EQU 0DH ;Tecla de ENTER. KSPACE EQU 20H ;Tecla de espacio. ;NUMERO DE CARACTERES DEL TECLADO PARA EL DISPLAY KEY_CHARS EQU 0080H ;128 caracteres. ;CONSTANTES PARA EL RELOJ DE TIEMPO REAL RELOJ_CA EQU 0FFFEH ;Comparador A RELOJ_CB EQU 0E84AH ;Comparador B COMPARADOR_B EQU 01000H ;Bit del comparador en us o (1 = CB) RELOJ_LTICKS EQU 0A400H ;Maximo numero de ticks (baja) RELOJ_HTICKS EQU 0001FH ;Maximo numero de ticks (alta) RELOJ_TKSSEG EQU 018H ;Divisor para convertir T icks<->Segundos RELOJ_TKSMIN EQU 005A0H ;Divisor para convertir T icks<->Minutos RELOJ_MINHOR EQU 03CH ;Divisor para convertir M inutos<->Horas RELOJ_SEGMIN EQU 03CH ;Divisor para convertir Segundos<->Minutos ;CONSTANTES DE LOS TEMPORIZADORES TEMP_TMP0 EQU 0FF30H ;Inicio en el PCB del t emporizador 0 TEMP_TMP1 EQU 0FF38H ;Inicio en el PCB del t emporizador 1 TEMP_TMP2 EQU 0FF40H ;Inicio en el PCB del temporizador 2 TEMP_TMP0_CTRL EQU 0FF36H ;Registro de control de l temporizador 0 TEMP_TMP1_CTRL EQU 0FF3EH ;Registro de control de l temporizador 1 TEMP_TMP2_CTRL EQU 0FF46H ;Registro de control de l temporizador 2 ;CONSTANTES DE LOS SERIALES PCBSER_COM1 EQU 0FF60H ;Serial 0 PCBSER_COM2 EQU 0FF70H ;Serial 1 ;CONSTANES PARA EL TECLADO KEYB_BUFFER EQU 0041EH ;Inicio real del buffer de teclado. KEYB_IBUFFER EQU 0041AH ;Posicion de inicio de b uffer de teclado. KEYB_FBUFFER EQU 0043CH ;Posicion de fin de buff er de teclado. ;CONSTANTES DEL PUERTO SERIAL SER0_BAUD EQU 0FF60H ;Direcciones en el PCB SER0_CONT EQU 0FF62H SER0_CTRL EQU 0FF64H SER0_STAT EQU 0FF66H SER0_REC EQU 0FF68H SER0_TRAN EQU 0FF6AH SER1_CTRL EQU 0FF74H SERVEL_1200 EQU 084E1H ;Velocidades SERVEL_2400 EQU 08270H SERVEL_4800 EQU 08138H SERVEL_9600 EQU 0809BH SERVEL_19200 EQU 0804DH SERBUFFER_TAM EQU 0DH ;Tama¤o del buffer para interrupcion por recepcion SER_DEL_REQ EQU 0FFFBH ;Para borrar la solicitu d por INT. SER_DEL_STS EQU 0FFE7H ;Para borrar el estado d e la INT (trans y recev). ;CONTADOR TEMPORIZADOR TEMPORIZADOR_MAX EQU 07D0H ;Maximo 2000 segundos . ;CONSTANTES DE ESTADO DEL BIOS (SON LOS MISMO QUE L OS DEL INDICADOR-INDICA_XXX) BIOSEDO_OK EQU 00H ;Estado al inicio del sist ema.

Page 187: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

182

BIOSEDO_STP EQU 01H ;Programa cargado, pero no ejecutado. BIOSEDO_RUN EQU 02H ;Programa ejecutado. BIOSEDO_DBG EQU 04H ;Programa en depuracion. BIOSEDO_DSC EQU 08H ;La UAMI188EB se desconect o. ;MENSAJES ENTRE EL DEPURADOR Y LA UAMI188EB CMSNADA EQU 000H ;No hay ningun mensaje. CMSOK EQU 001H ;Mensaje de estado y acuerdo. CMSRESET EQU 002H ;Mensaje de reset d el sistema. CMSCARGA EQU 003H ;Mensaje para cargar p rograma a memoria. CMSEJECUTAR EQU 004H ;Ejecuta el programa carga do. CMSPASO EQU 005H ;Ejecuta paso a paso. CMSEND EQU 006H ;Termino el programa carga do. CMSERROR EQU 007H ;Termino el program a por un error. CMSOBTENMEM EQU 008H ;Obtiene memoria de la UA MI188EB. CMSMUEVEMEM EQU 009H ;Mueve memoria en la UAMI 188EB. CMSOBTENREG EQU 00AH ;Lee los registros de la UAMI188EB. CMSDETENER EQU 00BH ;Detiene el program a en ejecucion. CMSDESCONECT EQU 00CH ;La UAMI envia desc onecxion. CMSCONECTAR EQU 00DH ;La UAMI se conecta de nuevo. CMSOBTENRET EQU 00EH ;Obtiene el byte de retorn o de fin de programa. CMSOBTENERR EQU 00FH ;Obtiene el byte de error de fin de programa. CMSOBTENPRG EQU 010H ;Obtiene el programa de la UAMI188EB. CMSCARGAREG EQU 011H ;Cambia un registro en esp ecifico. CMSCARGAMEM EQU 012H ;Carga datos en la memori de la UAMI188EB. CMSACERCADE EQU 013H ;Mensaje de acerca de... CMSRESIDENTE EQU 014H ;Hay codigo residente. CMSFIJAHORA EQU 015H ;Fija la hora. CMSTEST EQU 0F0H ;Para prubebas. ;MENSAJES DE ERROR ENTRE UAMI188EB Y EL DEPURADOR CERRNINGUNO EQU 000H ;No hay error. CERRDIVCERO EQU 001H ;Division entre cero. CERROVERFLOW EQU 002H ;Overflow. CERRARRAY EQU 003H ;Array bounds exception. CERRUNUSED EQU 004H ;Unused opcode exception. CERRESCAPE EQU 005H ;Escape opcode exception. ;CONSTANTES ENTRE EL BIOS Y EL DEPURADOR UAMI188_D188_COM EQU 003BH ;Modo 3, paridad par ;CONSTANTES DE LOS BITS DEL REGISTRO DE BANDERAS BIT_TRAMPA EQU 00100H ;Bit de trampa. BIT_INTERRUP EQU 00200H ;Bit de interrupcion. NBIT_TRAMPA EQU 0FEFFH ;Para eliminar el bit de trampa ;CONSTANTES PARA EL BUFFER DE REGISTROS DBGREG_NUMREG EQU 0000EH ;Numero de registros e n buffer. ;CONSTANTES PARA CODIGO "RESIDENTE" TAM_BUFFER_CR EQU 0000AH ;Tama¤o de buffer en pr ogramas residentes (multiplos de 16 bytes). ;CONSTANTES DE LA SEGUNDA ROM ROM2_SEG EQU 00000H ;Segmento conrrespondiente a la ROM 2 ROM2_OFF EQU 04000H ;Offset conrrespondiente a la ROM 2

E.3 BIOSVARS.ASM ;CONTIENE LA DIRECCION DE MEMORIA DONDE SE ALMACENAN LAS VARIABLES USADAS ;POR EL BIOS. COM1_ADDRESS EQU 0400H ;2 bytes. COM2_ADDRESS EQU 0402H ;2 bytes. COM3_ADDRESS EQU 0404H ;2 bytes. COM4_ADDRESS EQU 0406H ;2 bytes. EQUIPMENT_FLAG EQU 0410H ;2 bytes. MEMORY_SIZE EQU 0413H ;2 bytes.

Page 188: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

183

KEYBOARD_STATUS_FLAG EQU 0417H ;2 bytes. KEYBOARD_BUFFER EQU 041AH ;36 bytes. KEY_END_TAIL EQU 00H ;Primer word esta la cola. KEY_INI_TAIL EQU 02H ;Segundo word esta la cabe za.. CURRENT_DISPLAY_MODE EQU 0449H ;1 byte. NUMBER_SCREEN_COLS EQU 044AH ;2 bytes. CURSOR_POSITION EQU 0450H ;2 bytes. CURRENT_CURSOR_MODE EQU 0460H ;2 bytes. NUMBER_ACTIVE_VID_PAG EQU 0462H ;1 byte. LWORD_TIMER EQU 046CH ;2 bytes. HWORD_TIMER EQU 046EH ;2 bytes. MIDNIGHT_FLAG EQU 0470H ;1 byte. START_KEYBOARD_DATA EQU 0480H ;2 bytes. ADD_KEYBOARD_DATA EQU 0002H ;Agregar a la dir eccion de datos. END_KEYBOARD_DATA EQU 0482H ;2 bytes. COMUNICATION_AREA EQU 04F0H ;16 bytes. COM_AREA_END_TAIL EQU 04F0H ;1 byte fin de la cola. COM_AREA_INI_TAIL EQU 04F1H ;1 byte ini cio de la cola. KEY_CARACTER EQU 0500H ;130 bytes. KEY_CARACTER_MAY EQU 0540H ;Direccion del buffer de mayusculas. KEY_CARACTER_DATA EQU 0580H ;2 bytes. D atos del inicio del teclado. KEY_CARACTER_DATA_CS EQU 0580H ;1 byte. Da tos Chip-Select. KEY_CARACTER_DATA_IT EQU 0581H ;1 byte. Da tos INT del teclado. TEMPORIZADOR EQU 0582H ;2 bytes. C ontador del temporizador. TEMPORIZADOR_FLAG EQU 0584H ;1 byte. Ba ndera del contador del temporizador. BUFFER_DISPLAY EQU 0588H ;40 bytes. Buffer donde se almacena momentaneamente PRIMERA LINEA DEL DISPLAY. BIOS_ESTADO EQU 05B0H ;1 byte. Banderas de estado del bios. VELOCIDAD_DEPURADOR EQU 05B1H ;2 bytes. V elocidad de comunicacion con el depurador. ESPERA_SERIAL EQU 05B3H ;1 byte. Segundos de espe ra del serial. BIOS_OFF EQU 05B4H ;2 bytes. Offset de entrada de l BIOS. BIOS_SEG EQU 05B6H ;2 bytes. Segmento de entrada del BIOS. MONITOR_OFF EQU 05B8H ;2 bytes. Offset de entrada al monitor. MONITOR_SEG EQU 05BAH ;2 bytes. Segmento de entra da al monitor. ;Registros del programa en ejecucion. ;Se podria pensar en llevar un orden, pero en algu nas situaciones no ;serviria; por lo que se deja como esta. REGISTRO_AX EQU 05BCH ;2 bytes. Registro AX REGISTRO_BX EQU 05BEH ;2 bytes. Registro BX REGISTRO_CX EQU 05C0H ;2 bytes. Registro CX REGISTRO_DX EQU 05C2H ;2 bytes. Registro DX REGISTRO_DI EQU 05C4H ;2 bytes. Registro SI REGISTRO_SI EQU 05C6H ;2 bytes. Registro DI REGISTRO_BP EQU 05C8H ;2 bytes. Registro BP REGISTRO_SP EQU 05CAH ;2 bytes. Registro SP REGISTRO_DS EQU 05CCH ;2 bytes. Registro CS REGISTRO_ES EQU 05CEH ;2 bytes. Registro DS REGISTRO_SS EQU 05D0H ;2 bytes. Registro ES REGISTRO_CS EQU 05D2H ;2 bytes. Registro SS REGISTRO_IP EQU 05D4H ;2 bytes. Registro IP REGISTRO_FLAG EQU 05D6H ;2 bytes. Registro FLAG RETURN_END EQU 05DAH ;1 byte. Codigo d e retorno. RETURN_ERR EQU 05DBH ;1 byte. Codigo de error por interrupcion. DISPLAY_BIOS EQU 05DDH ;1 byte. Valor del tipo de display. PILA_MONITOR EQU 05DEH ;2 bytes. Offset de la pil a, para uso del monitor. MEMORIA_MONITOR EQU 0600H ;100H bytes. Area de mem oria del monitor. MEM_DEPURA EQU 0690H ;Memoria para depuracion d el BIOS. PROGRAMA_SEG EQU 0070H ;Segmento d onde inician los programas. PROGRAMA_OFF EQU 0000H ;Este es el offset STAK_SEG EQU 0000H ;Se fija el segmento de la p ila. STAK_OFF EQU TAM_MEMORIA_RAM ;Esta es el offset, se fija toda la RAM ;************************************************** ******************* ;NOTAS: EL BUFFER DE TECLADO FUNCIONA COMO UNA COLA CIRCULAR. LA COLA ;ESTA INDICADA POR EL PRIMER WORD DEL BUFFER, LA CA BEZA ES EL SEGUNDO ;WORD. LA CABEZA PUEDE ALCANZAR A LA COLA, EN CUYO CASO LA COLA ESTARIA

Page 189: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

184

;VACIA; PERO LA COLA NO PUEDE ALCANZAR A LA CABEZA, EN CUYO CASO LA ;COLA ESTARIA LLENA, NO SE PUEDEN AGREGAR MAS CARACTERES Y ESTOS SE ;PERDERIAN. ;DE IGUAL FORMA FUNCIONA EL AREA DE COMUNICACIONES, SIN EMBARGO, AQUI ;GUARDA LA POSICION LOCAL; ES DECIR, LOS APUNTADORE S VAN DEL 0 AL 13. ;************************************************** *******************

E.4 CHIPSEL.ASM ;EN ESTE ARCHIVO ESTAN CONTENIDOS TODOS LOS PROCEDIMIENTOS ;NECESARIOS PARA EL MANEJO DE LOS CHIPSELECT. ;SE ASUME QUE LA PILA YA NO SE HA INICIADO. ;************************************************** ********************** ;NOTAS: SE EMPLEAN LOS REGISTROS AX Y DX. ; ; ; ;************************************************** ********************** ;INICIA LA ACTIVACION DE LOS CHIP-SELET. INC DX INC DX MOV AX, 0FFCEh OUT DX, AL ;Fin de ROM MOV DX, INI_RAM ;Inicio de la RAM. MOV AX, 000Fh OUT DX, AL INC DX INC DX MOV AX, 020Ah ;Fin de RAM 2000h (8Kb) OUT DX, AL ;Se programa el Chip-Select GCS1 (DISPLAY). MOV DX, INI_GCS1 ;Chip Select GCS1. MOV AX, 004FH ;Inicio: 40h, 15 edos. de espera. OUT DX, AL INC DX INC DX MOV AX, 0088H ;Fin: 80h. I/O. OUT DX, AL ;Fin de GCS1. ;Se programa el Chip-Select GCS0 (SEGUNDA ROM). MOV DX, INI_GCS0 MOV AX, 040FH ;Inicia en 4000H con 15 edos de es pera. OUT DX, AL INC DX INC DX MOV AX, 080AH ;Termina en 8000H. Ciclos de MEM. OUT DX, AL ;FIN DE ACTIVACION DE LOS CHIP-SELET

E.5 INITDSP.ASM ;EN ESTE ARCHIVO ESTAN CONTENIDOS TODO EL CODIGO NECESARIO ;PARA EL MANEJO DEL DISPLAY SIN PILA. ;SE ASUME QUE LA PILA NO SE HA INICIADO. ;************************************************** ********************** ;NOTAS: EL DISPLAY POR DEFAULT ES A 16x2. ;SE EMPLEA EL REGISTRO AX Y CX. ; ; ;************************************************** ********************** ;INICIA EL DISPLAY. MOV CX, 2000H ESPERA_DSP: LOOP ESPERA_DSP ;Para esperar al display.

Page 190: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

185

MOV AL, DSP_ON OUT DSP_COMMWRITE, AL ;Enciende el display. ESPERA_FLAG1: IN AL, DSP_COMMREAD RCL AL, 1 JC ESPERA_FLAG1 MOV AL, 38H OUT DSP_COMMWRITE, AL ;Dos renglones, 8 bits. ESPERA_FLAG2: IN AL, DSP_COMMREAD RCL AL, 1 JC ESPERA_FLAG2 MOV AL, DSP_INC OUT DSP_COMMWRITE, AL ;Incrementa la memoria del display. ESPERA_FLAG3: IN AL, DSP_COMMREAD RCL AL, 1 JC ESPERA_FLAG3 MOV AL, 01H OUT DSP_COMMWRITE, AL ;Limpia el display. ESPERA_FLAG4: IN AL, DSP_COMMREAD RCL AL, 1 JC ESPERA_FLAG4 ;TERMINA EL DISPLAY.

E.6 CHKMEM.ASM ;EN ESTE ARCHIVO ESTAN CONTENIDOS TODO EL CODIGO PARA LA VERIFICACION ;DE LA MEMORIA. ;SE ASUME QUE EL DISPLAY YA SE INICIO, NO SE USA PI LA. ;************************************************** ********************** ;NOTAS: SE EMPLEAN TODOS LOS REGISTROS. ;SE REVISAN EN WORDS, NO EN BYTES. AL FINAL BP TIEN E EL ERROR EB RAM O ;ROM CON LOS SIGUIENTES BITS. ; BIT 1 BIT 0 SIGNIFICADO ; 0 0 MEMORIA OK ; 0 1 ERROR EN RAM ; 1 0 ERROR EN ROM ; 1 1 ERROR EN RAM Y ROM ;************************************************** ********************** ;INICIA LA REVISION DE AMBAS MEMORIAS. MOV AX, CS MOV ES, AX MOV AL, 01H OUT DSP_COMMWRITE, AL ;BORRA LA PANTALLA. CHKMEM00: IN AL, DSP_COMMREAD RCL AL, 1 JC CHKMEM00 MOV BX, MSG_01 ;Mensaje: CHK. MEM. MOV AL, 00H ;Fijamos la posicion SHL AL, 06H OR AL, 00H OR AL, 80H OUT DSP_COMMWRITE, AL CHKMEM04: IN AL, DSP_COMMREAD RCL AL, 1 JC CHKMEM04 CHKMEM02: MOV AL, ES:[BX] AND AL, AL JZ CHKMEM01 OUT DSP_DATAWRITE, AL ;Imprime el dato. CHKMEM03: IN AL, DSP_COMMREAD

Page 191: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

186

RCL AL, 1 JC CHKMEM03 INC BX JMP CHKMEM02 CHKMEM01: MOV BX, MSG_02 ;Mensaje: BYTES. MOV AL, 01H SHL AL, 06H OR AL, 06H OR AL, 80H OUT DSP_COMMWRITE, AL CHKMEM08: IN AL, DSP_COMMREAD RCL AL, 1 JC CHKMEM08 CHKMEM06: MOV AL, ES:[BX] AND AL, AL JZ CHKMEM05 OUT DSP_DATAWRITE, AL ;Imprime el dato. CHKMEM07: IN AL, DSP_COMMREAD RCL AL, 1 JC CHKMEM07 INC BX JMP CHKMEM06 CHKMEM05: ;Primero hace un revision normal MOV CX, TAM_MEMORIA_RAMM XOR BP, BP ;Aqui se guardan los errores. XOR DI, DI XOR AX, AX MOV ES, AX ;Se inician ambos registros de segme nto. MOV DS, AX CLD ;Incrementa DI. REP STOSW ;Llena de cero's. DEC DI DEC DI STD ;Decrementa DI. MOV CX, TAM_MEMORIA_RAMM REP SCASW ;Compara JZ CHKMEM_RAMOK ;La ram esta bien. INC BP ;Se imcrementa BP, hay un error. CHKMEM_RAMOK: MOV CX, TAM_MEMORIA_RAMM NOT AX XOR DI, DI CLD ;Incrementa DI. REP STOSW ;Llena de unos's. XOR DI, DI ;Contador de la memoria. CHKMEM_CHK: MOV BX, DI MOV AL, 01H SHL AL, 06H OR AL, 00H OR AL, 80H OUT DSP_COMMWRITE, AL CHKMEM15: IN AL, DSP_COMMREAD RCL AL, 1 JC CHKMEM15 XOR CX, CX ;Corrimiento MOV AX, BX ;Colocamos el divisor. XOR BX, BX ;Se coloca el numero convertido. MOV SI, 0AH ;Contador CHKMEM10: XOR DX, DX ;Residuo. DIV SI ;Obtenemos el primer digito.

Page 192: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

187

AND DX, 0FH ;Buscamos el digito. SHL DX, CL ;Lo recorremos. OR BX, DX ;Ya esta el numero. ADD CL, 04H ;Siguiente recorrido. AND AX, AX JZ CHKMEM09 CMP CL, 10H ;Solo cuatro digitos de cinco digito s. JNE CHKMEM10 CHKMEM09: ADD AL, 30H ;El ultimo digito. OUT DSP_DATAWRITE, AL ;Imprime el dato. CHKMEM13: IN AL, DSP_COMMREAD RCL AL, 1 JC CHKMEM13 MOV CX, 04H ;Corrimiento. CHKMEM11: MOV AL, BH AND AL, 0F0H ;Obtenemos los 4 bits. SHR AL, 04H ;Los recorremos. ADD AL, 30H ;Por si es un numero. CMP AL, 3AH ;Es una letra? JBE CHKMEM12 ADD AL, 07H ;Para convertirlo a letra. CHKMEM12: OUT DSP_DATAWRITE, AL ;Imprime el dato. CHKMEM14: IN AL, DSP_COMMREAD RCL AL, 1 JC CHKMEM14 SHL BX, 04H ;Siguiente numero. LOOP CHKMEM11 CMP WORD PTR [DI], 0FFFFH ;Compara los unos que p uso. JNZ CHKMEM_ERRORRAM INC DI INC DI CMP DI, TAM_MEMORIA_RAM JNB CHKMEM_CONTINUA_ROM JMP CHKMEM_CHK ;Continua con la revision. CHKMEM_ERRORRAM: AND BP, BP JNZ CHKMEM_CONTINUA_ROM INC BP CHKMEM_CONTINUA_ROM: ;Inicia la revision de ROM. CLD XOR DI, DI MOV AX, INICIO_ROM ;Ahora sigue la ROM. MOV DS, AX XOR AX, AX CHKMEM_CHK_ROM: MOV BX, DI ADD BX, TAM_MEMORIA_RAM MOV ES, AX ;Se usa como buffer el registro ES. MOV AL, 01H SHL AL, 06H OR AL, 00H OR AL, 80H OUT DSP_COMMWRITE, AL CHKMEM22: IN AL, DSP_COMMREAD RCL AL, 1 JC CHKMEM22 XOR CX, CX ;Corrimiento MOV AX, BX ;Colocamos el divisor. XOR BX, BX ;Se coloca el numero convertido. MOV SI, 0AH ;Contador CHKMEM17: XOR DX, DX ;Residuo. DIV SI ;Obtenemos el primer digito. AND DX, 0FH ;Buscamos el digito. SHL DX, CL ;Lo recorremos.

Page 193: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

188

OR BX, DX ;Ya esta el numero. ADD CL, 04H ;Siguiente recorrido. AND AX, AX JZ CHKMEM16 CMP CL, 10H ;Solo cuatro digitos de cinco digito s. JNE CHKMEM17 CHKMEM16: ADD AL, 30H ;El ultimo digito. OUT DSP_DATAWRITE, AL ;Imprime el dato. CHKMEM20: IN AL, DSP_COMMREAD RCL AL, 1 JC CHKMEM20 MOV CX, 04H ;Corrimiento. CHKMEM18: MOV AL, BH AND AL, 0F0H ;Obtenemos los 4 bits. SHR AL, 04H ;Los recorremos. ADD AL, 30H ;Por si es un numero. CMP AL, 3AH ;Es una letra? JBE CHKMEM19 ADD AL, 07H ;Para convertirlo a letra. CHKMEM19: OUT DSP_DATAWRITE, AL ;Imprime el dato. CHKMEM21: IN AL, DSP_COMMREAD RCL AL, 1 JC CHKMEM21 SHL BX, 04H ;Siguiente numero. LOOP CHKMEM18 MOV AX, ES MOV CX, [DI] ;Para seguir con el conteo. INC DI INC DI ADD AX, CX ;Hace la suma. CMP DI, TAM_MEMORIA_ROM2 ;Ultimos 2 bytes tienen el conteo. JNB CHKMEM_TERMINA JMP CHKMEM_CHK_ROM ;Continua con la revision. CHKMEM_TERMINA: MOV CX, [DI] CMP AX, CX ;La comparacion. JE CHKMEM_EXIT ;Termino de revisar la ROM. OR BP, 02H ;Error de ROM. CHKMEM_EXIT: MOV AX, BP ;Recuperamos los errores. MOV BX, MSG_03 ;Direccion base. MOV CL, 10H ;Longitud de cada mensaje. MUL CL ADD BX, AX ;Tenemos el OFFSET REAL. MOV AX, CS MOV ES, AX MOV DS, AX MOV AL, 00H SHL AL, 06H OR AL, 00H OR AL, 80H OUT DSP_COMMWRITE, AL CHKMEM27: IN AL, DSP_COMMREAD RCL AL, 1 JC CHKMEM27 CHKMEM25: MOV AL, ES:[BX] AND AL, AL JZ CHKMEM24 OUT DSP_DATAWRITE, AL ;Imprime el dato. CHKMEM26: IN AL, DSP_COMMREAD RCL AL, 01H JC CHKMEM26 INC BX

Page 194: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

189

JMP CHKMEM25 CHKMEM24: AND BP, BP JZ CHKMEM_JMP_MENSAJES HLT ;TERMINO CON UN ERROR, NO PUEDE CONTINUAR. MSG_01: DB "Rev. Memoria: ", 0 MSG_02: DB "bytes. ", 0 MSG_03: DB "MEMORIA BIEN ", 0 MSG_04: DB "ERROR EN RAM ", 0 MSG_05: DB "ERROR EN ROM ", 0 MSG_06: DB "RAM-ROM ERROR ", 0 CHKMEM_JMP_MENSAJES: ;TERMINA LA REVISION.

E.7 INITVARS.ASM ;AQUI SE ASIGNAN LOS VALORES INICIALES A LAS VARIAB LES. ;SE ASUME QUE LA PILA SE HA INICIADO. ;************************************************** ********************** ;NOTAS: SE ASIGNA AL REGISTRO DS=0000H, NO SE SALVA . ;SI SE MODIFICA ALGO DEL DISPLAY, VER ARCHIVO INITD SP.ASM ;SE USAN LOS REGISTROS BX, CX Y DS. ; ;************************************************** ********************** ;************************************************** ********************** ;ESTA ZONA ES PARA DEFINIR LO QUE SERA EL VALOR LAS VARIABLES QUE ;CONFIGURAN AL BIOS Y EL MONITOR PARA EL DEPURADOR. INIT_NULL EQU 00H INIT_MEM EQU 08H ;8Kb de memoria. INIT_DISPLAY EQU 01H ;Display inicial de 16x2 . INIT_COLROW EQU 00210H ;2 renglones 16 columna s. INIT_ESPERAS EQU 03H ;3 segundos de espera al serial VEL_SERIAL EQU SERVEL_19200 ;Velocidad default ;************************************************** ********************** ;Inicia la asignacion de las variables que usa el BIOS. PUSH DS XOR BX, BX MOV DS, BX MOV BX, COM1_ADDRESS ;Direccion PCB de los seria les. MOV WORD PTR [BX], PCBSER_COM1;COM1 INC BX INC BX MOV WORD PTR [BX], PCBSER_COM2;COM2 INC BX INC BX MOV WORD PTR [BX], INIT_NULL ;COM3 INC BX INC BX MOV WORD PTR [BX], INIT_NULL ;COM4 MOV BX, EQUIPMENT_FLAG ;Banderas de equipo. MOV WORD PTR [BX], INIT_NULL ;8K de memoria y 16 x2. MOV BX, MEMORY_SIZE MOV WORD PTR [BX], INIT_MEM MOV BX, KEYBOARD_STATUS_FLAG ;Banderas del teclad o, nada presionado. MOV WORD PTR [BX], INIT_NULL MOV BX, KEYBOARD_BUFFER ;Buffer de teclado. MOV WORD PTR [BX], KEYB_BUFFER;Fin de cola de tec lado. INC BX

Page 195: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

190

INC BX MOV WORD PTR [BX], KEYB_BUFFER;Inicio de cola de teclado. ;Inicio y fin son iguales, ya que la cola esta va cia MOV BX, CURRENT_DISPLAY_MODE ;Display actual 16x2 . MOV BYTE PTR [BX], INIT_DISPLAY MOV BX, NUMBER_SCREEN_COLS ;Numero de columnas y renglones del display. MOV WORD PTR [BX], INIT_COLROW MOV BX, CURSOR_POSITION MOV WORD PTR [BX], INIT_NULL ;Posicion del cursor X=0, Y=0. MOV BX, CURRENT_CURSOR_MODE ;Sin cursor. MOV BYTE PTR [BX], INIT_NULL MOV BX, NUMBER_ACTIVE_VID_PAG ;Siempre es cero la pagina de video. MOV BYTE PTR [BX], INIT_NULL MOV BX, LWORD_TIMER MOV WORD PTR [BX], INIT_NULL ;Palabra baja del t imer = 0 INC BX INC BX MOV WORD PTR [BX], INIT_NULL ;Palabra alta del t imer = 0 INC BX INC BX MOV WORD PTR [BX], INIT_NULL ;Bandera de media n oche = 0 MOV BX, START_KEYBOARD_DATA ;Inicio del buffer de teclado MOV WORD PTR [BX], KEYB_IBUFFER INC BX INC BX MOV WORD PTR [BX], KEYB_FBUFFER;Fin del buffer de teclado. MOV BX, COMUNICATION_AREA MOV BYTE PTR [BX], INIT_NULL ;Fin de la cola INC BX MOV BYTE PTR [BX], INIT_NULL ;Inicio de la cola MOV BX, BIOS_ESTADO MOV BYTE PTR [BX], BIOSEDO_OK ;Estado del bios BI OSEDO_OK MOV BX, VELOCIDAD_DEPURADOR MOV WORD PTR [BX], VEL_SERIAL ;Velocidad con el d epurador, por default 19200 MOV BX, ESPERA_SERIAL MOV BYTE PTR [BX], INIT_ESPERAS MOV BX, BIOS_OFF INITREG_INICIA: MOV [BX], INIT_NULL CMP BX, REGISTRO_FLAG JE INITREG_TERMINA INC BX INC BX JMP INITREG_INICIA INITREG_TERMINA: MOV BX, REGISTRO_SS MOV WORD PTR [BX], INIT_NULL MOV BX, REGISTRO_SS MOV [BX], STAK_SEG MOV BX, REGISTRO_SP MOV [BX], STAK_OFF MOV BX, REGISTRO_CS MOV [BX], PROGRAMA_SEG ;Coloca el segmento MOV BX, REGISTRO_IP MOV [BX], PROGRAMA_OFF ;El offset de un programa MOV BX, REGISTRO_ES MOV [BX], PROGRAMA_SEG ;Coloca el segmento MOV BX, REGISTRO_DS MOV [BX], PROGRAMA_SEG ;Coloca el segmento MOV BX, RETURN_END MOV [BX], INIT_NULL ;Codigo de fin de programa. MOV BX, RETURN_ERR MOV [BX], CERRNINGUNO ;Numero de error por inter rupcion MOV BX, DISPLAY_BIOS MOV BYTE PTR [BX], INIT_DISPLAY;Para cambiar el d isplay del BIOS. MOV BX, MEMORIA_MONITOR ;Area de memoria del moni tor, puede tener cualquier cosa. MOV [BX], INIT_NULL MOV BX, MEM_DEPURA MOV WORD PTR [BX], INIT_NULL INC BX INC BX

Page 196: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

191

MOV WORD PTR [BX], INIT_NULL POP DS ;Termina la asignacion de las variables que usa e l BIOS.

E.8 INITVEC.ASM ;EN ESTE ARCHIVO ESTAN CONTENIDOS EL CODIGO NECESARIO PARA ;ACCEDER A LOS VERCTORES DE INTERRUPCION DEFINIDOS POR EL ;USUARIO QUE SE EMPLEARAN EN EL BIOS. ;SE ASUME QUE LA PILA YA SE HA INICIADO. ;************************************************** ********************** ;NOTAS: EL REGISTRO SE MODIFICA EL DS HACIENDOLO IG UAL A CS. ;SE EMPLEA EL REGISTRO AX, DX Y DS. ; ; ;************************************************** ********************** ;INICIA LA COLOCACION DE LOS VECTORES DE INTERRUPCI ON POR SOFTWARE. COLOCA_VECTORES PROC PUSH AX PUSH DX PUSH DS PUSH CS POP DS ;************************* POR SOFTWARE *********** ****************** ;Division entre cero MOV DX, INTERRUPT_INT00H MOV AL, VINT_00H CALL INT21H_25H ;Depuracion MOV DX, INTERRUPT_INT01H MOV AL, VINT_01H CALL INT21H_25H ;Punto de ruptura MOV DX, INTERRUPT_INT03H MOV AL, VINT_03H CALL INT21H_25H ;Overflow MOV DX, INTERRUPT_INT04H MOV AL, VINT_04H CALL INT21H_25H ;BOUND MOV DX, INTERRUPT_INT05H MOV AL, VINT_05H CALL INT21H_25H ;Unused opcode MOV DX, INTERRUPT_INT06H MOV AL, VINT_06H CALL INT21H_25H ;Escape opcode MOV DX, INTERRUPT_INT07H MOV AL, VINT_07H CALL INT21H_25H ;Se inicia el display. MOV DX, INTERRUPT_INT10H MOV AL, VINT_10H CALL INT21H_25H ;Teclado. MOV DX, INTERRUPT_INT16H MOV AL, VINT_16H CALL INT21H_25H ;Reset del sistema. MOV DX, INTERRUPT_INT19H MOV AL, VINT_19H CALL INT21H_25H ;Reloj del sistema.

Page 197: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

192

MOV DX, INTERRUPT_INT1AH MOV AL, VINT_1AH CALL INT21H_25H ;Ticks del reloj. MOV DX, INTERRUPT_INT1CH MOV AL, VINT_1CH CALL INT21H_25H ;MS-DOS. MOV DX, INTERRUPT_INT20H MOV AL, VINT_20H CALL INT21H_25H ;MS-DOS. MOV DX, INTERRUPT_INT21H MOV AL, VINT_21H CALL INT21H_25H ;MS-DOS. MOV DX, INTERRUPT_INT27H MOV AL, VINT_27H CALL INT21H_25H ;Utilerias. MOV DX, INTERRUPT_INT60H MOV AL, VINT_60H CALL INT21H_25H ;Las banderas de equipo. MOV DX, INTERRUPT_INT61H MOV AL, VINT_61H CALL INT21H_25H ;Tama¤o de memoria MOV DX, INTERRUPT_INT62H MOV AL, VINT_62H CALL INT21H_25H ;Puerto serie. MOV DX, INTERRUPT_INT63H MOV AL, VINT_63H CALL INT21H_25H ;Para ejecucion paso a pas MOV DX, INTERRUPT_INT64H MOV AL, VINT_64H CALL INT21H_25H ;Temporizadores. MOV DX, INTERRUPT_INT70H MOV AL, VINT_70H CALL INT21H_25H ;************************* POR HARDWARE *********** ****************** ;El vector de los ticks del reloj. MOV DX, INTERRUPT_RELOJ_T1 MOV AL, VINT_TMR1 CALL INT21H_25H ;El vector de interrupcion en transmision y recep cion con el depurador. MOV DX, INTERRUPT_TX_SERIAL0 MOV AL, VINT_STX CALL INT21H_25H ;Vector para transmision MOV DX, INTERRUPT_RX_SERIAL0 MOV AL, VINT_SRX CALL INT21H_25H ;Vector para recepcion ;************************************************ ****************** ;KEYB ******************************************* ****************** ;SOLO PARA TECLADO CON LA OTRA UAMI188EB ;MOV DX, INTERRUPT_KEY_8279 ;MOV AL, VINT_INT1 ;CALL INT21H_25H ;Vector para teclado ;************************************************ ****************** POP DS POP DX POP AX RET ENDP ;FIN DE COLOCACION DE VECTORES.

Page 198: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

193

E.9 INITHARD.ASM ;EN ESTE ARCHIVO ESTAN CONTENIDOS EL CODIGO NECESARIO PARA ;ACTIVAR LOS PERIFERICOS DE LA TARJETA, PUERTO SERI AL, TECLADO; ASI ;COMO TAMBIEN SUS REPECTIVAS INTERRUPCIONES POR HARDWARE. ;SE ASUME QUE LA PILA YA SE HA INICIADO. ;************************************************** ********************** ;NOTAS: EL REGISTRO SE MODIFICA EL DS HACIENDOLO IG UAL A CS. ;SE EMPLEA EL REGISTRO AX, BX, DX Y CX. SI ALGO SE MODIFICA, HAY QUE ;ASEGURARSE DE QUE SE MODIFIQUE EL VECTOR DE INTERRUPCION EN EL ARCHIVO ;INITVEC.ASM ;************************************************** ********************** ;************************************************ ********************** ;Se inicia el temporizador 1 como reloj del siste ma (reloj tiempo real) CALL RELOJ_REAL ;************************************************ ********************** ;Ahora se inicia el puerto serie. PUSH DS XOR BX, BX MOV DS, BX MOV BX, VELOCIDAD_DEPURADOR MOV BX, [BX] ;Velocidad con el depurador, por de fault 19200 POP DS CALL INICIA_COM_DEPURADOR ;************************************************ ********************** ;Continua con la carga del BIOS

E.10 INITKEYB.ASM ;CONTIENE EL CODIGO PARA INICIAR EL TECLADO CON EL 8279. ;************************************************** ********************** ;NOTAS: SE ASUME QUE LA PILA YA SE INICIO ; ; ; ;************************************************** ********************** ;*********** PARA ACTIVAR EL TECLADO DESDE EL PRINC IPIO ************ MOV AL, 00H ;Chip-Select 0 MOV BH, 1FH ;Divisor de frecuencia. MOV BL, 02H ;Modo del 8279. MOV CH, 00H ;INT0 MOV AH, 08H INT 60H ;Activa el teclado. ;************************************************** ***************** ;En algunos 8279, esposible que no funcienen bien debido a lo rapido ;del reloj; es decir, el reloj del CPU = 12MHz, c on el divisor serian ;380KHz, y el 8279 trabaja con 100MHz. Dos soluci ones a este problema ;son: ; ;- Colocar dos divisores de frencuencia antes de la entrada del reloj ; del 8279; con esto se tiene 3MHz y simplemente dividimos entre 30. ;- Usar el temporizador 0 como reloj; seleccionam os una frecuencia de ; 300KHz y dividimos entre 3. Esta solucion se m uestra en las siguientes ; lineas. ;MOV AL, 03H ;Control del temporizador 0. ;XOR SI, SI ;Contador en cero. ;MOV BX, 05H ;300KHz. ;MOV CX, 05H ;MOV AH, 00H ;INT 70H ;************************************************** *****************

E.11 INT00.ASM ;EN ESTE ARCHIVO ESTAN CONTENIDOS TODOS LOS PROCEDIMIENTOS ;NECESARIOS PARA EL MANEJO DE LA INTERRUPCION 00H.

Page 199: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

194

;SE ASUME QUE LA PILA YA SE HA INICIADO. ;************************************************** ********************** ;NOTAS: ; ; ; ;************************************************** ********************** INTERRUPT_INT00H PROC ;Regresa el control al mon itor, division entre cero. MOV CL, CERRDIVCERO CALL PROCESA_ERR_INT ENDP

E.12 INT01Y03.ASM ;EN ESTE ARCHIVO ESTAN CONTENIDOS TODOS LOS PROCEDIMIENTOS ;NECESARIOS PARA EL MANEJO DE LA INTERRUPCION 19H. ;SE ASUME QUE LA PILA YA SE HA INICIADO. ;************************************************** ********************** ;NOTAS: EN ESENCIA INT 01H E INT 03H TIENEN LA MIS MA FINALIDAD, PERO ;DEBIDO A SU NATURALEZA, EL CODIGO ES DIFERENTE. LA INTERRUPCION INT 01H ;ES MUY SUSCEPTIBLE DE MAL FUNCIONAMIENTO SI SE MOD IFICA LA PILA. ; ;************************************************** ********************** ;LA INT 01H ES LA QUE SE ENCARGA DEL TRAZADO; ES DE CIR, CUANDO SE ACTIVA ;LA BANDERA DE TRAMPA, ESTA SE EJECUTA CADA INSTRUC CION. SI LA INSTRUCCION ;ES UNA INT, LA INTERRUPCION DE TRAMPA SE ACTIVA HA STA LA SIGUIENTE ;INSTRUCCION A INT. LA INTERRUPCION DE TRAMPA PERMI TE QUE SE EJECUTEN ;INTERRUPCIONES DE HARDWARE ANTES DE QUE SEA EJECUTADA LA INTERRUPCION EN ;CUESTION, SI LA INTERRUPCION ENTRA INMEDIATAMENTE DESPUES DE QUE SE HA ;EJECUTADO LA INSTRUCCION, SE DARA POR TERMINADA LA INTERRUPCION. ;LA INT 03, ES PARA QUE SE USARSE COMO UN PUNTO DE RUPTURA; SIN EMBARGO, ;ESTO SE DEBE HACER DE FORMA MANUAL, EL PROGRAMADOR DEBERA COLOCAR ESTA ;INSTRUCCION DENTRO DE SU CODIGO, EN DONDE DESEE QUE SE INICIE EL TRAZADO. ;************************************************** ********************** INTERRUPT_INT01H PROC ;Regresa el control al monit or. PUSH AX PUSH BX PUSH DX PUSH BP PUSH DS MOV BP, SP ;Para evitar que NO entre por INT de software ADD BP, 0EH ;Para posicion en FLAG MOV DX, [BP] AND DX, BIT_TRAMPA ;Bit de trampa activo? JNZ INTERRUPT_INT01H_CONTINUA ;No hay interrupcio n, se ejecuto instruccion MOV DX, INT_INSERV ;Vemos si es de hardware o so ftware IN AL, DX AND AX, BITS_INSERV ;Para obtener solo los bits en servicio JNZ INTERRUPT_INT01H_HARDWARE ;Es de hardware, la terminamos y continuamos INTERRUPT_INT01H_EJEC_INT: POP DS POP BP ;Como es de software se ejecuta y CONTIN UA POP DX ;con la siguiente instruccion. POP BX POP AX IRET INTERRUPT_INT01H_HARDWARE: ;Es interrupcion de hard ware MOV BP, SP ADD BP, 10H ;Comparamos el IP XOR AX, AX MOV DS, AX MOV BX, REGISTRO_IP MOV AX, [BP] MOV DX, [BX] CMP AX, DX JE INTERRUPT_INT01H_EJEC_INT ;IP no ha cambiado, permite la ejecucion

Page 200: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

195

MOV DX, INT_END_INT ;Fin de interrupcion no espe cifica MOV AX, 8000H OUT DX, AL POP DS POP BP POP DX POP BX POP AX ADD SP, 06H JMP INTERRUPT_INT01H_CONTINUA1 INTERRUPT_INT01H_CONTINUA: POP DS POP BP POP DX POP BX POP AX INTERRUPT_INT01H_CONTINUA1: PUSH DS PUSH BX PUSH AX XOR AX, AX MOV DS, AX POP AX MOV BX, REGISTRO_BX POP [BX] ;Guarda BX MOV BX, REGISTRO_DS POP [BX] ;Guarda DS MOV BX, REGISTRO_AX MOV [BX], AX ;Guarda AX INC BX INC BX INC BX INC BX MOV [BX], CX ;Guarda CX INC BX INC BX MOV [BX], DX ;Guarda DX INC BX INC BX MOV [BX], DI ;Guarda DI INC BX INC BX MOV [BX], SI ;Guarda SI INC BX INC BX MOV [BX], BP ;Guarda BP MOV BX, REGISTRO_ES MOV [BX], ES ;Guarda ES MOV BX, REGISTRO_IP POP [BX] MOV BX, REGISTRO_CS POP [BX] MOV BX, REGISTRO_FLAG POP [BX] MOV BX, REGISTRO_SS MOV [BX], SS ;Guarda SS MOV BX, REGISTRO_SP MOV [BX], SP ;Guarda SP ;Ya se pueden usar la mayoria de los registros MOV BX, BIOS_ESTADO MOV BYTE PTR [BX], BIOSEDO_DBG XOR AX, AX MOV DS, AX OR AX, BIT_INTERRUP PUSH AX ;Banderas MOV BX, MONITOR_SEG PUSH [BX] ;Segmento MOV BX, MONITOR_OFF PUSH [BX] ;Offset MOV BL, CMSPASO

Page 201: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

196

CALL SER0_SENDE ;Se envia el mensaje de cmsPaso IRET ENDP ;************************************************** ********************** INTERRUPT_INT03H PROC ;Regresa el control al monit or. PUSH DS PUSH BX PUSH AX XOR AX, AX MOV DS, AX POP AX MOV BX, REGISTRO_BX POP [BX] ;Guarda BX MOV BX, REGISTRO_DS POP [BX] ;Guarda DS MOV BX, REGISTRO_AX MOV [BX], AX ;Guarda AX INC BX INC BX INC BX INC BX MOV [BX], CX ;Guarda CX INC BX INC BX MOV [BX], DX ;Guarda DX INC BX INC BX MOV [BX], DI ;Guarda DI INC BX INC BX MOV [BX], SI ;Guarda SI INC BX INC BX MOV [BX], BP ;Guarda BP MOV BX, REGISTRO_ES MOV [BX], ES ;Guarda ES MOV BX, REGISTRO_IP POP [BX] MOV BX, REGISTRO_CS POP [BX] MOV BX, REGISTRO_FLAG POP [BX] MOV BX, REGISTRO_SS MOV [BX], SS ;Guarda SS MOV BX, REGISTRO_SP MOV [BX], SP ;Guarda SP ;Ya se pueden usar la mayoria de los registros MOV BX, BIOS_ESTADO MOV BYTE PTR [BX], BIOSEDO_DBG XOR AX, AX MOV DS, AX OR AX, BIT_INTERRUP PUSH AX ;Banderas MOV BX, MONITOR_SEG PUSH [BX] ;Segmento MOV BX, MONITOR_OFF PUSH [BX] ;Offset MOV BL, CMSPASO CALL SER0_SENDE ;Se envia el mensaje de cmsPaso IRET ENDP

E.13 INT04.ASM ;EN ESTE ARCHIVO ESTAN CONTENIDOS TODOS LOS PROCEDIMIENTOS ;NECESARIOS PARA EL MANEJO DE LA INTERRUPCION 04H. ;SE ASUME QUE LA PILA YA SE HA INICIADO. ;************************************************** ********************** ;NOTAS:

Page 202: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

197

; ; ; ;************************************************** ********************** INTERRUPT_INT04H PROC ;Regresa el control al mon itor, overflow. MOV CL, CERROVERFLOW CALL PROCESA_ERR_INT ENDP

E.14 INT05.ASM ;EN ESTE ARCHIVO ESTAN CONTENIDOS TODOS LOS PROCEDIMIENTOS ;NECESARIOS PARA EL MANEJO DE LA INTERRUPCION 05H. ;SE ASUME QUE LA PILA YA SE HA INICIADO. ;************************************************** ********************** ;NOTAS: ; ; ; ;************************************************** ********************** INTERRUPT_INT05H PROC ;Bound MOV CL, CERRARRAY CALL PROCESA_ERR_INT ENDP

E.15 INT06.ASM ;EN ESTE ARCHIVO ESTAN CONTENIDOS TODOS LOS PROCEDIMIENTOS ;NECESARIOS PARA EL MANEJO DE LA INTERRUPCION 06H. ;SE ASUME QUE LA PILA YA SE HA INICIADO. ;************************************************** ********************** ;NOTAS: ; ; ; ;************************************************** ********************** INTERRUPT_INT06H PROC ;Devuelve el control al monitor, Unused opcode. MOV CL, CERRUNUSED CALL PROCESA_ERR_INT ENDP

E.16 INT07.ASM ;EN ESTE ARCHIVO ESTAN CONTENIDOS TODOS LOS PROCEDIMIENTOS ;NECESARIOS PARA EL MANEJO DE LA INTERRUPCION 07H. ;SE ASUME QUE LA PILA YA SE HA INICIADO. ;************************************************** ********************** ;NOTAS: ; ; ; ;************************************************** ********************** INTERRUPT_INT07H PROC ;Escape Opcode MOV CL, CERRESCAPE CALL PROCESA_ERR_INT ENDP

E.17 INT10.ASM ;EN ESTE ARCHIVO ESTAN CONTENIDOS TODOS LOS PROCEDIMIENTOS ;NECESARIOS PARA EL MANEJO DE LA INTERRUPCION 10H ( DISPLAY).

Page 203: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

198

;SE ASUME QUE LA PILA YA SE HA INICIADO. ;************************************************** ***************** ;NOTAS: ; ; ; ;************************************************** ********************** ACTIVE_PAG EQU 00H ;Esto es para compatibilid ad en el futuro. INTERRUPT_INT10H PROC CMP AH, 00H ;Modo de display (video). JNE INT10H_NO00H CALL INT10H_00H JMP INT10H_EXIT INT10H_NO00H: CMP AH, 01H ;Tipo de cursor. JNE INT10H_NO01H CALL INT10H_01H JMP INT10H_EXIT INT10H_NO01H: CMP AH, 02H ;Fijar posici¢n del cursor. JNE INT10H_NO02H CALL INT10H_02H JMP INT10H_EXIT INT10H_NO02H: CMP AH, 03H ;Leer posicion del cursor. JNE INT10H_NO03H CALL INT10H_03H JMP INT10H_EXIT INT10H_NO03H: CMP AH, 05H ;Selecciona pagina de video. JNE INT10H_NO05H CALL INT10H_05H JMP INT10H_EXIT INT10H_NO05H: CMP AH, 08H ;Leer caracter en la posicion actual del cursor. JNE INT10H_NO08H CALL INT10H_08H JMP INT10H_EXIT INT10H_NO08H: CMP AH, 09H ;Escribir caracter en posici¢n actua l, no avanza cursor. JNE INT10H_NO09H CALL INT10H_09H JMP INT10H_EXIT INT10H_NO09H: CMP AH, 0AH ;Escribe CX caracteres desde posicio n actual, avanza cursor. JNE INT10H_NO0AH CALL INT10H_0AH JMP INT10H_EXIT INT10H_NO0AH: CMP AH, 0EH ;Escribir caracter en posicion actua l, avanza cursor. JNE INT10H_NO0EH CALL INT10H_0EH JMP INT10H_EXIT INT10H_NO0EH: CMP AH, 0FH ;Obtiene el modo de display actual. JNE INT10H_NO0FH CALL INT10H_0FH JMP INT10H_EXIT INT10H_NO0FH: CMP AH, 11H ;Generador de caracteres. JNE INT10H_NO11H CALL INT10H_11H JMP INT10H_EXIT INT10H_NO11H: CMP AH, 13H ;Escribe una cadena de texto. JNE INT10H_NO13H CALL INT10H_13H JMP INT10H_EXIT INT10H_NO13H:

Page 204: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

199

INT10H_EXIT: IRET ENDP ;************************************************** ********************** ;*************** SUBFUNCIONES DE LA INTERRUPCION 10 H ******************** ;************************************************** ********************** INT10H_00H PROC ;Enciende/apaga el display (16x2, 16X4, 20x2 y 20x4). PUSH AX PUSH BX PUSH CX PUSH DS MOV BL, AL MOV AL, DSP_CLS ;Limpia display. OUT DSP_COMMWRITE, AL CALL DSP_WAITFLAG MOV AL, DSP_INC ;Incrementa la DD p CG RAM. OUT DSP_COMMWRITE, AL CALL DSP_WAITFLAG AND BL, BL JNZ I10H_00H_DISPLAY ;Continua con el display. I10H_00H_OFF_DISPLAY: ;Apaga el display. MOV AL, DSP_OFF OUT DSP_COMMWRITE, AL CALL DSP_WAITFLAG XOR AX, AX MOV CX, AX JMP I10H_00H_CONTINUA I10H_00H_DISPLAY: MOV AL, DSP_ON ;Enciende display sin cursor. OUT DSP_COMMWRITE, AL CALL DSP_WAITFLAG XOR AX, AX MOV DS, AX MOV AL, BL ;Para determinar el tipo de display. CMP BL, 01H ;Display 16x2. JNE I10H_00H_NO_16X2 MOV CX, 0210H ;2 Renglones y 16 Columnas. JMP I10H_00H_CONTINUA I10H_00H_NO_16X2: CMP BL, 02H ;Display 16x4. JNE I10H_00H_NO_16X4 MOV CX, 0410H ;4 Renglones y 16 Columnas. JMP I10H_00H_CONTINUA I10H_00H_NO_16X4: CMP BL, 03H ;Display 20x2. JNE I10H_00H_NO_20X2 MOV CX, 0214H ;2 Renglones y 20 Columnas. JMP I10H_00H_CONTINUA I10H_00H_NO_20X2: CMP BL, 04H ;Display 20x4. JNE I10H_00H_NO_20X4 MOV CX, 0414H ;4 Renglones y 20 Columnas. JMP I10H_00H_CONTINUA I10H_00H_NO_20X4: JMP I10H_00H_OFF_DISPLAY;Ninguno de los anteriore s, apaga el display. I10H_00H_CONTINUA: MOV BX, NUMBER_ACTIVE_VID_PAG ;Por default es CER O. MOV BYTE PTR [BX], ACTIVE_PAG MOV BX, CURRENT_DISPLAY_MODE MOV [BX], AL MOV BX, NUMBER_SCREEN_COLS MOV [BX], CX MOV BX, CURSOR_POSITION MOV WORD PTR [BX], 0000H ;Posicion X=0, Y=0 del c ursor. MOV BX, CURRENT_CURSOR_MODE MOV WORD PTR [BX], 0000H ;Sin cursor. POP DS POP CX POP BX POP AX

Page 205: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

200

RET ENDP ;************************************************** ********************** INT10H_01H PROC ;Selecciona el tipo de cursor. PUSH AX PUSH BX PUSH DS MOV AL, CL OR AL, 0CH AND AL, 0FH OUT DSP_COMMWRITE, AL XOR AX, AX MOV DS, AX MOV BX, CURRENT_CURSOR_MODE MOV [BX], CL ;Guarda el tipo de cursor. POP DS POP BX POP AX RET ENDP ;************************************************** ********************** INT10H_02H PROC ;Fija la posicion del cursor. PUSH AX PUSH BX PUSH CX PUSH DX PUSH DS XOR AX, AX MOV DS, AX MOV BX, NUMBER_SCREEN_COLS MOV AX, [BX] ;Obtenemos el tama¤o del display. CMP DH, AH ;Comparamos renglones. JAE I10H_02H_EXIT ;Posicion no valida. CMP DL, AL ;Comparamos columnas. JAE I10H_02H_EXIT ;Posicion no valida. MOV BX, CURSOR_POSITION MOV [BX], DX ;Guarda la posicion. MOV BX, CURRENT_DISPLAY_MODE MOV CL, [BX] AND CL, 01H ;Para ver si es de 2 o 4 renglones. JZ I10H_02H_4_ROW ;Es de 4 renglones. I10H_02H_1_2_ROW: SHL DH, 06H ;Es de 2 renglones. OR DL, DH JMP I10H_02H_CONTINUA I10H_02H_4_ROW: MOV CL, DH AND CL, 02H ;Renglones 0, 1 o 2, 3. JZ I10H_02H_1_2_ROW;Renglones 0 y 1. AND DH, 01H ;Para saber si es 2 o 3. SHL DH, 06H OR DH, AL ADD DL, DH I10H_02H_CONTINUA: MOV AL, DL OR AL, 80H OUT DSP_COMMWRITE, AL CALL DSP_WAITFLAG I10H_02H_EXIT: POP DS POP DX POP CX POP BX POP AX RET ENDP ;************************************************** ********************** INT10H_03H PROC ;Lee la posicion y el tipo (de mem oria) de cursor. PUSH AX PUSH BX PUSH DS

Page 206: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

201

XOR AX, AX MOV DS, AX IN AL, DSP_COMMREAD ;Se lee la posicion del curs or. AND AL, 7FH ;Quitamos la bandera. CALL DSP_CAL_ROWCOL ;Obtenemos la posicion X-Y en DX. MOV BX, CURSOR_POSITION MOV [BX], DX ;Coloca en memoria la posicion. MOV BX, CURRENT_CURSOR_MODE MOV CL, [BX] ;Lee de memoria el tipo de cursor. POP DS POP BX POP AX RET ENDP ;************************************************** ********************** INT10H_05H PROC ;Seleccion pagina de video, sin us o. RET ENDP ;************************************************** ********************** INT10H_08H PROC ;Lee el caracter de la posicion ac tual del cursor. IN AL, DSP_COMMREAD ;Leemos la posicion del curs or. CALL DSP_WAITFLAG MOV AH, AL ;La posicion queda en AH. IN AL, DSP_DATAREAD ;Leemos el caracter. CALL DSP_WAITFLAG PUSH AX MOV AL, AH OR AL, 80H OUT DSP_COMMWRITE, AL ;Fijamos la posicion anteri or. CALL DSP_WAITFLAG POP AX RET ENDP ;************************************************** ********************** INT10H_09H PROC ;Escribe un caracter sin avanzar e l cursor. PUSH AX PUSH BX MOV BL, AL ;Salvamos el caracter. IN AL, DSP_COMMREAD ;Leemos la posicion del curs or. CALL DSP_WAITFLAG MOV AH, AL ;Salvamos la posicion. MOV AL, BL OUT DSP_DATAWRITE, AL ;Escribimos el dato. CALL DSP_WAITFLAG MOV AL, AH OR AL, 80H OUT DSP_COMMWRITE, AL ;Fijamos la posicion anteri or. CALL DSP_WAITFLAG POP BX POP AX RET ENDP ;************************************************** ********************** INT10H_0AH PROC I10H_0AH_CONTINUA: CALL INT10H_0EH LOOP I10H_0AH_CONTINUA RET ENDP ;************************************************** ********************** INT10H_0EH PROC ;Escribe un caracter, avanza el cu rsor. PUSH AX PUSH BX PUSH CX ;Sirve para guardar el caracter y la pos icion. PUSH DX PUSH DS MOV CL, AL ;Salvo el caracter. IN AL, DSP_COMMREAD ;Leo la posicion. CALL DSP_WAITFLAG MOV CH, AL ;Salvo la posicion. CMP CL, KENTER ;Si la tecla es un enter, coloca e l cursor en

Page 207: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

202

JE I10H_0EH_NO_PRI ;la siguiente linea. MOV AL, CL ;Para imprimir el dato. OUT DSP_DATAWRITE, AL ;Imprime el dato. I10H_0EH_NO_PRI: ;Salta aqui cuando hay un ENTER, n o imprime. XOR AX, AX ;Ahora procedemos a colocar el cursor en la siguiente posicion. MOV DS, AX MOV AL, CH AND AL, 7FH CALL DSP_CAL_ROWCOL ;En DX esta la posicion en X- Y. MOV BX, NUMBER_SCREEN_COLS MOV AX, [BX] ;Obtenemos el tama¤o de la pantalla . CMP CL, KENTER ;Si la tecla es un enter, incremen ta el renglon. JE I10H_0EH_ENTER INC DL CMP DL, AL JB I10H_0EH_EXIT I10H_0EH_ENTER: XOR DL, DL INC DH CMP DH, AH JB I10H_0EH_EXIT ;Si es mayor, hay movimiento de renglones. MOV CL, AL ;Tama¤o de columnas. MOV DX, 0C080H ;Del segundo renglon al primero. CALL DSP_MOVE_UP_ROW ;Movemos el segundo renglon al primero. MOV DX, 0100H MOV BX, CURRENT_DISPLAY_MODE ;Para ver cuantos re nglones falta recorrer. MOV CH, [BX] AND CH, 01H ;Para ver si es de 2 o 4 renglones. JNZ I10H_0EH_EXIT ;Es de 2 renglones. MOV CL, AL ;Faltan dos renglones mas. MOV DH, AL MOV DL, 0C0H OR DH, 80H CALL DSP_MOVE_UP_ROW ;Movemos del tercero al segu ndo. MOV DL, DH OR DH, 40H CALL DSP_MOVE_UP_ROW ;Movemos del cuarto al terce ro. MOV DX, 0300H I10H_0EH_EXIT: CALL INT10H_02H POP DS POP DX POP CX POP BX POP AX RET ENDP ;************************************************** ********************** INT10H_0FH PROC ;Obtiene el modo de display actual . PUSH BX PUSH DS XOR AX, AX MOV DS, AX MOV BX, NUMBER_SCREEN_COLS MOV AX, [BX] ;Primero se obtienen las columnas. MOV AH, AL ;Columnas. MOV BX, CURRENT_DISPLAY_MODE MOV AL, [BX] ;El modo del display. XOR BX, BX POP DS POP BX RET ENDP ;************************************************** ********************** INT10H_11H PROC ;Generador de caracteres. PUSH AX PUSH BX PUSH CX PUSH DX IN AL, DSP_COMMREAD ;Leo la posicion.

Page 208: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

203

CALL DSP_WAITFLAG MOV DH, AL ;Salvo la posicion. AND DL, 07H SHL DL, 03H ;Para obtener la direccion de los ca racteres. MOV AL, DL OR AL, 40H OUT DSP_COMMWRITE, AL ;Coloca la posicion en la C GRAM. CALL DSP_WAITFLAG MOV BX, BP ;Para leer y generar el caracter. MOV CX, 0008H ;8 bytes por caracter. I10H_11H_WRITE: MOV AL, ES:[BX] OUT DSP_DATAWRITE, AL ;Escribimos el dato. CALL DSP_WAITFLAG INC BX LOOP I10H_11H_WRITE MOV AL, DH OR AL, 80H OUT DSP_COMMWRITE, AL ;Restauramos la posicion. CALL DSP_WAITFLAG POP DX POP CX POP BX POP AX RET ENDP ;************************************************** ********************** INT10H_13H PROC ;Escribe una cadena. PUSH AX PUSH BX PUSH CX MOV BL, AL ;Salva la opcion de no mover el curso r. IN AL, DSP_COMMREAD ;Leemos la posicion del curs or. CALL DSP_WAITFLAG MOV AH, AL ;Salvamos la posicion. CALL INT10H_02H ;Coloca el cursor desde donde se escribe. MOV AL, BL PUSH AX MOV BX, BP ;Para escribir la cadena. I10H_13H_WRITE: MOV AL, ES:[BX] CALL INT10H_0EH INC BX LOOP I10H_13H_WRITE ;Escribe los CX caracteres. POP AX AND AL, 01H JNZ I10H_13H_EXIT ;No mueve el cursor. MOV AL, AH OR AL, 80H OUT DSP_COMMWRITE, AL ;Fijamos la posicion anteri or. CALL DSP_WAITFLAG I10H_13H_EXIT: POP CX POP BX POP AX RET ENDP ;************************************************** ********************** ;*************** FUNCIONES PARA EL MANEJO DEL DISPL AY ******************* ;************************************************** ********************** ;ESPERA A QUE EL DISPLAY TERMINE EL COMANDO. ;PARAMETROS: NINGUNO ;RETORNO: NINGUNO DSP_WAITFLAG PROC PUSH AX DSP_WAIT_FLAG_P: ;Para espera de busy flag. IN AL, DSP_COMMREAD RCL AL, 1

Page 209: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

204

JC DSP_WAIT_FLAG_P POP AX RET ENDP ;************************************************** ********************** ;MUEVE LOS DATOS DE UN DETERMINADO RENGLON AL ANTERIOR. LOS DATOS DEL ;RENGLON SE CAMBIAN A ESPACIO (20H). NO INCLUYE EL BIT 7. ;PARAMETROS: CL=NUMERO DE CARACTERES ; DH=INICIO DE MEMORIA DEL RENGLON ORIGEN (VER HOJ A DE DATOS). ; DL=INICIO DE MEMORIA DEL RENGLON DESTINO (VER HO JA DE DATOS). ;RETORNO: NINGUNO. DSP_MOVE_UP_ROW PROC ;Mueve el segundo renglon al primero (pierde posicion). PUSH AX PUSH BX ;Se almacena posicion y caracter. PUSH CX PUSH DX XOR CH, CH ;En CX queda el contador de caractere s. DSP_MOVE_UP_ROW_CONT: MOV AL, DH ;Renglon origen. OUT DSP_COMMWRITE, AL CALL DSP_WAITFLAG IN AL, DSP_DATAREAD ;Leo el dato del segundo ren glon. CALL DSP_WAITFLAG MOV BH, AL ;Guardo el dato del segundo renglon. MOV AL, DH OUT DSP_COMMWRITE, AL ;Escribo el dato del renglo n origen. CALL DSP_WAITFLAG MOV AL, 20H OUT DSP_DATAWRITE, AL ;Borro el renglon. CALL DSP_WAITFLAG MOV AL, DL ;Renglon destino. OUT DSP_COMMWRITE, AL ;Posicion para el primer re nglon. CALL DSP_WAITFLAG MOV AL, BH OUT DSP_DATAWRITE, AL ;Coloco el caracter del seg undo renglon en el primero. CALL DSP_WAITFLAG INC DL INC DH LOOP DSP_MOVE_UP_ROW_CONT POP DX POP CX POP BX POP AX RET ENDP ;************************************************** ********************** ;CALCULA LA POSICION EN X-Y (COLUMNA-RENGLON) A PAR TIR DEL DATOS ;LEIDO DEL DISPLAY. ;PARAMETROS: AL=POSICION DE MEMORIA DEL DISPLAY SI N BANDERA. ;RETORNO: DH=RENGLON (Y). ; DL=COLUMNA (X). DSP_CAL_ROWCOL PROC ;Obtiene la posicion, a partir de la memoria. PUSH BX PUSH CX PUSH DS XOR BX, BX MOV DS, BX MOV BX, CURRENT_DISPLAY_MODE MOV CL, [BX] AND CL, 01H ;Para ver si es de 2 o 4 renglones. JZ DSP_CAL_ROWCOL_4ROW ;Es de 4 renglones. MOV DH, AL SHR DH, 06H ;Ya tenemos el renglon. MOV DL, AL AND DL, 3FH ;Tenemos la columna. JMP DSP_CAL_ROWCOL_EXIT DSP_CAL_ROWCOL_4ROW:

Page 210: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

205

MOV BX, NUMBER_SCREEN_COLS MOV CX, [BX] ;Obtengo las medidas del display. MOV DH, AL AND DH, 40H ;Para ver que renglon es. SHR DH, 06H MOV DL, AL AND DL, 3FH CMP DL, CL ;Compara con el numero de columnas. JB DSP_CAL_ROWCOL_EXIT SUB DL, CL INC DH INC DH DSP_CAL_ROWCOL_EXIT: POP DS POP CX POP BX RET ENDP ;************************************************** **********************

E.18 INT16.ASM ;EN ESTE ARCHIVO ESTAN CONTENIDOS TODOS LOS PROCEDIMIENTOS ;NECESARIOS PARA EL MANEJO DE LA INTERRUPCION 16H ( TECLADO). ;SE ASUME QUE LA PILA YA SE HA INICIADO. ;************************************************** ********************** ;NOTAS: ; ; ; ;************************************************** ********************** ;KEYBOARD_STATUS_FLAG EQU 0417H ;2 bytes. ;KEYBOARD_BUFFER EQU 041AH ;36 bytes. ;KEY_INI_TAIL EQU 02H ;KEY_END_TAIL EQU 00H ;START_KEYBOARD_DATA EQU 0480H ;2 bytes. ;END_KEYBOARD_DATA EQU 0452H ;2 bytes. INTERRUPT_INT16H PROC CMP AH, 00H ;Lee un caracter del buffer de tecla do. JNE INT16H_NO00H CALL INT16H_00H JMP INT16H_EXIT INT16H_NO00H: CMP AH, 01H ;Lee un caracter del buffer de tecla do. JNE INT16H_NO01H CALL INT16H_01H JMP INT16H_EXIT INT16H_NO01H: CMP AH, 02H ;Lee las banderas del teclado. JNE INT16H_NO02H CALL INT16H_02H JMP INT16H_EXIT INT16H_NO02H: CMP AH, 05H ;Escribe al buffer de teclado. JNE INT16H_NO05H CALL INT16H_05H JMP INT16H_EXIT INT16H_NO05H: CMP AH, 13H ;Reinicia el buffer de teclado. JNE INT16H_NO13H CALL INT16H_13H JMP INT16H_EXIT INT16H_NO13H: INT16H_EXIT: IRET ENDP ;************************************************** ********************** INT16H_00H PROC ;Lee una tecla del buffer de tecla do.

Page 211: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

206

PUSH BX PUSH CX PUSH SI PUSH DS XOR AX, AX MOV DS, AX MOV SI, START_KEYBOARD_DATA;Para obtener la direc cion del buffer. MOV BX, [SI] ;Direccion del buffer STI ;Para que se pueda recibir una tecla I16H_00H_CHK_TECLA: MOV CX, [BX] ;Fin de la cola. MOV AX, [BX+KEY_INI_TAIL] ;Inicio de la cola del buffer CMP CX, AX JNE I16H_00H_HAY_TECLA JMP I16H_00H_CHK_TECLA I16H_00H_HAY_TECLA: CLI INC BX INC BX ;Se posiciona la inicio de la cola INC AX INC AX ;Para obtener la siguiente tecla. CMP AX, [SI+ADD_KEYBOARD_DATA];Es fin de cola? JBE I16H_00H_CONTINUA_0 MOV AX, BX INC AX INC AX I16H_00H_CONTINUA_0: MOV [BX], AX ;Guarda inicio de cola. MOV BX, AX MOV AX, [BX] ;Obtiene el caracter. POP DS POP SI POP CX POP BX RET ENDP ;************************************************** ********************** INT16H_01H PROC ;Lee una tecla del buffer del tecl ado. PUSH BX PUSH CX PUSH SI PUSH DS XOR AX, AX MOV DS, AX MOV SI, START_KEYBOARD_DATA;Para obtener la direc cion del buffer. MOV BX, [SI] ;Direccion del buffer MOV CX, [BX] ;Fin de la cola. INC BX INC BX MOV AX, [BX] ;Inicio de la cola del buffer CMP CX, AX JNE I16H_01H_HAY_TECLA XOR AX, AX JMP I16H_01H_END I16H_01H_HAY_TECLA: INC AX INC AX ;Para obtener la siguiente tecla. CMP AX, [SI+ADD_KEYBOARD_DATA];Es fin de cola? JBE I16H_01H_CONTINUA_0 MOV AX, BX INC AX INC AX I16H_01H_CONTINUA_0: MOV [BX], AX ;Guarda inicio de cola. MOV BX, AX MOV AX, [BX] ;Obtiene el caracter. I16H_01H_END: POP DS POP SI POP CX POP BX

Page 212: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

207

RET ENDP ;************************************************** ********************** INT16H_02H PROC ;Lee las banderas del teclado. PUSH BX PUSH DS XOR AX, AX MOV DS, AX MOV BX, KEYBOARD_STATUS_FLAG MOV AL, [BX] POP DS POP BX RET ENDP ;************************************************** ********************** INT16H_05H PROC ;Escribe un caracter al buffer de teclado. PUSH AX PUSH BX PUSH CX PUSH SI PUSH DS MOV AX, CX ;Salvamos el scan y caracter. XOR CX, CX ;Para guardar al buffer de teclado. MOV DS, CX MOV SI, START_KEYBOARD_DATA;Direccion del buffer. MOV BX, [SI] ;Direccion del buffer de teclado. MOV CX, [BX] ;Primer word del buffer de teclado. Fin de cola. INC CX INC CX ;Lo incrementa para agregar la tecla. CMP CX, [SI+ADD_KEYBOARD_DATA];Fin de buffer? JBE I16H_05H_CONTINUA_1 MOV CX, BX INC CX INC CX INC CX INC CX I16H_05H_CONTINUA_1: CMP CX, [BX+KEY_INI_TAIL];Es igual al inicio de l a cola? JNE I16H_05H_CONTINUA_2 MOV AL, 01H JMP I16H_05H_END ;No guarda nada y sale. I16H_05H_CONTINUA_2: MOV SI, CX MOV [SI], AX ;Guarda el caracter. MOV [BX], CX ;Guarda la direccion de la cola. I16H_05H_END: POP DS POP SI POP CX POP BX POP AX RET ENDP ;************************************************** ********************** INT16H_13H PROC ;Reinicia el buffer de teclado. PUSH BX PUSH DS CLI XOR BX, BX MOV DS, BX MOV BX, KEYBOARD_BUFFER ;Buffer de teclado. MOV WORD PTR [BX], KEYB_BUFFER;Fin de cola de tec lado. INC BX INC BX MOV WORD PTR [BX], KEYB_BUFFER;Inicio de cola de teclado. MOV BX, START_KEYBOARD_DATA ;Inicio del buffer de teclado MOV WORD PTR [BX], KEYB_IBUFFER INC BX INC BX MOV WORD PTR [BX], KEYB_FBUFFER;Fin del buffer de teclado.

Page 213: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

208

STI POP DS POP BX RET ENDP ;************************************************** **********************

E.19 INT19.ASM ;EN ESTE ARCHIVO ESTAN CONTENIDOS TODOS LOS PROCEDIMIENTOS ;NECESARIOS PARA EL MANEJO DE LA INTERRUPCION 19H. ;SE ASUME QUE LA PILA YA SE HA INICIADO. ;************************************************** ********************** ;NOTAS: ; ; ; ;************************************************** ********************** INTERRUPT_INT19H PROC ;Reset del sistema. XOR AX, AX CLI CALL SER0_LIMPIAPUERTO;Limpiamos el puerto serie de comunicacion con el depurador MOV DX, INT_INSERV OUT DX, AL ;Ninguna interrupcion en servicio. MOV DX, INT_INT_REQ OUT DX, AL ;Ninguna interrupcion en espera. MOV DX, INT_MASK OUT DX, AL ;Deshabilitamos las interrupciones. MOV DX, SER0_CTRL OUT DX, AL ;Quitamos puerto serie 0 MOV DX, SER1_CTRL OUT DX, AL ;Quitamos puerto serie 1 MOV AX, 4000H MOV DX, TEMP_TMP0_CTRL OUT DX, AL ;Quitamos temporizador 0 MOV DX, TEMP_TMP1_CTRL OUT DX, AL ;Quitamos temporizador 1 MOV DX, TEMP_TMP2_CTRL OUT DX, AL ;Quitamos temporizador 2 DB 0EAh ;Hace un salto al inicio de la ROM. DW 3FF0h DW 0FC00h DW 0000h IRET ENDP

E.20 INT1A.ASM ;EN ESTE ARCHIVO ESTAN CONTENIDOS TODOS LOS PROCEDIMIENTOS ;NECESARIOS PARA EL MANEJO DE LA INTERRUPCION 1AH ( RELOJ). ;SE ASUME QUE LA PILA YA SE HA INICIADO. ;************************************************** ********************** ;NOTAS: ; ; ; ;************************************************** ********************** INTERRUPT_INT1AH PROC CMP AH, 00H ;Lee los ticks del temporizador. JNE INT1AH_NO00H CALL INT1AH_00H JMP INT1AH_EXIT INT1AH_NO00H: CMP AH, 01H ;Fija los ticks del temporizador. JNE INT1AH_NO01H CALL INT1AH_01H JMP INT1AH_EXIT

Page 214: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

209

INT1AH_NO01H: CMP AH, 02H ;Lee la hora en base a los ticks del temporizador. JNE INT1AH_NO02H CALL INT1AH_02H JMP INT1AH_EXIT INT1AH_NO02H: CMP AH, 03H ;Fija la hora en base a los ticks de l temporizador. JNE INT1AH_NO03H CALL INT1AH_03H JMP INT1AH_EXIT INT1AH_NO03H: CMP AH, 20H ;Activa el contador del temporizador . JNE INT1AH_NO20H CALL INT1AH_20H JMP INT1AH_EXIT INT1AH_NO20H: CMP AH, 21H ;Muestra el estado del contador del temporizador. JNE INT1AH_NO21H CALL INT1AH_21H JMP INT1AH_EXIT INT1AH_NO21H: INT1AH_EXIT: IRET ENDP ;************************************************** ********************** INT1AH_00H PROC ;Lee los ticks del temporizador. PUSH BX PUSH DS XOR BX, BX MOV DS, BX MOV BX, LWORD_TIMER ;Primero la parte baja. MOV DX, [BX] INC BX INC BX MOV CX, [BX] ;Ahora la parte alta. INC BX INC BX MOV AL, [BX] ;Bandera de media-noche. MOV BYTE PTR [BX], 00H;Se coloca a cero. POP DS POP BX RET ENDP ;************************************************** ********************** INT1AH_01H PROC ;Fija los ticks del temporizador. PUSH BX PUSH DS XOR BX, BX MOV DS, BX MOV BX, LWORD_TIMER ;Primero la parte baja. MOV [BX], DX INC BX INC BX MOV [BX], CX ;Ahora la parte alta. INC BX INC BX AND AL, 01H MOV [BX], AL ;Bandera de media-noche. POP DS POP BX RET ENDP ;************************************************** ********************** INT1AH_02H PROC ;Lee la hora en base a los ticks d el temporizador. PUSH AX PUSH BX PUSH DS XOR BX, BX MOV DS, BX MOV BX, LWORD_TIMER ;Primero la parte baja. MOV AX, [BX]

Page 215: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

210

INC BX INC BX MOV DX, [BX] ;Ahora la parte alta. Ya se tiene e l par DX:AX para la division. MOV BX, RELOJ_TKSMIN DIV BX ;AX=Minutos, DX=Ticks PUSH AX MOV AX, DX MOV BL, RELOJ_TKSSEG DIV BL MOV DL, AL ;DL=Segundos POP AX MOV BL, RELOJ_MINHOR DIV BL ;AL=Horas, AH=Minutos. PUSH AX MOV AL, DL CALL INT60H_0EH XOR DX, DX MOV DH, AL ;Los segundos. POP BX ;BL=Horas, BH=Minutos. MOV AL, BL CALL INT60H_0EH MOV CH, AL ;Las horas. MOV AL, BH CALL INT60H_0EH MOV CL, AL ;Los minutos. POP DS POP BX POP AX RET ENDP ;************************************************** ********************** INT1AH_03H PROC ;Fija la hora en base a los ticks del temporizador. PUSH AX PUSH BX PUSH CX PUSH DX PUSH DS MOV AL, CH CALL INT60H_0FH ;BCD a 8 bits (horas). MOV CH, AL MOV AL, CL CALL INT60H_0FH ;BCD a 8 bits (minutos). MOV CL, AL MOV AL, DH CALL INT60H_0FH ;BCD a 8 bits (segundos). MOV DH, AL XOR AX, AX MOV AL, CH MOV BL, RELOJ_MINHOR MUL BL XOR CH, CH ADD AX, CX ;AX=Parcial de Minutos PUSH AX XOR AX, AX MOV AL, DH MOV BL, RELOJ_TKSSEG MUL BL ;AX=Parcial de ticks. MOV DX, AX POP AX MOV BX, RELOJ_TKSMIN PUSH DX MUL BX ;DX:AX=Ticks POP BX XOR CX, CX ADD AX, BX ADC DX, CX ;DX:AX=Total de ticks. XOR BX, BX MOV DS, BX MOV BX, LWORD_TIMER ;Primero la parte baja. MOV [BX], AX INC BX

Page 216: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

211

INC BX MOV [BX], DX ;Ahora la parte alta. INC BX INC BX XOR AL, AL MOV [BX], AL ;Se borra la bandera de media-noche . POP DS POP DX POP CX POP BX POP AX RET ENDP ;************************************************** ********************** INT1AH_20H PROC ;Activa el contador del temporiza dor. PUSH BX PUSH DX PUSH DS PUSH AX XOR AX, AX MOV DS, AX MOV DX, TEMP_TMP1_CTRL ;La direccion en el PCB re gistro de control IN AX, DX ;Obtiene el valor del registro. AND AX, 2000H JNZ INT1AH_20H_CONTINUA MOV BX, TEMPORIZADOR_FLAG ;No se va activar este temporizador MOV BYTE PTR [BX], 01H ;Activa la bandera de ter minacion. POP AX XOR AL, AL JMP INT1AH_20H_TERMINA INT1AH_20H_CONTINUA: CMP BX, TEMPORIZADOR_MAX JBE INT1AH_20H_CONTINUA1 ;Maximo 2000 segundos. MOV BX, TEMPORIZADOR_MAX INT1AH_20H_CONTINUA1: MOV AX, BX MOV BX, RELOJ_TKSSEG MUL BX ;En AX se tiene cuanto hay que contar. MOV BX, TEMPORIZADOR MOV WORD PTR [BX], AX ;Este es el contador. INC BX INC BX MOV BYTE PTR [BX], 00H ;La bandera POP AX MOV AL, 01H INT1AH_20H_TERMINA: POP DS POP DX POP BX RET ENDP ;************************************************** ********************** INT1AH_21H PROC ;Muestra el estado del contador de l temporizador. PUSH CX PUSH DX PUSH DS MOV CH, AH ;Para salvar el registro AH y luego s e recupere XOR BX, BX MOV DS, BX MOV BX, TEMPORIZADOR ;Contador MOV AX, [BX] MOV CX, RELOJ_TKSSEG ;Entre 24 1/s XOR DX, DX DIV CX INC BX INC BX MOV CL, [BX] ;La bandera MOV BX, AX MOV AX, CX POP DS POP DX

Page 217: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

212

POP CX RET ENDP ;************************************************** **********************

E.21 INT1C.ASM ;EN ESTE ARCHIVO ESTAN CONTENIDOS TODOS LOS PROCEDIMIENTOS ;NECESARIOS PARA EL MANEJO DE LA INTERRUPCION 1CH. ;SE ASUME QUE LA PILA YA SE HA INICIADO. ;************************************************** ********************** ;NOTAS: ESTA INTERRUPCION SOLO SIRVE PARA PROGRAMAS "RESIDENTES" ; ; ; ;************************************************** ********************** INTERRUPT_INT1CH PROC ;Complemento de 12H IRET ENDP

E.22 INT20.ASM ;EN ESTE ARCHIVO ESTAN CONTENIDOS TODOS LOS PROCEDIMIENTOS ;NECESARIOS PARA EL MANEJO DE LA INTERRUPCION 27H ( TIPO MS-DOS). ;SE ASUME QUE LA PILA YA SE HA INICIADO. ;************************************************** ********************** ;NOTAS: ; ; ; ;************************************************** ********************** INTERRUPT_INT20H PROC MOV DX, AX XOR AX, AX CALL SER0_INTERRUPCIONEDO ;Desactiva la interrupc ion del serial XOR AX, AX MOV DS, AX MOV BX, BIOS_ESTADO MOV BYTE PTR [BX], BIOSEDO_STP MOV BX, RETURN_END MOV [BX], DL ;Guarda el codigo de retorno XOR AX, AX MOV SS, AX MOV DS, AX MOV BX, PILA_MONITOR MOV SP, [BX] CALL PREPARA_MONITOR XOR AX, AX MOV DS, AX PUSH AX ;Banderas MOV BX, MONITOR_SEG PUSH [BX] ;Segmento MOV BX, MONITOR_OFF PUSH [BX] ;Offset MOV AL, 01H ;Activa la interrupcion del serial CALL SER0_INTERRUPCIONEDO ;Activa la interrupcion del serial MOV AX, CS MOV DS, AX MOV ES, AX MOV BL, CMSEND CALL SER0_SENDE ;Se envia el mensaje de cmsEnd IRET ENDP

Page 218: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

213

E.23 INT21.ASM ;EN ESTE ARCHIVO ESTAN CONTENIDOS TODOS LOS PROCEDIMIENTOS ;NECESARIOS PARA EL MANEJO DE LA INTERRUPCION 21H ( TIPO MS-DOS). ;SE ASUME QUE LA PILA YA SE HA INICIADO. ;************************************************** ********************** ;NOTAS: ; ; ; ;************************************************** ********************** INT21H_ENT_TXT EQU 24H INTERRUPT_INT21H PROC CMP AH, 01H ;Entrada de teclado con ECHO. JNE INT21H_NO01H CALL INT21H_01H JMP INT21H_EXIT INT21H_NO01H: CMP AH, 02H ;Imprime un caracter en el display. JNE INT21H_NO02H CALL INT21H_02H JMP INT21H_EXIT INT21H_NO02H: CMP AH, 09H ;Imprime una cadena en el display. JNE INT21H_NO09H CALL INT21H_09H JMP INT21H_EXIT INT21H_NO09H: CMP AH, 25H ;Coloca un vector de interrupcion. JNE INT21H_NO25H CALL INT21H_25H JMP INT21H_EXIT INT21H_NO25H: CMP AH, 30H ;Version del BIOS. JNE INT21H_NO30H CALL INT21H_30H JMP INT21H_EXIT INT21H_NO30H: CMP AH, 35H ;Obtiene el vector de interrupcion. JNE INT21H_NO35H CALL INT21H_35H JMP INT21H_EXIT INT21H_NO35H: CMP AH, 4CH ;Terminar programa con codigo de reg reso. JNE INT21H_NO4CH CALL INT21H_4CH JMP INT21H_EXIT INT21H_NO4CH: INT21H_EXIT: IRET ENDP ;************************************************** ********************** INT21H_01H PROC ;Entrada de teclado con ECHO. CALL INT16H_00H ;Emplea una de las interrupciones de teclado. CALL INT10H_0EH ;Emprea una de las interrupciones de pantalla, para imprimir el caracter. RET ENDP ;************************************************** ********************** INT21H_02H PROC ;Imprime un caracter en el display . PUSH AX MOV AL, DL CALL INT10H_0EH ;Usa la INT10H para imprimir el c aracter. POP AX RET ENDP ;************************************************** ********************** INT21H_09H PROC ;Imprime una cadena de texto en el display.

Page 219: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

214

PUSH AX PUSH BX MOV BX, DX INT21H_09H_CONTINUA: MOV AL, [BX] CMP AL, INT21H_ENT_TXT JE INT21H_09H_EXIT CALL INT10H_0EH ;Usa la INT10H para imprimir el c aracter. INC BX JMP INT21H_09H_CONTINUA INT21H_09H_EXIT: POP BX POP AX RET ENDP ;************************************************** ********************** INT21H_25H PROC ;Coloca un vector de interrupcion . PUSH AX PUSH DI PUSH ES CLD XOR DI, DI ;Colocamos el segmento 0000H MOV ES, DI ;Que es donde estan los vectores. MOV AH, AL ;El numero de interrupcion. MOV AL, 04 MUL AH ;Multiplicamos por 4 para obtener el OFFS ET del vector. MOV DI, AX MOV AX, DX STOSW ;Primero el OFFSET. MOV AX, DS STOSW ;Luego el segmento. POP ES POP DI POP AX RET ENDP ;************************************************** ********************** INT21H_30H PROC ;Version del bios. PUSH DS PUSH BX MOV BX, 0FC00H MOV DS, BX MOV BX, 03FFCH MOV AX, [BX] POP BX POP DS RET ENDP ;************************************************** ********************** INT21H_35H PROC ;Obtiene el vector de interrupcion es. PUSH AX PUSH SI PUSH DS CLD MOV AH, AL ;El numero de interrupcion. MOV AL, 04 MUL AH ;Obtiene el OFFSET del numero de interrup cion. MOV SI, AX XOR AX, AX MOV DS, AX LODSW MOV BX, AX ;Primero el OFFSET. LODSW MOV ES, AX ;Luego el segmento. POP DS POP SI POP AX RET ENDP ;************************************************** ********************** INT21H_4CH PROC ;Regresa el control al BIOS.

Page 220: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

215

MOV DX, AX XOR AX, AX CALL SER0_INTERRUPCIONEDO ;Desactiva la interrupc ion del serial XOR AX, AX MOV DS, AX MOV BX, BIOS_ESTADO MOV BYTE PTR [BX], BIOSEDO_STP MOV BX, RETURN_END MOV [BX], DL ;Guarda el codigo de retorno PUSH AX ;Banderas MOV BX, BIOS_SEG PUSH [BX] ;Segmento MOV BX, BIOS_OFF PUSH [BX] ;Offset MOV BL, CMSEND CALL SER0_SENDE ;Se envia el mensaje de cmsEnd IRET ENDP ;************************************************** **********************

E.24 INT27.ASM ;EN ESTE ARCHIVO ESTAN CONTENIDOS TODOS LOS PROCEDIMIENTOS ;NECESARIOS PARA EL MANEJO DE LA INTERRUPCION 27H ( TIPO MS-DOS). ;SE ASUME QUE LA PILA YA SE HA INICIADO. ;************************************************** ********************** ;NOTAS: ; ; ; ;************************************************** ********************** INTERRUPT_INT27H PROC MOV AX, CS MOV ES, AX ;Fijamos el registro ES. CMP DX, TAM_BUFFER_CR JBE INTERRUPT_INT27H_CONTINUA MOV DX, TAM_BUFFER_CR INTERRUPT_INT27H_CONTINUA: SHL DX, 04H ;Rotacion para obtener el valor rea l. MOV AX, TAM_MEMORIA_RAM SUB AX, DX XOR DX, DX MOV DS, DX MOV BX, PILA_MONITOR MOV [BX], AX ;Se almacena el nuevo valor de pil a. XOR AX, AX MOV SS, AX MOV DS, AX MOV BX, PILA_MONITOR MOV SP, [BX] CALL PREPARA_MONITOR XOR AX, AX MOV DS, AX PUSH AX ;Banderas MOV BX, MONITOR_SEG PUSH [BX] ;Segmento MOV BX, MONITOR_OFF PUSH [BX] ;Offset MOV BX, BIOS_ESTADO MOV BYTE PTR [BX], BIOSEDO_OK MOV BX, RETURN_END MOV BYTE PTR [BX], 00H ;Guarda el codigo de retor no, siempre CERO. MOV AL, 01H ;Activa la interrupcion del serial CALL SER0_INTERRUPCIONEDO ;Activa la interrupcion del serial

Page 221: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

216

MOV AX, CS MOV DS, AX MOV ES, AX MOV BL, CMSRESIDENTE ;Envia comando de residente . CALL SER0_SENDE ;Se envia el mensaje de cmsEnd IRET ENDP ;************************************************** **********************

E.25 INT60.ASM ;EN ESTE ARCHIVO ESTAN CONTENIDOS TODOS LOS PROCEDIMIENTOS ;NECESARIOS PARA EL MANEJO DE LA INTERRUPCION 60H ( UTILERIAS). ;SE ASUME QUE LA PILA YA SE HA INICIADO. ;************************************************** ********************** ;NOTAS: ; ; ; ;************************************************** ********************** INTERRUPT_INT60H PROC CMP AH, 00H ;Imprime un numero en HEX. JNE INT60H_NO00H CALL INT60H_00H JMP INT60H_EXIT INT60H_NO00H: CMP AH, 01H ;Imprime un numero en BIN. JNE INT60H_NO01H CALL INT60H_01H JMP INT60H_EXIT INT60H_NO01H: CMP AH, 02H ;Imprime un numero en DEC. JNE INT60H_NO02H CALL INT60H_02H JMP INT60H_EXIT INT60H_NO02H: CMP AH, 03H ;Imprime TEXTO. JNE INT60H_NO03H CALL INT60H_03H JMP INT60H_EXIT INT60H_NO03H: CMP AH, 04H ;Longitud de cadena. JNE INT60H_NO04H CALL INT60H_04H JMP INT60H_EXIT INT60H_NO04H: CMP AH, 05H ;ATOI de C. JNE INT60H_NO05H CALL INT60H_05H JMP INT60H_EXIT INT60H_NO05H: CMP AH, 06H ;ITOA de C. JNE INT60H_NO06H CALL INT60H_06H JMP INT60H_EXIT INT60H_NO06H: CMP AH, 07H ;El SCANF de C. JNE INT60H_NO07H CALL INT60H_07H JMP INT60H_EXIT INT60H_NO07H: CMP AH, 08H ;Inicia el 8279. JNE INT60H_NO08H CALL INT60H_08H JMP INT60H_EXIT INT60H_NO08H: CMP AH, 09H ;Termina el 8279. JNE INT60H_NO09H CALL INT60H_09H

Page 222: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

217

JMP INT60H_EXIT INT60H_NO09H: CMP AH, 0AH ;Cambia la matriz del teclado. JNE INT60H_NO0AH CALL INT60H_0AH JMP INT60H_EXIT INT60H_NO0AH: CMP AH, 0BH ;Obtiene la INT empleada por el tecl ado. JNE INT60H_NO0BH CALL INT60H_0BH JMP INT60H_EXIT INT60H_NO0BH: CMP AH, 0CH ;Imprime en HEX un numero de 8 bits. JNE INT60H_NO0CH CALL INT60H_0CH JMP INT60H_EXIT INT60H_NO0CH: CMP AH, 0DH ;Controla la ejecucion del reloj del sistema. JNE INT60H_NO0DH CALL INT60H_0DH JMP INT60H_EXIT INT60H_NO0DH: CMP AH, 0EH ;Convierte de 8 bits a BCD. JNE INT60H_NO0EH CALL INT60H_0EH JMP INT60H_EXIT INT60H_NO0EH: CMP AH, 0FH ;Convierte de BCD a 8 bits. JNE INT60H_NO0FH CALL INT60H_0FH JMP INT60H_EXIT INT60H_NO0FH: CMP AH, 10H ;Activa/desactiva la comunicacion co n el depurador. JNE INT60H_NO10H CALL INT60H_10H JMP INT60H_EXIT INT60H_NO10H: INT60H_EXIT: IRET ENDP ;************************************************** ********************** INT60H_00H PROC ;Imprime un numero en HEX de 16 bi ts. PUSH AX PUSH BX PUSH CX MOV CX, 04H ;Corrimiento. I60H_00H_SIG_NUM: MOV AL, BH AND AL, 0F0H ;Obtenemos los 4 bits. SHR AL, 04H ;Los recorremos. ADD AL, 30H ;Por si es un numero. CMP AL, 3AH ;Es una letra? JB I60H_00H_CONTINUA1 ADD AL, 07H ;Para convertirlo a letra. I60H_00H_CONTINUA1: CALL INT10H_0EH ;Se imprime el numero. SHL BX, 04H ;Siguiente numero. LOOP I60H_00H_SIG_NUM POP CX POP BX POP AX RET ENDP ;************************************************** ********************** INT60H_01H PROC ;Imprime un numero en BIN, 8 bits. PUSH AX PUSH BX PUSH CX MOV CX, 08H I60H_01H_SIG_NUM:

Page 223: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

218

MOV AL, 30H ;Por default es cero. SAL BL, 01H ;Un desplazamiento de un bit JNC I60H_01H_CONTINUA1 INC AL I60H_01H_CONTINUA1: CALL INT10H_0EH ;Se imprime el numero. LOOP I60H_01H_SIG_NUM POP CX POP BX POP AX RET ENDP ;************************************************** ********************** INT60H_02H PROC ;Imprime un numero en decimal, 16 bits. PUSH AX PUSH BX PUSH CX PUSH DX PUSH DI XOR CX, CX ;Corrimiento MOV AX, BX ;Colocamos el divisor. XOR BX, BX MOV DI, 0AH ;Contador I60H_02H_CONTINUA1: XOR DX, DX DIV DI ;Obtenemos el primer digito, en AX el res iduo. AND DX, 0FH ;Buscamos el digito. SHL DX, CL ;Lo recorremos. OR BX, DX ;Ya esta el numero. ADD CL, 04H ;Siguiente recorrido. CMP AX, 00H JE I60H_02H_TERMINA INC CH CMP CH, 04H ;Solo cuatro digitos. JNE I60H_02H_CONTINUA1 I60H_02H_TERMINA: ADD AL, 30H ;El ultimo digito. CALL INT10H_0EH CALL INT60H_00H ;Los ultimos cuatro digitos. I60H_02H_EXIT: POP DI POP DX POP CX POP BX POP AX RET ENDP ;************************************************** ********************** INT60H_03H PROC PUSH AX PUSH SI PUSHF CLD I60H_03H_CONTINUA: LODSB AND AL, AL JZ I60H_03H_EXIT CALL INT10H_0EH JMP I60H_03H_CONTINUA I60H_03H_EXIT: POPF POP SI POP AX RET ENDP ;************************************************** ********************** INT60H_04H PROC PUSH AX PUSH SI PUSHF CLD

Page 224: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

219

XOR CX, CX I60H_04H_CONTINUA: LODSB AND AL, AL JZ I60H_04H_EXIT INC CX JMP I60H_04H_CONTINUA I60H_04H_EXIT: POPF POP SI POP AX RET ENDP ;************************************************** ********************** INT60H_05H PROC PUSH AX PUSH CX PUSH DX PUSH SI PUSH DI PUSHF XOR DI, DI XOR BX, BX INC DI CALL INT60H_04H ;Mide la cadena. AND CX, CX JZ I60H_05H_EXIT ADD SI, CX ;Coloca en la posicion. DEC SI STD ;Para atras. I60H_05H_CONTINUA: LODSB SUB AL, 30H ;Lo convierte a un numero. XOR AH, AH MUL DI ADD BX, AX MOV AX, DI MOV DI, 000AH MUL DI MOV DI, AX LOOP I60H_05H_CONTINUA I60H_05H_EXIT: POPF POP DI POP SI POP DX POP CX POP AX RET ENDP ;************************************************** ********************** INT60H_06H PROC PUSH AX PUSH BX PUSH CX PUSH DX PUSH DI PUSHF MOV AX, BX ;Colocamos el divisor. XOR BX, BX ;Contador AND CX, 001FH I60H_06H_CONTINUA1: XOR DX, DX DIV CX ;Obtenemos el primer digito, en AX el res iduo. PUSH DX ;Guardamos en la pila el digito. INC BX ;Contador de digitos. AND AX, AX JNZ I60H_06H_CONTINUA1 MOV CX, BX I60H_06H_CONTINUA2: POP AX

Page 225: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

220

ADD AL, 30H CMP AL, 3AH JB I60H_06H_CONTINUA3 ADD AL, 07H I60H_06H_CONTINUA3: STOSB LOOP I60H_06H_CONTINUA2 I60H_06H_EXIT: XOR AL, AL ;Coloca fin de cadena. STOSB POPF POP DI POP DX POP CX POP BX POP AX RET ENDP ;************************************************** ********************** INT60H_07H PROC PUSH AX PUSH BX PUSH DX PUSH DI PUSHF CLD MOV BL, DL ;Prompt. XOR DL, DL CALL INT10H_02H ;Fijamos la posicion. CALL INT10H_0FH ;Obtenemos las columnas. MOV BH, AH ;Numero de caracteres. DEC BH ;En realidad es -1. MOV CL, BH XOR CH, CH MOV AL, KSPACE I60H_07H_SPC: CALL INT10H_0EH ;Colocamos espacio en todo el ren glon. LOOP I60H_07H_SPC CALL INT10H_09H XOR DL, DL CALL INT10H_02H ;Fijamos la posicion. AND BL, BL JZ I60H_07H_CONTINUA3 MOV AL, BL MOV BL, 01H MOV DL, BL CALL INT10H_0EH I60H_07H_CONTINUA3: I60H_07H_LEE: CALL INT16H_00H ;Leemos un caracter. CMP AL, KENTER JE I60H_07H_TERMINA CMP AL, KBACKSP ;Hay retroceso. JNE I60H_07H_CONTINUA2 MOV AL, KSPACE CMP DL, BL JE I60H_07H_LEE DEC DI DEC DL STOSB CALL INT10H_02H CALL INT10H_0EH CALL INT10H_03H DEC DI DEC DL CALL INT10H_02H JMP I60H_07H_LEE I60H_07H_CONTINUA2: CMP DL, BH ;Solo 15 o 19 caracteres. JE I60H_07H_LEE STOSB ;Guarda el caracter.

Page 226: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

221

INC DL I60H_07H_CONTINUA1: CALL INT10H_0EH CALL INT10H_02H JMP I60H_07H_LEE I60H_07H_TERMINA: XOR AL, AL STOSB MOV CL, DL SUB CL, BL XOR CH, CH POPF POP DI POP DX POP BX POP AX RET ENDP ;************************************************** ********************** INT60H_08H PROC CALL INICIA_KEYBOARD CALL INT16H_13H ;Inicia el buffer de teclado. RET ENDP ;************************************************** ********************** INT60H_09H PROC PUSH BX PUSH CX PUSH DX PUSH DS XOR AX, AX MOV DS, AX MOV BX, KEY_CARACTER_DATA ;Datos del teclado. MOV AL, [BX] ;Se obtiene el Chip-Select. AND AL, 07H ;Obtenemos los 3 bits significativos . MOV DL, AL ;Para salvar el Chip-Select. MOV CL, 04H ;Ya que ocupa 4 bytes cada Chip-Sele ct. MUL CL MOV CL, DL ;Salvamos el Chip-Select. MOV DX, INI_GCS0 ;Chip Select GCS0. ADD DX, AX INC DX INC DX XOR AX, AX ;Se desactiva. OUT DX, AL ;Fin de GCSX. INC BX MOV CH, [BX] ;Ahora la INT. AND CH, 03H ;Para obtener la INT. MOV AL, CH MOV DL, CL MOV CL, 02H MUL CL MOV CL, DL ;Aqui continua el Chip-Select. MOV DX, INT_INT0 ;Activa la interrupcion INTX. ADD DX, AX ;Obtiene la INT. XOR AX, AX OUT DX, AL ;Desactiva la INTX. MOV AX, CX ;Retorna. POP DS POP DX POP CX POP BX RET ENDP ;************************************************** ********************** INT60H_0AH PROC PUSH AX PUSH SI PUSH DI PUSH ES

Page 227: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

222

PUSH DS PUSHF ;Carga las matrices del teclado. XOR AX, AX MOV ES, AX ;Destino MOV DI, KEY_CARACTER MOV CX, KEY_CHARS CLD REPE MOVSB ;Carga las matrices. POPF POP DS POP ES POP DI POP SI POP AX RET ENDP ;************************************************** ********************** INT60H_0BH PROC CALL RET_INT_KEYBOARD RET ENDP ;************************************************** ********************** INT60H_0CH PROC ;Imprime un numero en HEX de 8 bit s. PUSH AX PUSH BX PUSH CX MOV CX, 02H ;Corrimiento. I60H_0CH_SIG_NUM: MOV AL, BL AND AL, 0F0H ;Obtenemos los 4 bits. SHR AL, 04H ;Los recorremos. ADD AL, 30H ;Por si es un numero. CMP AL, 3AH ;Es una letra? JB I60H_0CH_CONTINUA1 ADD AL, 07H ;Para convertirlo a letra. I60H_0CH_CONTINUA1: CALL INT10H_0EH ;Se imprime el numero. SHL BL, 04H ;Siguiente numero. LOOP I60H_0CH_SIG_NUM POP CX POP BX POP AX RET ENDP ;************************************************** ********************** INT60H_0DH PROC ;Controla la ejecucion del reloj d el sistema. PUSH AX PUSH BX PUSH DX PUSH DS MOV BX, AX MOV DX, TEMP_TMP1_CTRL ;La direccion en el PCB re gistro de control IN AL, DX ;Obtiene el valor del registro. AND BL, 01H JZ I60H_0DH_INACTIVA ;Inhabilita la interrupcio n OR AX, 0E000H ;Activa la interrupcion. JMP I60H_0DH_CONTINUA I60H_0DH_INACTIVA: XOR BX, BX MOV DS, BX MOV BX, TEMPORIZADOR_FLAG MOV BYTE PTR [BX], 01H ;Activa la bandera de ter minacion. AND AX, 0DFFFH I60H_0DH_CONTINUA: OUT DX, AL ;Activa/inactiva la INT del temporiza dor 1 POP DS POP DX POP BX POP AX RET

Page 228: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

223

ENDP ;************************************************** ********************** INT60H_0EH PROC ;Convierte de 8 bits a BCD. PUSH CX MOV CH, AH XOR AH, AH MOV CL, 0AH ;Divisor entre 10. DIV CL ;AL=Decenas, AH = unidades. SHL AL, 04H OR AL, AH ;BCD. MOV AH, CH POP CX RET ENDP ;************************************************** ********************** INT60H_0FH PROC ;Convierte de BCD a 8 bits. PUSH CX PUSH BX MOV CX, AX AND CL, 0FH ;Unidades. SHR AL, 04H ;Centenas XOR AH, AH MOV BL, 0AH MUL BL ADD AL, CL MOV AH, CH POP BX POP CX RET ENDP ;************************************************** ********************** INT60H_10H PROC ;Activa/Desactiva las comunicacion es con el depurador PUSH AX PUSH BX PUSH CX PUSH DS XOR BX, BX MOV DS, BX MOV BX, VELOCIDAD_DEPURADOR MOV CX, [BX] AND AL, 01H ;Para asegurar el 1 o 0. JZ I60H_10H_OFF ;Desactiva MOV BX, CX CALL INICIA_COM_DEPURADOR CALL SER0_LIMPIACOLA ;Limpia la cola CALL SER0_LIMPIAPUERTO ;Limpia el puerto MOV BL, CMSCONECTAR CALL SER0_SENDE JMP I60H_10H_TERMINA I60H_10H_OFF: MOV BL, CMSDESCONECT CALL SER0_SENDE MOV DX, INT_SERIAL MOV AX, 0008H OUT DX, AL ;Deshabilita la interrupcion. MOV DX, SER0_CTRL XOR AX, AX OUT DX, AL ;Quitamos puerto serie 0 I60H_10H_TERMINA: POP DS POP CX POP BX POP AX RET ENDP ;************************************************** **********************

Page 229: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

224

E.26 INT61Y62.ASM ;EN ESTE ARCHIVO ESTAN CONTENIDOS TODOS LOS PROCEDIMIENTOS ;NECESARIOS PARA EL MANEJO DE LAS INTERRUPCIONES 61 H Y 62H. ;SE ASUME QUE LA PILA YA SE HA INICIADO. ;************************************************** ********************** ;NOTAS: ; ; ; ;************************************************** ********************** INTERRUPT_INT61H PROC PUSH BX PUSH DS MOV BX, EQUIPMENT_FLAG MOV AX, [BX] POP DS POP BX IRET ENDP ;************************************************** ********************** INTERRUPT_INT62H PROC PUSH BX PUSH DS MOV BX, MEMORY_SIZE MOV AX, [BX] POP DS POP BX IRET ENDP ;************************************************** **********************

E.27 INT63.ASM ;EN ESTE ARCHIVO ESTAN CONTENIDOS TODOS LOS PROCEDIMIENTOS ;NECESARIOS PARA EL MANEJO DE LA INTERRUPCION 63H ( PUERTO SERIE). ;SE ASUME QUE LA PILA YA SE HA INICIADO. ;************************************************** ********************** ;NOTAS: EN LA TARJETA SERIAL0 ES COM1 Y SERIAL1 ES COM2. ; ; ; ;************************************************** ********************** SER_VEL_00110 EQU 3543H ;Velocidad de 110b SER_VEL_00150 EQU 270FH ;Velocidad de 150b SER_VEL_00300 EQU 1387H ;Velocidad de 300b SER_VEL_00600 EQU 09C3H ;Velocidad de 600b SER_VEL_01200 EQU 04E1H ;Velocidad de 1200b SER_VEL_02400 EQU 0270H ;Velocidad de 2400b SER_VEL_04800 EQU 0138H ;Velocidad de 4800b SER_VEL_09600 EQU 009BH ;Velocidad de 9600b SER_VEL_19200 EQU 004DH ;Velocidad de 19200b, sol o es valida en la extendida. SER_7_BITS_P EQU 01H ;7 bits con paridad. SER_7_BITS_S EQU 04H ;7 bits sin paridad. SER_8_BITS_P EQU 03H ;8 bits con paridad. SER_8_BITS_S EQU 01H ;8 bits sin paridad. SER_ADD_STAT EQU 0006H ;Se suma 6 a la direccion para el estado. SER_CAN_TRANS EQU 0008H ;Para ver si se puede tra nsmitir. SER_CAN_RECEV EQU 0040H ;Para ver si se puede re cibir. INTERRUPT_INT63H PROC

Page 230: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

225

CMP AH, 00H ;Inicializa el puerto de comunicacio nes. JNE INT63H_NO00H CALL INT63H_00H JMP INT63H_EXIT INT63H_NO00H: CMP AH, 01H ;Escribe un caracter en el puerto. JNE INT63H_NO01H CALL INT63H_01H JMP INT63H_EXIT INT63H_NO01H: CMP AH, 02H ;Lee un caracter del puerto. JNE INT63H_NO02H CALL INT63H_02H JMP INT63H_EXIT INT63H_NO02H: CMP AH, 03H ;Estado del puerto. JNE INT63H_NO03H CALL INT63H_03H JMP INT63H_EXIT INT63H_NO03H: INT63H_EXIT: IRET ENDP ;************************************************** ********************** ;*************** SUBFUNCIONES DE LA INTERRUPCION 14 H ******************** ;************************************************** ********************** INT63H_00H PROC ;Inicializa el puerto. PUSH BX PUSH DX PUSH DS MOV DH, AL ;Salvo el parametro de inicio. XOR AX, AX ;Obtenemos la direccion del puerto MOV DS, AX MOV BX, COM1_ADDRESS ;Para saber la direccion del puerto. AND DL, 03H ;Solo se usan 2 bits para el tipo de puerto. SHL DL, 01H ADD BL, DL ;Con esto sabemos que puerto, COM1, C OM2, etc. MOV AL, DH ;Regresamos el parametro de inicio. MOV DX, [BX] ;Direccion del puerto. MOV BL, AL ;Trabajamos con BX. MOV BH, AL ADD DX, SER_ADD_STAT IN AX, DX ;Limpiamos el estado del serial. SUB DX, SER_ADD_STAT AND BL, 0E0H ;Primero la velocidad. SHR BL, 05H ;En BL esta la velocidad. CMP BL, 00H JNE I63H_00H_NO110 ;No es velocidad de 110. MOV AX, SER_VEL_00110 JMP I63H_00H_CONTINUA I63H_00H_NO110: CMP BL, 01H JNE I63H_00H_NO150 ;No es velocidad de 150. MOV AX, SER_VEL_00150 JMP I63H_00H_CONTINUA I63H_00H_NO150: CMP BL, 02H JNE I63H_00H_NO300 ;No es velocidad de 300. MOV AX, SER_VEL_00300 JMP I63H_00H_CONTINUA I63H_00H_NO300: CMP BL, 03H JNE I63H_00H_NO600 ;No es velocidad de 600. MOV AX, SER_VEL_00600 JMP I63H_00H_CONTINUA I63H_00H_NO600: CMP BL, 04H JNE I63H_00H_NO1200 ;No es velocidad de 1200. MOV AX, SER_VEL_01200 JMP I63H_00H_CONTINUA I63H_00H_NO1200:

Page 231: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

226

CMP BL, 05H JNE I63H_00H_NO2400 ;No es velocidad de 2400. MOV AX, SER_VEL_02400 JMP I63H_00H_CONTINUA I63H_00H_NO2400: CMP BL, 06H JNE I63H_00H_NO4800 ;No es velocidad de 4800. MOV AX, SER_VEL_04800 JMP I63H_00H_CONTINUA I63H_00H_NO4800: MOV AX, SER_VEL_09600 ;Debe ser de 9600. I63H_00H_CONTINUA: OR AX, 8000H ;Para indicar reloj interno. OUT DX, AL ;Coloca la velocidad. INC DX INC DX XOR AX, AX OUT DX, AX ;Limpia el contador. INC DX INC DX MOV BL, BH AND BL, 01H ;Para ver si es de 7 u 8 bits. JNZ I63H_00H_8_BITS ;Es de 8 bits. MOV BL, BH AND BL, 08H ;Es paridad o sin paridad. JZ I63H_00H_7BITS_S;Sin paridad. MOV AL, SER_7_BITS_P JMP I63H_00H_EXIT I63H_00H_7BITS_S: MOV AL, SER_7_BITS_S JMP I63H_00H_EXIT I63H_00H_8_BITS: MOV BL, BH AND BL, 08H ;Es paridad o sin paridad. JZ I63H_00H_8BITS_S;Sin paridad. MOV AL, SER_8_BITS_P JMP I63H_00H_EXIT I63H_00H_8BITS_S: MOV AL, SER_8_BITS_S I63H_00H_EXIT: AND BH, 18H OR AL, BH ;Tenemos el control del serial. OR AL, 20H ;Habilitamos el serial. OUT DX, AL INC DX INC DX IN AX, DX ;Estado de puerto. POP DS POP DX POP BX RET ENDP ;************************************************** ********************** INT63H_01H PROC ;Escribe un caracter. PUSH BX PUSH DX PUSH DS MOV DH, AL ;Salvo el caracter a enviar. XOR AX, AX ;Obtengo en DX la direccion. MOV DS, AX MOV BX, COM1_ADDRESS ;Para saber la direccion del puerto. AND DL, 03H ;Solo se usan 2 bits para el tipo de puerto. SHL DL, 01H ADD BL, DL ;Con esto sabemos que puerto, COM1, C OM2, etc. MOV AL, DH ;Regresamos el caracter. MOV DX, [BX] ;Direccion del puerto. ADD DX, SER_ADD_STAT ;Para el registro de estado. MOV BL, AL ;Salvamos el caracter. IN AX, DX ;Leemos el estado. PUSH AX AND AX, SER_CAN_TRANS ;Se puede enviar??

Page 232: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

227

JZ I63H_01H_NO_SEND;No se puede enviar. INC DX INC DX INC DX INC DX MOV AL, BL OUT DX, AL ;Se envia el caracter. POP AX MOV AL, BL XOR AH, AH JMP I63H_01H_EXIT I63H_01H_NO_SEND: POP AX OR AH, 80H I63H_01H_EXIT: POP DS POP DX POP BX RET ENDP ;************************************************** ********************** INT63H_02H PROC ;Recibe un caracter. PUSH BX PUSH DX PUSH DS XOR AX, AX ;Obtengo la direccion de puerto MOV DS, AX MOV BX, COM1_ADDRESS ;Para saber la direccion del puerto. AND DL, 03H ;Solo se usan 2 bits para el tipo de puerto. SHL DL, 01H ADD BL, DL ;Con esto sabemos que puerto, COM1, C OM2, etc. MOV DX, [BX] ;Direccion del puerto. ADD DX, SER_ADD_STAT ;Para el registro de estado. IN AX, DX ;Leemos el estado. PUSH AX ;Se salva el estado. AND AX, SER_CAN_RECEV ;Se puede recibir? JZ I63H_02H_NO_RECV ;No se puede recibir. POP AX INC DX INC DX IN AX, DX ;Se recibe el caracter. XOR AH, AH JMP I63H_02H_EXIT I63H_02H_NO_RECV: POP AX OR AH, 80H I63H_02H_EXIT: POP DS POP DX POP BX RET ENDP ;************************************************** ********************** INT63H_03H PROC ;Lee el estado del puerto. PUSH BX PUSH DX PUSH DS XOR AX, AX ;Obtengo la direccion de puerto MOV DS, AX MOV BX, COM1_ADDRESS ;Para saber la direccion del puerto. AND DL, 03H ;Solo se usan 2 bits para el tipo de puerto. SHL DL, 01H ADD BL, DL ;Con esto sabemos que puerto, COM1, C OM2, etc. MOV DX, [BX] ;Direccion del puerto. ADD DX, SER_ADD_STAT ;Para el registro de estado. IN AX, DX ;Leemos el estado. POP DS POP DX POP BX ENDP

Page 233: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

228

;************************************************** **********************

E.28 INT70.ASM ;EN ESTE ARCHIVO ESTAN CONTENIDOS TODOS LOS PROCEDIMIENTOS ;NECESARIOS PARA EL MANEJO DE LA INTERRUPCION 70H ( TEMPORIZADORES). ;SE ASUME QUE LA PILA YA SE HA INICIADO. ;************************************************** ********************** ;NOTAS: PARA LA OBTENER LA FRECUENCIA DESEADA SE HA CE LO SIGUIENTE: ; FCPU = 12MHZ, FTIMERS = FCPU / 4 = 3MHZ ; COMP A = COMP B = (FTIMERS / FRECDESEADA) / 2 ; ;LO ANTERIOR SI SE DESEA UN SE¥ALA SIMETRICA; EN OT RO CASO, SE DEBERA ;MOVER EL VALOR DE LOS COMPARADORES, PERO RESPETANDO: ; ; COMP A + COMP B = FTIMERS / FRECDESEADA ; ; ;************************************************** ********************** INTERRUPT_INT70H PROC PUSH DX CMP AH, 00H ;Temporizador 0. JNE INT70H_NO00H MOV DX, TEMP_TMP0 ;Direccion PCB del temporizador 0 CALL INT70H_00H JMP INT70H_EXIT INT70H_NO00H: CMP AH, 01H ;Temporizador 1. JNE INT70H_NO01H MOV DX, TEMP_TMP1 ;Direccion PCB del temporizador 1 CALL INT70H_00H JMP INT70H_EXIT INT70H_NO01H: CMP AH, 02H ;Temporizador 2. JNE INT70H_NO02H MOV DX, TEMP_TMP2 ;Direccion PCB del temporizador 2 CALL INT70H_02H JMP INT70H_EXIT INT70H_NO02H: INT70H_EXIT: POP DX IRET ENDP ;************************************************** ********************** INT70H_00H PROC ;Temporizadores 0 y 1. PUSH AX PUSH DI MOV DI, AX ;Salvamos el control. MOV AX, SI OUT DX, AL ;Contador INC DX INC DX MOV AX, BX OUT DX, AL ;Comparador A. INC DX INC DX MOV AX, CX OUT DX, AL ;Comparador B. INC DX INC DX MOV AX, DI AND AX, 000FH ;Solo dejamos los 4 bits menos sig nificativos. OR AX, 0C000H ;Para activar el temporizador. OUT DX, AL POP DI POP AX RET ENDP

Page 234: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

229

;************************************************** ********************** INT70H_02H PROC ;Temporizador 2. PUSH AX PUSH DI MOV DI, AX ;Salvamos el control. MOV AX, SI OUT DX, AL ;Contador INC DX INC DX MOV AX, BX OUT DX, AL ;Comparador A. INC DX INC DX INC DX INC DX MOV AX, DI AND AX, 000FH ;Solo dejamos los 4 bits menos sig nificativos. OR AX, 0C000H ;Para activar el temporizador. OUT DX, AL POP DI POP AX RET ENDP ;************************************************** **********************

E.29 KEYBOARD.ASM ;EN ESTE ARCHIVO ESTAN CONTENIDOS TODOS LOS PROCEDIMIENTOS ;NECESARIOS PARA EL MANEJO DE INTERRUPCION DEL TECL ADO Y EL 8279. ;SE ASUME QUE LA PILA YA SE HA INICIADO. ;************************************************** ********************** ;NOTAS: ; ; ; ;************************************************** ********************** KEY_COM8279 EQU 01H ;IN y OUT para el teclado. KEY_RAM8279 EQU 00H ;Leer la RAM del 8279. KEY_STW8279 EQU 01H ;Leer la palabra de estado d el 8279. KEY_CAPS EQU 0BH ;Activar mayusculas/minuscu las. ;************************************************** ******************* ;INICIA EL 8279 PARA EL TECLADO. ;PARAMETROS: ; AL = Numero de Chip-Selec 0 - 7. ; BH = DIVISOR DE FRECUENCIA 0 - 31. ; BL = MODO DEL TECLADO. ; CH = Numero de INT 0 - 3. INICIA_KEYBOARD PROC PUSH AX PUSH BX PUSH CX PUSH DX PUSH DI PUSH SI PUSH ES PUSH DS PUSHF CLI ;Desactiva interrupciones. XOR DX, DX MOV DS, DX PUSH BX MOV BX, KEY_CARACTER_DATA ;Datos del 8279. ;Se programa el Chip-Select GCSX (TECLADO). AND AL, 07H ;Obtenemos los 3 bits significativos . MOV [BX], AL ;Almacena el Chip-Select INC BX

Page 235: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

230

MOV CL, 04H ;Ya que ocupa 4 bytes cada Chip-Sele ct. MUL CL MOV DX, INI_GCS0 ;Chip Select GCSX. ADD DX, AX ;Por default la direccion de inicio es 00H hasta 40H. MOV AX, 000FH ;Inicio: 00h, 15 edos. de espera. OUT DX, AL INC DX INC DX MOV AX, 0048H ;Fin: 40h. OUT DX, AL ;Fin de GCSX. ;Se inicia el vector del teclado. MOV DX, INTERRUPT_KEY_8279 AND CH, 03H ;Para obtener la INT. MOV [BX], CH ;Almacena la INT. MOV AX, CS MOV DS, AX ;Para el segmento del servicio. POP BX MOV AL, VINT_INT0 ;De base esta la INT0. ADD AL, CH CALL INT21H_25H ;Se emplea BX! CALL KEY_INICIA_8279 ;Inicia la programaci¢n del 8279. MOV AL, CH MOV CL, 02H MUL CL MOV DX, INT_INT0 ;Activa la interrupcion INTX. ADD DX, AX ;Obtiene la INT. MOV AX, 0010H ;Activa la INTX. OUT DX, AL ;Carga las matrices del teclado. XOR AX, AX MOV ES, AX ;Destino MOV DI, KEY_CARACTER MOV AX, CS MOV DS, AX ;Origen. MOV SI, MATRIZ_ASCII_MIN ;La matriz del teclado. MOV CX, KEY_CHARS CLD REPE MOVSB ;Carga las matrices. STI ;Activa interrupciones. POPF POP DS POP ES POP SI POP DI POP DX POP CX POP BX POP AX RET ENDP ;************************************************** ******************* ;INICIA EL 8279 PARA EL TECLADO. ;PARAMETROS: ; BH = DIVISOR DE FRECUENCIA 0 - 31 ; BL = MODO DEL TECLADO KEY_INICIA_8279 PROC PUSH AX PUSH DX MOV AL, BH AND AL, 3FH OR AL, 20H ;Para verificar que se escriban las banderas. OUT KEY_COM8279, AL ;Primero el divisor. MOV AL, BL AND AL, 1FH OUT KEY_COM8279, AL ;Ahora el comando. IN AL, KEY_STW8279 ;Leeo el status word. POP DX

Page 236: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

231

POP AX RET ENDP ;************************************************** ******************* ;INTERRUPCION DEL 8279 PARA EL TECLADO, AGREGA AL B UFFER DEL TECLADO. ;************************************************** ******************* INTERRUPT_KEY_8279 PROC ;C¢digo de la interrupcio n del teclado. PUSH AX PUSH BX PUSH CX PUSH DX PUSH SI PUSH DS XOR AX, AX MOV DS, AX MOV BX, KEYBOARD_STATUS_FLAG ;Las banderas. MOV CL, [BX] ;Obtenemos las banderas. IN AL, KEY_RAM8279 ;Leemos el caracter tecleado. MOV CH, AL ;Salvamos el scan. MOV AH, AL ;Aqui va estar el scan, en AH. AND CH, 3FH ;Obtenemos el renglon/columna, 3 bits de cada uno. CMP CH, KEY_CAPS ;Se presiono la tecla CAPS? JNE INTKEY_8279NOCAPS XOR CL, 40H ;Con esto se activa/desactiva. INTKEY_8279NOCAPS: AND CL, 40H ;Solo CAPS. AND AH, 0C0H ;Obtenemos si se presiono SHFT y/o CTRL SHR AH, 05H ;Estan en posicion para las banderas . OR CL, AH MOV [BX], CL ;Se guardan las banderas. CH=SCAN, CL=BANDERAS CMP CH, KEY_CAPS ;Se presiono la tecla CAPS? JE INTKEY_8279END;Salimos. MOV AL, CL MOV AH, CL SHR AL, 01H ;En AL esta el SHFT. SHR AH, 06H ;En AH esta CAPS. MOV BX, KEY_CARACTER ;Para acceder a la matriz. XOR AL, AH AND AL, 01H JZ INTKEY_8279CONTINUA_0 MOV BX, KEY_CARACTER_MAY ;Matriz de mayusculas. INTKEY_8279CONTINUA_0: ;MOV AX, CS ;Seguimos con CH=SCAN, CL=BANDERAS. XOR AX, AX ;Se fija el segmento. MOV DS, AX ;Fijamos el segmento para acceder a l a matriz. MOV AH, CH ;Obtenemos el renglon/columna, 3 bits de cada uno. SHR AH, 03H ;Tenemos en AH el renglon. MOV AL, 08H ;Numero de caracteres por renglon. MUL AH ;Con esto tenemos el OFFSET logico. ADD BX, AX ;Ya tenemos el OFFSET fisico. MOV AL, CH ;De nuevo el scan. MOV AH, CH AND AL, 07H ;La columna. XLAT ;AL=CARACTER, AH=SCAN, CL=BANDERAS. AND CL, 04H ;Para ver si se presiono control. JZ INTKEY_8279CONTINUA_1 AND AL, 9FH ;Se presiono control, se eliminan bi ts 5 y 6. INTKEY_8279CONTINUA_1: ;Se guarda AX en el buffer d el teclado. XOR CX, CX ;Para guardar al buffer de teclado. MOV DS, CX MOV SI, START_KEYBOARD_DATA;Direccion del buffer. MOV BX, [SI] ;Direccion del buffer de teclado. MOV CX, [BX] ;Primer word del buffer de teclado. Fin de cola. INC CX INC CX ;Lo incrementa para agregar la tecla. CMP CX, [SI+ADD_KEYBOARD_DATA];Fin de buffer? JBE INTKEY_8279CONTINUA_2

Page 237: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

232

MOV CX, BX INC CX INC CX INC CX INC CX INTKEY_8279CONTINUA_2: CMP CX, [BX+KEY_INI_TAIL];Es igual al inicio de l a cola? JE INTKEY_8279END ;No guarda nada y sale. MOV SI, CX MOV [SI], AX ;Guarda el caracter. MOV [BX], CX ;Guarda la direccion de la cola. INTKEY_8279END: MOV DX, INT_END_INT ;Fin de interrupcion no espec . MOV AX, 8000H OUT DX, AL POP DS POP SI POP DX POP CX POP BX POP AX IRET ENDP ;************************************************** ******************* ;RETORNA LA INT CORRESPONDIENTE DEL TECLADO. ;RETORNA: ; AL = NUMERO DE INTERRUPCION POR HARDWARE ;************************************************** ******************* RET_INT_KEYBOARD PROC PUSH ES PUSH BX XOR BX, BX MOV ES, BX MOV BX, KEY_CARACTER_DATA_IT MOV AH, ES:[BX] POP BX POP ES RET ENDP ;************************************************** ******************* ;MATRICES DEL TECLADO, PUEDE CAMBIAR SEGUN EL TECLA DO. ;************************************************** ******************* MATRIZ_ASCII_MIN: ;ORIGINAL DB 0EEH, 00H, "q", 09H, "a", 00H, "z", 00H ;1 DB "7", 00H, "w", 0FFH, "s", 00H, "x", 00H ;2 DB "8", 00H, "e", 00H, "d", 00H, "c", 00H ;3 DB "5", 00H, "r", "t", "f", 00H, "v", 00H ;4 DB "6", 00H, "u", "y", "j", 00H, "m", 00H ;5 DB "b", "9", "o", "n", "l", "g", "k", "h" ;7 DB "-", "0", "p", "i", 3BH, 27H, 00H, "\" ;8 DB "1", "2", "3", 08H, 5CH, "4", 0DH, 20H ;9 ;************************************************** ******************* MATRIZ_ASCII_MAY: ;ORIGINAL DB 0EEH, 00H, "Q", 09H, "A", 00H, "Z", 00H ;1 DB 26H, 00H, "W", 0FFH, "S", 00H, "X", 00H ;2 DB 2AH, 00H, "E", 00H, "D", 00H, "C", 00H ;3 DB 25H, 00H, "R", "T", "F", 00H, "V", 00H ;4 DB "^", 00H, "U", "Y", "J", 00H, "M", 00H ;5 DB "B", 28H, "O", "N", "L", "G", "K", "H" ;7 DB "_", 29H, "P", "I", ":", 22H, 00H, 3FH ;8 DB 21H, "@", 23H, 08H, 7CH, 24H, 0DH, 20H ;9 ;************************************************** *******************

E.30 RELOJ.ASM ;EN ESTE ARCHIVO ESTAN CONTENIDOS TODOS LOS PROCEDIMIENTOS ;NECESARIOS PARA EL MANEJO DEL RELOJ. ;SE ASUME QUE LA PILA YA SE HA INICIADO.

Page 238: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

233

;************************************************** ******************* ;INTERRUPCION DEL RELOJ, ACTUALIZA LOS TICKS. ;************************************************** ******************* INTERRUPT_RELOJ_T1 PROC PUSH AX PUSH BX PUSH CX PUSH DX PUSH DS MOV DX, TEMP_TMP1_CTRL IN AX, DX ;Obtenemos el registro de control. AND AX, COMPARADOR_B ;Si es CERO esta en el compa rador A. JZ INT_RELOJ_T1_END XOR BX, BX ;Es el comparador B, continua. MOV DS, BX MOV BX, LWORD_TIMER MOV AX, [BX] ;Carga la parte baja de los ticks INC BX INC BX MOV CX, [BX] ;Carga la parte alta de los ticks INC AX ;Incrementa los ticks JNZ INT_RELOJ_T1_CONTINUA INC CX INT_RELOJ_T1_CONTINUA: CMP CX, RELOJ_HTICKS JNE INT_RELOJ_T1_TERMINA CMP AX, RELOJ_LTICKS ;Llega hasta 1FA400H ticks. JNE INT_RELOJ_T1_TERMINA XOR AX, AX ;Limpia los ticks. XOR CX, CX PUSH BX MOV BX, MIDNIGHT_FLAG MOV BYTE PTR [BX], 01H;Actualiza la bandera de me dia-noche POP BX INT_RELOJ_T1_TERMINA: MOV [BX], CX ;Retorna los ticks, parte alta DEC BX DEC BX MOV [BX], AX ;Retorna los ticks, parte baja MOV BX, TEMPORIZADOR ;Ahora el temporizador DEC WORD PTR [BX] ;Decrementa el contador JNZ INT_RELOJ_T1_END1 ;No se ha cumplido el tiemp o INC BX INC BX MOV BYTE PTR [BX], 01H;Se enciende la bandera INT_RELOJ_T1_END1: INT 1CH ;Llama a la interrupcion 1CH. INT_RELOJ_T1_END: MOV DX, INT_END_INT ;Fin de interrupcion no espec ifica MOV AX, 8000H OUT DX, AL POP DS POP DX POP CX POP BX POP AX IRET ENDP ;************************************************** ******************* RELOJ_REAL PROC PUSH AX PUSH DX MOV DX, TEMP_TMP1 ;La direccion en el PCB XOR AX, AX OUT DX, AL ;Contador INC DX INC DX MOV AX, RELOJ_CA OUT DX, AL ;Comparador A.

Page 239: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

234

INC DX INC DX MOV AX, RELOJ_CB OUT DX, AL ;Comparador B. INC DX INC DX MOV AX, 0E003H ;Para activar el temporizador, con interrupcion. OUT DX, AL MOV DX, INT_TIMER ;Ahora se activan las interrupc iones en el INTERRUPT TIMER CONTROL MOV AX, 0007H ;Activa y coloca la prioridad mas baja OUT DX, AL POP DX POP AX RET ENDP

E.31 SERIAL.ASM ;EN ESTE ARCHIVO ESTAN CONTENIDOS TODOS LOS PROCEDIMIENTOS ;NECESARIOS PARA EL MANEJO DEL PUERTO SERIAL. ;SE ASUME QUE LA PILA YA SE HA INICIADO. ;************************************************** ******************* ;INICIA EL PUERTO SERIAL CON INTERRUPCION (CHANNEL 0). ;PARAMETROS: ; BX = VELOCIDAD DEL PUERTO (USAR CONSTANTES) ; CX = CONTROL DEL PUERTO SER0_INICIA PROC PUSH AX PUSH BX PUSH CX PUSH DX XOR AX, AX MOV DX, SER0_CTRL ;Elimina el serial IN AX, DX MOV DX, SER0_BAUD MOV AX, BX OUT DX, AX ;Fija la velocidad INC DX INC DX XOR AX, AX OUT DX, AX ;Borra el contador INC DX INC DX MOV AX, CX AND AX, 0FFDFH ;Para quitar el REN OUT DX, AL ;Control del puerto INC DX INC DX IN AX, DX ;Limpia el estado del serial. MOV DX, INT_SERIAL ;Activa la interrupcion MOV AX, 0003H ;Prioridad MEDIA OUT DX, AL ;Habilita la interrupcion. MOV DX, SER0_CTRL ;Ahora para el control de inter rupcion IN AX, DX OR AX, 0020H OUT DX, AX ;Habilita REN POP DX POP CX POP BX POP AX RET ENDP ;************************************************** ******************* ;ENVIA UN BYTE POR EL PUERTO SERIAL. ;PARAMETROS: ; BL = BYTE A ENVIAR.

Page 240: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

235

;RETORNA: ; BH = 1 Si se envio, 0 si no. SER0_SEND PROC PUSH DX PUSH AX MOV DX, SER0_STAT IN AL, DX XOR BH, BH ;Borra la bandera AND AX, 0008H ;Revisa bit TXE JZ SER0_SEND_TERMINA INC BH MOV DX, SER0_TRAN MOV AL, BL OUT DX, AL SER0_SEND_TERMINA: POP AX POP DX RET ENDP ;************************************************** ******************* ;RECIBE UN BYTE POR EL PUERTO SERIAL. ;RETORNA: ; AL = BYTE RECIBIDO. ; AH = 1 Se recibio, 0 si no. SER0_RECEV PROC PUSH DX MOV DX, SER0_STAT IN AX, DX XOR AH, AH AND AX, 0040H ;Verifica el bit RI JZ SER0_RECEV_TERMINA INC AH MOV DX, SER0_REC IN AL, DX ;Regresa en byte transmitido. SER0_RECEV_TERMINA: POP DX RET ENDP ;************************************************** ******************* ;INTERRUPCION POR TRANSMISION INTERRUPT_TX_SERIAL0 PROC ;Interrupcion por transm ision (NO HACE NADA) PUSH AX PUSH DX MOV DX, SER0_STAT IN AX, DX ;Para evitar los errores MOV DX, INT_END_INT ;Fin de interrupcion no espec . MOV AX, 8000H OUT DX, AX POP DX POP AX IRET ENDP ;************************************************** ******************* ;INTERRUPCION POR RECEPCION INTERRUPT_RX_SERIAL0 PROC ;Interrupcion por recepc ion PUSH AX PUSH BX PUSH CX PUSH DX PUSH DS MOV DX, SER0_STAT IN AX, DX ;Primero se obtiene un posible error AND AX, 0314H JNZ INTERRUPT_RX_SERIAL0_TERMINA ;Hay un error, salta el caracter.

Page 241: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

236

MOV DX, SER0_REC IN AL, DX ;Obtiene el byte transmitido. MOV CL, AL CMP CL, CMSOK ;Comando cmsOK JNE INTERRUPT_RX_SERIAL0_NOCMSOK CALL PROC_CMSOK JMP INTERRUPT_RX_SERIAL0_TERMINA INTERRUPT_RX_SERIAL0_NOCMSOK: CMP CL, CMSRESET ;Comando cmsReset JNE INTERRUPT_RX_SERIAL0_NOCMSRESET CALL PROC_CMSRESET JMP INTERRUPT_RX_SERIAL0_TERMINA INTERRUPT_RX_SERIAL0_NOCMSRESET: CMP CL, CMSDETENER ;Comando cmsDetener JNE INTERRUPT_RX_SERIAL0_NOCMSDETENER CALL PROC_CMSDETENER JMP INTERRUPT_RX_SERIAL0_TERMINA INTERRUPT_RX_SERIAL0_NOCMSDETENER: INTERRUPT_RX_SERIAL0_CONTINUA: XOR AX, AX MOV DS, AX MOV BX, COMUNICATION_AREA MOV AX, [BX] ;AH INICIO, AL FIN DE COLA MOV BX, AX ;BH INICIO, BL FIN DE COLA XOR AH, AH INC AL ;Incrementa el fin de cola MOV DL, SERBUFFER_TAM DIV DL ;En AH esta el modulo y el nuevo fin de c ola. CMP AH, BH ;Compara si fin e inicio son iguales. JE INTERRUPT_RX_SERIAL0_TERMINA ;No puede agrega r se pierde el caracter. XOR DX, DX MOV DL, BL MOV BX, COM_AREA_END_TAIL MOV [BX], AH ;Guarda el fin de cola. INC BX INC BX ;Estamos en donde se almacena ADD BX, DX MOV [BX], CL ;Se guarda el caracter transmitido. INTERRUPT_RX_SERIAL0_TERMINA: MOV DX, INT_END_INT ;Fin de interrupcion no espec . MOV AX, 8000H OUT DX, AL POP DS POP DX POP CX POP BX POP AX IRET ENDP ;************************************************** ******************* ;REVISA SI LA COLA ESTA VACIA. ;RETORNA: ; AL = 1 cola vacia, 0 si no. SER0_COLAVACIA PROC PUSH BX PUSH CX PUSH DS MOV CH, AH ;Para guardar el regustro AH. XOR BX, BX MOV DS, BX MOV BX, COMUNICATION_AREA MOV AX, [BX] MOV BX, AX XOR AX, AX CMP BH, BL JNE SER0_COLAVACIA_TERMINA INC AL SER0_COLAVACIA_TERMINA: MOV AH, CH

Page 242: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

237

POP DS POP CX POP BX RET ENDP ;************************************************** ******************* ;OBTIENE EL DATO DE LA COLA. ;RETORNA: ; AH = 1 Si se obtuvo el dato, 0 en otro caso. ; AL = Dato. SER0_OBTENDATO PROC PUSH BX PUSH CX PUSH DS CALL SER0_COLAVACIA CMP AL, 01H ;Para saber si la cola esta vacia JE SER0_OBTENDATO_NODATO ;Cola vacia. XOR AX, AX MOV DS, AX MOV BX, COM_AREA_INI_TAIL ;Obtiene el inicio MOV AL, [BX] ;El inicio. INC AX ADD BX, AX ;Posicion del dato MOV CL, SERBUFFER_TAM DIV CL MOV CL, AH ;La nueva posicion XOR AX, AX INC AH MOV AL, [BX] ;Obtiene el dato MOV BX, COM_AREA_INI_TAIL ;Obtiene el inicio MOV [BX], CL ;Guarda la posicion JMP SER0_OBTENDATO_TERMINA SER0_OBTENDATO_NODATO: XOR AX, AX SER0_OBTENDATO_TERMINA: POP DS POP CX POP BX RET ENDP ;************************************************** ******************* ;ACTIVA/DESACTIVA LA INTERRUPCION DEL PUERTO SERIAL ;PARAMETROS: ; AL = 1 ACTIVA, 0 DESACTIVA. SER0_INTERRUPCIONEDO PROC PUSH AX PUSH BX PUSH DX CLI MOV BX, AX ;Guarda el valor MOV DX, SER0_CTRL IN AX, DX AND AX, 0FFDFH OUT DX, AX ;Elimina en REN CALL SER0_LIMPIAPUERTO;Saca la basura MOV DX, INT_SERIAL ;PCB de la interrupcion MOV AX, 0003H ;Fija prioridad 3 CMP BL, 01H JE SER0_INTERRUPCIONEDO_ACTIVA ;La activa OR AL, 08H ;Desactiva SER0_INTERRUPCIONEDO_ACTIVA: OUT DX, AX ;Habilita/Inhabilita la interrupcion. MOV DX, SER0_CTRL IN AX, DX OR AX, 0020H OUT DX, AX ;Activa el REN MOV DX, SER0_STAT

Page 243: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

238

IN AX, DX ;Borra un anterior TI o RI MOV DX, INT_INT_REQ ;Elimina la solicitud de int errupcion. IN AX, DX AND AX, SER_DEL_REQ OUT DX, AX ;Quita solicitud de interrupcion MOV DX, INT_STATUS IN AX, DX AND AX, 0FFE7H OUT DX, AX ;Quita pendiente MOV DX, INT_INSERV IN AX, DX AND AX, 0FFFBH OUT DX, AX ;Elimina en servicio STI POP DX POP BX POP AX RET ENDP ;************************************************** ******************* ;LIMPIA LA COLA SER0_LIMPIACOLA PROC PUSH BX PUSH CX PUSH DS MOV BX, COMUNICATION_AREA XOR CX, CX MOV [BX], CX POP DS POP CX POP BX RET ENDP ;************************************************** ******************* ;LIMPIA EL PUERTO SER0_LIMPIAPUERTO PROC PUSH AX PUSH DX SER0_LIMPIAPUERTO_CONTINUA: MOV DX, SER0_STAT IN AL, DX XOR AH, AH AND AX, 0040H ;Verifica el bit RI JZ SER0_LIMPIAPUERTO_TERMINA INC AH MOV DX, SER0_REC IN AL, DX ;Regresa en byte transmitido. JMP SER0_LIMPIAPUERTO_CONTINUA SER0_LIMPIAPUERTO_TERMINA: POP DX POP AX RET ENDP ;************************************************** ******************* ;INICIA LA COMUNICACION CON EL DEPURADOR ;PARAMETROS: ; BX = VELOCIDAD DEL PUERTO (USAR CONSTANTES) INICIA_COM_DEPURADOR PROC PUSH BX PUSH CX MOV CX, UAMI188_D188_COM ;Modo 3, paridad par, la velocidad se fijo en BX CALL SER0_INICIA POP CX POP BX RET ENDP ;************************************************** *******************

Page 244: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

239

;ENVIA UN DATO, PERO SALE HASTA QUE SE HA ENVIADO ;PARAMETROS ;PARAMETROS: ; BL = BYTE A ENVIAR. SER0_SENDE PROC PUSH AX PUSH BX PUSH CX PUSH DX PUSHF CLI SER0_SENDE_NOENVIO: CALL SER0_SEND ;Se envia mensaje CMP BH, 01H JNE SER0_SENDE_NOENVIO SER0_SENDE_CONTINUA: MOV DX, SER0_STAT IN AX, DX AND AX, 0008H ;Revisa bit TXE JZ SER0_SENDE_CONTINUA SER0_SENDE_TERMINA: MOV DX, INT_STATUS ;Quita la espera de INT por t ransmision. IN AX, DX AND AX, 800FH OUT DX, AX POPF POP DX POP CX POP BX POP AX RET ENDP ;************************************************** *******************

E.32 MONITOR.ASM ;ESTE ES EL QUE CONTROLA EL MONITOREO. ;SE ASUME QUE LA PILA SE HA INICIADO. ;************************************************** ********************** ;NOTAS: PROCEDIMIENTOS DEL MONITOREO ; ; ; ;************************************************** ********************** NUMB_CARGA EQU 02H ;Numero de bytes de datos a cargar NUMB_OBTENMEM EQU 06H ;Numero de bytes de datos a leer de memoria NUMB_MUEVEMEM EQU 0AH ;Numero de bytes de datos a mover memoria NUMB_CARGAREG EQU 03H ;Numero de bytes de carga d e registros NUMB_CARGAMEM EQU 06H ;Numero de bytes de datos a guardar en memoria NUMB_FIJAHORA EQU 04H ;Numero de bytes de datos p ara cambiar la hora ;************************************************** ********************** ;ESTA ES LA FUNCION QUE SE ENCARGA DE PROCESAR LAS PETICIONES ;PARAMETROS: ; AL = COMANDO MONITOREO PROC PUSH AX PUSH BX PUSH DS CMP AL, CMSCARGA JNE NO_CMSCARGA CALL PROC_CMSCARGA ;Carga un programa del depura dor al UAMI188EB JMP MONITOREO_TERMINA NO_CMSCARGA: CMP AL, CMSEJECUTAR JNE NO_CMSEJECUTAR

Page 245: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

240

CALL PROC_CMSEJECUTAR ;Ejecuta el programa carga do JMP MONITOREO_TERMINA NO_CMSEJECUTAR: CMP AL, CMSPASO JNE NO_CMSPASO INT 64H ;Para ejecucion paso a paso. JMP MONITOREO_TERMINA NO_CMSPASO: CMP AL, CMSOBTENREG JNE NO_CMSOBTENREG CALL PROC_CMSOBTENREG ;Envia el valor de los reg istros. JMP MONITOREO_TERMINA NO_CMSOBTENREG: CMP AL, CMSDETENER JNE NO_CMSDETENER CALL PROC_CMSDETENER ;Detiene un programa. JMP MONITOREO_TERMINA NO_CMSDETENER: CMP AL, CMSOBTENRET JNE NO_CMSOBTENRET CALL PROC_CMSOBTENRET ;Envia el valor de retorno del programa. JMP MONITOREO_TERMINA NO_CMSOBTENRET: CMP AL, CMSOBTENERR JNE NO_CMSOBTENERR CALL PROC_CMSOBTENERR ;Envia el error generado p or el programa. JMP MONITOREO_TERMINA NO_CMSOBTENERR: CMP AL, CMSOBTENMEM JNE NO_CMSOBTENMEM CALL PROC_CMSOBTENMEM ;Envia un bloque de memori a. JMP MONITOREO_TERMINA NO_CMSOBTENMEM: CMP AL, CMSMUEVEMEM JNE NO_CMSMUEVEMEM CALL PROC_CMSMUEVEMEM ;Mueve un bloque de memori a. JMP MONITOREO_TERMINA NO_CMSMUEVEMEM: CMP AL, CMSCARGAREG JNE NO_CMSCARGAREG CALL PROC_CMSCARGAREG ;Carga un registro. JMP MONITOREO_TERMINA NO_CMSCARGAREG: CMP AL, CMSOBTENPRG JNE NO_CMSOBTENPRG CALL PROC_CMSOBTENPRG ;Envia un programa cargado en la UAMI188 XOR BX, BX MOV DS, BX MOV BX, BIOS_ESTADO MOV BYTE PTR [BX], BIOSEDO_STP;Se cambia el estad o. JMP MONITOREO_TERMINA NO_CMSOBTENPRG: CMP AL, CMSCARGAMEM JNE NO_CMSCARGAMEM CALL PROC_CMSCARGAMEM ;Recibe datos del depurado r a memoria. JMP MONITOREO_TERMINA NO_CMSCARGAMEM: CMP AL, CMSACERCADE JNE NO_CMSACERCADE CALL PROC_CMSACERCADE ;Mensaje Acerca de ... JMP MONITOREO_TERMINA NO_CMSACERCADE: CMP AL, CMSFIJAHORA ;Fija la hora que envia D188 .EXE JNE NO_CMSFIJAHORA CALL PROC_CMSFIJAHORA JMP MONITOREO_TERMINA NO_CMSFIJAHORA: MONITOREO_TERMINA: POP DS POP BX

Page 246: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

241

POP AX RET ENDP ;************************************************** ********************** PROC_CMSOK PROC ;Procesa el comando CMSOK PUSH AX PUSH BX PUSH DS MOV BL, CMSOK CALL SER0_SENDE ;Se envia mensaje de cmsOK XOR AX, AX MOV DS, AX MOV BX, BIOS_ESTADO MOV AL, [BX] MOV BL, AL CALL SER0_SENDE ;Se envia el estado del sistema POP DS POP BX POP AX RET ENDP ;************************************************** ********************** PROC_CMSRESET PROC ;Procesa el comando CMSRESET PUSH AX PUSH BX PUSH DS MOV BL, CMSOK CALL SER0_SENDE ;Se envia el mensaje de cmsOK MOV BL, BIOSEDO_OK CALL SER0_SENDE ;Se envia el estado de OK INT 19H ;Inicia el RESET RET ;El RET ya no importa. ENDP ;************************************************** ********************** PROC_CMSCARGA PROC ;Procesa el comando CMSCARGA. POP AX POP AX POP AX ;Para sacar seg, off y banderas de la pila XOR AX, AX CALL SER0_INTERRUPCIONEDO ;Desactiva la interrupc ion del serial XOR DX, DX MOV AH, 02H INT 10H ;Coloca el cursor en primer renglon MOV AX, CS MOV DS, AX MOV AH, 03H MOV SI, MSG_CARGA INT 60H ;Imprime mensaje de carga MOV BL, CMSOK CALL SER0_SENDE ;Se envia el mensaje de cmsO K XOR AX, AX MOV DS, AX MOV CX, NUMB_CARGA ;A esperar el tama¤o de los d atos PROC_CMSCARGA_E1: SHR DX, 08H ;Al siguiente dato MOV BX, ESPERA_SERIAL XOR AX, AX MOV AL, [BX] MOV BX, AX MOV AH, 20H INT 1AH ;Fija el tiempo de espera. PROC_CMSCARGA_ED1: CALL SER0_RECEV CMP AH, 01H ;Se recivio DATO JE PROC_CMSCARGA_R1 MOV AH, 21H INT 1AH CMP AL, 01H JNE PROC_CMSCARGA_ED1 ;Se cumplio el tiempo y sa le. JMP PROC_CMSCARGA_TERMINA ;Sale sin hacer nada. PROC_CMSCARGA_R1:

Page 247: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

242

MOV DH, AL LOOP PROC_CMSCARGA_E1 MOV BL, CMSOK CALL SER0_SENDE ;Se envia el mensaje de cmsOK MOV CX, DX ;Los bytes esperados MOV BX, PROGRAMA_SEG ;Segmento donde estara el p rograma MOV ES, BX MOV SI, PROGRAMA_OFF ;El Offset PROC_CMSCARGA_E2: MOV BX, ESPERA_SERIAL XOR AX, AX MOV AL, [BX] MOV BX, AX MOV AH, 20H INT 1AH ;Fija el tiempo de espera. PROC_CMSCARGA_ED2: CALL SER0_RECEV CMP AH, 01H ;Se recivio DATO JE PROC_CMSCARGA_R2 MOV AH, 21H INT 1AH CMP AL, 01H JNE PROC_CMSCARGA_ED2 ;Se cumplio el tiempo y sa le. JMP PROC_CMSCARGA_TERMINA ;Sale sin hacer nada. PROC_CMSCARGA_R2: MOV ES:[SI], AL NOT AL MOV BL, AL CLI CALL SER0_SENDE ;Para comprobacion. STI INC SI LOOP PROC_CMSCARGA_E2 MOV BX, BIOS_ESTADO MOV BYTE PTR [BX], BIOSEDO_STP;Cambia el estado PROC_CMSCARGA_TERMINA: CALL SER0_LIMPIAPUERTO XOR AX, AX MOV SS, AX MOV DS, AX MOV BX, PILA_MONITOR MOV SP, [BX] CALL PREPARA_MONITOR XOR AX, AX MOV DS, AX PUSH AX ;Banderas MOV BX, MONITOR_SEG PUSH [BX] ;Segmento MOV BX, MONITOR_OFF PUSH [BX] ;Offset MOV AL, 01H CALL SER0_INTERRUPCIONEDO ;Activa la interrupcion del serial MOV AX, CS MOV DS, AX MOV ES, AX IRET ENDP ;************************************************** ********************** PROC_CMSEJECUTAR PROC ;Procesa el comando CMSEJEC UTAR CLI ;Quitamos la interrupciones MOV BL, CMSOK CALL SER0_SENDE ;Se envia el mensaje de cmsOK XOR AX, AX MOV DS, AX MOV BX, BIOS_ESTADO MOV BYTE PTR [BX], BIOSEDO_RUN MOV BX, RETURN_END MOV BYTE PTR [BX], INIT_NULL;Coloca en 0 el codig o de retorno. CALL CARGA_BUFFER2REG ;Carga los registros del b uffer MOV BX, REGISTRO_SS MOV AX, [BX]

Page 248: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

243

MOV SS, AX MOV BX, REGISTRO_SP MOV SP, [BX] MOV BX, REGISTRO_FLAG MOV AX, [BX] OR AX, BIT_INTERRUP ;Activa las interrupcio nes AND AX, NBIT_TRAMPA ;Quita el bit de trampa PUSH AX MOV BX, REGISTRO_CS PUSH [BX] MOV BX, REGISTRO_IP PUSH [BX] MOV BX, REGISTRO_DS PUSH [BX] MOV BX, REGISTRO_BX MOV BX, [BX] POP DS IRET ENDP ;************************************************** ********************** INTERRUPT_INT64H PROC ;Procesa el comando CMSPASO MOV BL, CMSOK CALL SER0_SENDE ;Se envia el mensaje de cmsOK XOR AX, AX MOV DS, AX MOV BX, BIOS_ESTADO MOV BYTE PTR [BX], BIOSEDO_DBG MOV BX, RETURN_END MOV BYTE PTR [BX], INIT_NULL;Coloca en 0 el codig o de retorno. CALL CARGA_BUFFER2REG ;Carga los registros del b uffer MOV BX, REGISTRO_SS MOV AX, [BX] MOV SS, AX MOV BX, REGISTRO_SP MOV SP, [BX] MOV BX, REGISTRO_FLAG MOV AX, [BX] OR AX, BIT_TRAMPA ;Activa el bit de trampa PUSH AX MOV BX, REGISTRO_CS PUSH [BX] MOV BX, REGISTRO_IP PUSH [BX] MOV BX, REGISTRO_DS PUSH [BX] MOV BX, REGISTRO_AX MOV AX, [BX] MOV BX, REGISTRO_BX MOV BX, [BX] POP DS IRET ENDP ;************************************************** ********************** ;CARGA DEL BUFFER A LOS REGISTROS (NO CARGA AX, BX, CS, DS, SS, SP, IP Y FLAG) CARGA_BUFFER2REG PROC PUSH AX PUSH BX PUSH DS XOR AX, AX MOV DS, AX MOV BX, REGISTRO_CX MOV CX, [BX] MOV BX, REGISTRO_DX MOV DX, [BX] MOV BX, REGISTRO_DI MOV DI, [BX] MOV BX, REGISTRO_SI MOV SI, [BX] MOV BX, REGISTRO_BP MOV BP, [BX] MOV BX, REGISTRO_ES

Page 249: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

244

MOV AX, [BX] MOV ES, AX POP DS POP BX POP AX RET ENDP ;************************************************** ********************** PROC_CMSOBTENREG PROC ;Procesa el comando cmsObten Reg PUSH AX PUSH BX PUSH CX PUSH DX PUSH DS MOV BL, CMSOK CALL SER0_SENDE ;Se envia mensaje de cmsOK XOR AX, AX MOV DS, AX MOV CX, DBGREG_NUMREG MOV BX, REGISTRO_AX CMSOBTENREG_LOOP: MOV AL, [BX] PUSH BX MOV BL, AL CALL SER0_SENDE ;Se envia parte baja del registr o. POP BX INC BX MOV AL, [BX] PUSH BX MOV BL, AL CALL SER0_SENDE ;Se envia parte alta del registr o. POP BX INC BX LOOP CMSOBTENREG_LOOP POP DS POP DX POP CX POP BX POP AX RET ENDP ;************************************************** ********************** PROC_CMSDETENER PROC ;Procesa el comando cmsDetene r XOR AX, AX MOV DS, AX CALL SER0_INTERRUPCIONEDO ;Desactiva la interrupc ion del serial MOV BL, CMSOK CALL SER0_SENDE ;Se envia mensaje de cmsOK MOV BX, BIOS_ESTADO MOV BYTE PTR [BX], BIOSEDO_STP XOR AX, AX MOV SS, AX MOV DS, AX MOV BX, PILA_MONITOR MOV SP, [BX] CALL PREPARA_MONITOR XOR AX, AX MOV DS, AX PUSH AX ;Banderas MOV BX, MONITOR_SEG PUSH [BX] ;Segmento MOV BX, MONITOR_OFF PUSH [BX] ;Offset MOV AX, CS MOV DS, AX MOV ES, AX MOV AL, 01H ;Activa la interrupcion del serial CALL SER0_INTERRUPCIONEDO ;Activa la interrupcion del serial MOV BL, CMSDETENER CALL SER0_SENDE ;Se envia el mensaje de cmsEnd IRET

Page 250: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

245

ENDP ;************************************************** ********************** PROC_CMSOBTENRET PROC ;Procesa el comando cmsObten Ret PUSH BX PUSH DS XOR BX, BX MOV DS, BX MOV BX, RETURN_END MOV BL, [BX] CALL SER0_SENDE ;Envia el byte de retorno. POP DS POP BX RET ENDP ;************************************************** ********************** PROC_CMSOBTENERR PROC ;Procesa el comando cmsObten Err PUSH BX PUSH DS XOR BX, BX MOV DS, BX MOV BX, RETURN_ERR MOV BL, [BX] CALL SER0_SENDE ;Envia el byte de retorno. POP DS POP BX RET ENDP ;************************************************** ********************** PROC_CMSOBTENPRG PROC ;Procesa comando cmsObtenPrg , son el mismo codigo PROC_CMSOBTENMEM PROC ;Procesa comando cmsObtenMem PUSH AX PUSH BX PUSH CX PUSH DX PUSH SI PUSH DS XOR AX, AX MOV DS, AX CALL SER0_INTERRUPCIONEDO ;Desactiva la interrupc ion del serial MOV CX, NUMB_OBTENMEM ;Se van a leer NUMB_OBTENM EM MOV SI, MEMORIA_MONITOR ;Memoria destinada al mon itor MOV BL, CMSOK CALL SER0_SENDE ;Se envia mensaje de cmsOK PROC_CMSOBTENMEM_DATOS: ;Obtenemos los datos para enviar la memoria; se necesitan 6 bytes. MOV BX, ESPERA_SERIAL XOR AX, AX MOV AL, [BX] MOV BX, AX MOV AH, 20H INT 1AH ;Fija el tiempo de espera. PROC_CMSOBTENMEM_ED1: CALL SER0_RECEV CMP AH, 01H ;Se recibio DATO JE PROC_CMSOBTENMEM_R1 MOV AH, 21H INT 1AH CMP AL, 01H JNE PROC_CMSOBTENMEM_ED1 ;Se cumplio el tiempo y sale. JMP PROC_CMSOBTENMEM_TERMINA ;Sale sin hacer nada . PROC_CMSOBTENMEM_R1: MOV [SI], AL INC SI LOOP PROC_CMSOBTENMEM_DATOS ;Ya se cargaron los datos. MOV SI, MEMORIA_MONITOR ;Se van a enviar los dato s. MOV AX, [SI] ;Segmento INC SI INC SI MOV BX, [SI] ;Offset INC SI INC SI

Page 251: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

246

MOV CX, [SI] ;Numero de bytes MOV DS, AX MOV SI, BX PROC_CMSOBTENMEM_ENVIA: MOV BL, [SI] CALL SER0_SENDE ;Envia el byte. INC SI LOOP PROC_CMSOBTENMEM_ENVIA PROC_CMSOBTENMEM_TERMINA: MOV AL, 01H ;Activa la interrupcion del serial CALL SER0_INTERRUPCIONEDO ;Activa la interrupcion del serial POP DS POP SI POP DX POP CX POP BX POP AX RET ENDP ;************************************************** ********************** PROC_CMSMUEVEMEM PROC ;Procesa comando cmsMueveMem PUSH AX PUSH BX PUSH CX PUSH DX PUSH DI PUSH SI PUSH DS XOR AX, AX MOV DS, AX CALL SER0_INTERRUPCIONEDO ;Desactiva la interrupc ion del serial MOV CX, NUMB_MUEVEMEM ;Se van a leer NUMB_MUEVEM EM MOV SI, MEMORIA_MONITOR ;Memoria destinada al mon itor MOV BL, CMSOK CALL SER0_SENDE ;Se envia mensaje de cmsOK PROC_CMSMUEVEMEM_DATOS: ;Obtenemos los datos para enviar la memoria; se necesitan 6 bytes. MOV BX, ESPERA_SERIAL XOR AX, AX MOV AL, [BX] MOV BX, AX MOV AH, 20H INT 1AH ;Fija el tiempo de espera. PROC_CMSMUEVEMEM_ED1: CALL SER0_RECEV CMP AH, 01H ;Se recivio DATO JE PROC_CMSMUEVEMEM_R1 MOV AH, 21H INT 1AH CMP AL, 01H JNE PROC_CMSMUEVEMEM_ED1 ;Se cumplio el tiempo y sale. JMP PROC_CMSMUEVEMEM_TERMINA ;Sale sin hacer nada . PROC_CMSMUEVEMEM_R1: MOV [SI], AL INC SI LOOP PROC_CMSMUEVEMEM_DATOS ;Ya se cargaron los datos. MOV SI, MEMORIA_MONITOR ;Se van a enviar los dato s. MOV AX, [SI] ;Segmento final INC SI INC SI MOV BX, [SI] ;Offset final INC SI INC SI MOV ES, AX MOV DI, BX MOV AX, [SI] ;Segmento inicial INC SI INC SI MOV BX, [SI] ;Offset inicial INC SI

Page 252: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

247

INC SI MOV CX, [SI] ;Numero de bytes MOV DS, AX MOV SI, BX REPE MOVSB PROC_CMSMUEVEMEM_TERMINA: MOV AL, 01H ;Activa la interrupcion del serial CALL SER0_INTERRUPCIONEDO ;Activa la interrupcion del serial POP DS POP SI POP DI POP DX POP CX POP BX POP AX RET ENDP ;************************************************** ********************** PROC_CMSCARGAREG PROC ;Procesa comando cmsCargaReg PUSH AX PUSH BX PUSH CX PUSH SI PUSH DS XOR AX, AX MOV DS, AX CALL SER0_INTERRUPCIONEDO ;Desactiva la interrupc ion del serial MOV CX, NUMB_CARGAREG ;Se van a leer NUMB_CARGAR EG MOV SI, MEMORIA_MONITOR ;Memoria destinada al mon itor MOV BL, CMSOK CALL SER0_SENDE ;Se envia mensaje de cmsOK PROC_CMSCARGAREG_DATOS: ;Obtenemos los datos para enviar la memoria; se necesitan 6 bytes. MOV BX, ESPERA_SERIAL XOR AX, AX MOV AL, [BX] MOV BX, AX MOV AH, 20H INT 1AH ;Fija el tiempo de espera. PROC_CMSCARGAREG_ED1: CALL SER0_RECEV CMP AH, 01H ;Se recivio DATO JE PROC_CMSCARGAREG_R1 MOV AH, 21H INT 1AH CMP AL, 01H JNE PROC_CMSCARGAREG_ED1 ;Se cumplio el tiempo y sale. JMP PROC_CMSCARGAREG_TERMINA ;Sale sin hacer nada . PROC_CMSCARGAREG_R1: MOV [SI], AL INC SI LOOP PROC_CMSCARGAREG_DATOS ;Ya se cargaron los datos. MOV SI, MEMORIA_MONITOR MOV AL, [SI] ;Numero de registro a modificar INC SI MOV BX, [SI] ;Valor MOV CL, 02H MUL CL MOV CX, BX MOV BX, REGISTRO_AX ADD BX, AX ;Calcula la posicion. MOV [BX], CX ;Actualiza el registro. PROC_CMSCARGAREG_TERMINA: MOV AL, 01H ;Activa la interrupcion del serial CALL SER0_INTERRUPCIONEDO ;Activa la interrupcion del serial POP DS POP SI POP CX POP BX POP AX RET

Page 253: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

248

ENDP ;************************************************** ********************** PROC_CMSCARGAMEM PROC ;Procesa comando cmsCargaMem PUSH AX PUSH BX PUSH CX PUSH DX PUSH SI PUSH DS PUSH ES XOR AX, AX CALL SER0_INTERRUPCIONEDO ;Desactiva la interrupc ion del serial MOV BL, CMSOK CALL SER0_SENDE ;Se envia el mensaje de cmsOK XOR AX, AX MOV DS, AX MOV CX, NUMB_CARGAMEM ;A esperar el tama¤o de lo s datos MOV SI, MEMORIA_MONITOR PROC_CMSCARGAMEM_E1: MOV BX, ESPERA_SERIAL XOR AX, AX MOV AL, [BX] MOV BX, AX MOV AH, 20H INT 1AH ;Fija el tiempo de espera. PROC_CMSCARGAMEM_ED1: CALL SER0_RECEV CMP AH, 01H ;Se recivio DATO JE PROC_CMSCARGAMEM_R1 MOV AH, 21H INT 1AH CMP AL, 01H JNE PROC_CMSCARGAMEM_ED1 ;Se cumplio el tiempo y sale. JMP PROC_CMSCARGAMEM_TERMINA ;Sale sin hacer nada . PROC_CMSCARGAMEM_R1: MOV [SI], AL INC SI LOOP PROC_CMSCARGAMEM_E1 MOV BX, MEMORIA_MONITOR MOV ES, [BX] ;Coloca el segmento INC BX INC BX MOV SI, [BX] ;Coloca el offset INC BX INC BX MOV CX, [BX] ;EL numero de bytes. PROC_CMSCARGAMEM_E2: MOV BX, ESPERA_SERIAL XOR AX, AX MOV AL, [BX] MOV BX, AX MOV AH, 20H INT 1AH ;Fija el tiempo de espera. PROC_CMSCARGAMEM_ED2: CALL SER0_RECEV CMP AH, 01H ;Se recivio DATO JE PROC_CMSCARGAMEM_R2 MOV AH, 21H INT 1AH CMP AL, 01H JNE PROC_CMSCARGAMEM_ED2 ;Se cumplio el tiempo y sale. JMP PROC_CMSCARGAMEM_TERMINA ;Sale sin hacer nada . PROC_CMSCARGAMEM_R2: MOV ES:[SI], AL INC SI LOOP PROC_CMSCARGAMEM_E2 PROC_CMSCARGAMEM_TERMINA: MOV AL, 01H CALL SER0_INTERRUPCIONEDO ;Activa la interrupcion del serial POP ES

Page 254: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

249

POP DS POP SI POP DX POP CX POP BX POP AX RET ENDP ;************************************************** ********************** PROC_CMSACERCADE PROC ;Procesa comando cmsAcercaDe PUSH AX PUSH BX PUSH CX PUSH DX PUSH SI PUSH DS XOR AL, AL CALL SER0_INTERRUPCIONEDO ;Desactiva la interrupc ion del serial MOV AH, 0FH INT 10H ;El numero de columnas esta en AH PUSH CS POP DS MOV SI, MSG_ACERCADE MOV BX, SI MOV DL, AH XOR DH, DH PROC_CMSACERCADE_SIGUIENTE: MOV CX, DX MOV AH, 02H XOR DX, DX INT 10H ;Colocamos el cursor en primera columna MOV DX, CX PROC_CMSACERCADE_SIGCHAR: LODSB AND AL, AL JZ PROC_CMSACERCADE_TERMINA CALL INT10H_0EH LOOP PROC_CMSACERCADE_SIGCHAR MOV CX, 08FFFH PROC_CMSACERCADE_ESPERA: LOOP PROC_CMSACERCADE_ESPERA ;Una pausa INC BX MOV SI, BX JMP PROC_CMSACERCADE_SIGUIENTE PROC_CMSACERCADE_TERMINA: MOV AL, 01H CALL SER0_INTERRUPCIONEDO ;Activa la interrupcion del serial XOR AX, AX MOV DS, AX MOV BX, DISPLAY_BIOS MOV AL, [BX] MOV AH, 00H INT 10H ;Se limpia la pantalla Pantalla 16x2 p or default MOV AX, CS MOV DS, AX ;Fijamos el registro DS. MOV SI, MSGMONITOR_01 MOV AH, 03H INT 60H POP DS POP SI POP DX POP CX POP BX POP AX RET ENDP ;************************************************** ********************** PROC_CMSFIJAHORA PROC ;Fija la hora que envia D188 .EXE PUSH AX PUSH BX PUSH CX

Page 255: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

250

PUSH DX PUSH SI PUSH DS XOR AX, AX MOV DS, AX CALL SER0_INTERRUPCIONEDO ;Desactiva la interrupc ion del serial MOV CX, NUMB_FIJAHORA ;Se van a leer NUMB_FIJAHO RA MOV SI, MEMORIA_MONITOR ;Memoria destinada al mon itor MOV BL, CMSOK CALL SER0_SENDE ;Se envia mensaje de cmsOK PROC_CMSFIJAHORA_DATOS: ;Obtenemos los datos para enviar la memoria; se necesitan 6 bytes. MOV BX, ESPERA_SERIAL XOR AX, AX MOV AL, [BX] MOV BX, AX MOV AH, 20H INT 1AH ;Fija el tiempo de espera. PROC_CMSFIJAHORA_ED1: CALL SER0_RECEV CMP AH, 01H ;Se recivio DATO JE PROC_CMSFIJAHORA_R1 MOV AH, 21H INT 1AH CMP AL, 01H JNE PROC_CMSFIJAHORA_ED1 ;Se cumplio el tiempo y sale. JMP PROC_CMSFIJAHORA_TERMINA ;Sale sin hacer nada . PROC_CMSFIJAHORA_R1: MOV [SI], AL INC SI LOOP PROC_CMSFIJAHORA_DATOS ;Ya se cargaron los datos. MOV BX, MEMORIA_MONITOR MOV CX, [BX] ;Horas/Minutos INC BX INC BX MOV DX, [BX] ;Segundos MOV AH, 03H INT 1AH ;Cambia la hora PROC_CMSFIJAHORA_TERMINA: MOV AL, 01H CALL SER0_INTERRUPCIONEDO ;Activa la interrupcion del serial POP DS POP SI POP DX POP CX POP BX POP AX RET ENDP ;************************************************** ********************** ; ESTE PROCEDIMIENTO, PREPARA LAS VARIABLES PARA QU E EL MONITOR TOME ; EL CONTROL, SE ASUME QUE DESPUES DE ESTE PROCEDIM IENTO NO IMPORTA EL ; VALOR DE LOS REGISTROS, POR LO QUE NO LOS RESPALD A. ; PREPARA_MONITOR PROC ;Coloca las variables para act ivar el Monitor XOR BX, BX MOV DS, BX MOV CX, DBGREG_NUMREG MOV BX, REGISTRO_AX XOR DX, DX PREPARA_MONITOR_LIMPIA_REGS: ;Borra el buffer de re gistros. MOV [BX], DX INC BX INC BX LOOP PREPARA_MONITOR_LIMPIA_REGS MOV BX, REGISTRO_SS MOV [BX], STAK_SEG ;Se fija el segmento de la pi la MOV BX, REGISTRO_CS MOV [BX], PROGRAMA_SEG ;Coloca el segmento MOV BX, REGISTRO_IP MOV [BX], PROGRAMA_OFF ;El offset de un programa

Page 256: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

251

MOV BX, REGISTRO_DS MOV [BX], PROGRAMA_SEG ;Coloca el segmento MOV BX, REGISTRO_ES MOV [BX], PROGRAMA_SEG ;Coloca el segmento MOV BX, REGISTRO_FLAG XOR AX, AX OR AX, BIT_INTERRUP MOV [BX], AX MOV BX, PILA_MONITOR ;Obtiene el offset de la pi la desde pila monitor. MOV DX, [BX] MOV BX, REGISTRO_SP MOV [BX], DX ;Ahora el offset de la pil a MOV BX, DISPLAY_BIOS MOV AL, [BX] MOV AH, 00H INT 10H ;Se limpia la pantalla Pantalla MOV AX, CS MOV DS, AX MOV ES, AX MOV SI, MSGMONITOR_01 ;Mensaje de Monitor... MOV AH, 03H INT 60H RET ENDP ;************************************************** ********************** DB 06CH, 031H, 04BH, 00AH, 0F0H, 031H, 04FH, 00DH, 0F2H, 030H DB 05AH, 000H, 000H, 000H, 000H, 000H, 000H, 000H, 000H, 000H DB 000H, 022H, 0E8H, 027H, 0E1H, 02CH, 079H, 0EBH, 07BH, 02BH DB 0E7H, 044H, 03DH, 0EDH, 022H, 0EBH, 055H, 0F6H, 037H, 0AEH DB 06DH, 0A0H, 034H, 03AH, 08AH, 00EH, 086H, 004H, 07FH, 0FFH DB 041H, 0C3H, 053H, 023H, 0AEH, 0BFH, 0CCH, 069H, 0FFH, 092H DB 012H, 053H, 002H, 07AH, 0FAH, 088H, 0B3H, 0C3H, 047H, 0C4H DB 020H, 0A2H, 07EH, 0FAH, 02EH, 07EH, 0C9H, 066H, 0EDH, 037H DB 00CH, 040H, 0FEH, 08FH, 00EH, 0E0H, 02BH, 026H, 0A5H, 087H DB 00DH, 02EH, 0A2H, 080H, 0E2H, 037H, 002H, 0F2H, 09DH, 0B4H DB 048H, 0EBH, 043H, 001H, 032H, 0F2H, 078H, 039H, 02EH, 0EFH DB 045 ;************************************************** ********************** MSG_CARGA: DB "Cargando... ", 00h MSG_ACERCADE: DB " " DB "BIOS/MONITOR 1.0.1 (2005) UNIVERSIDAD AUTONOM A METROPOLITANA" DB " ", 00H

E.33 ERRINT.ASM ;EN ESTE ARCHIVO ESTAN CONTENIDOS TODOS LOS PROCEDIMIENTOS ;NECESARIOS PARA EL MANEJO DE LAS INTERRUPCIONES 00 H, 04H, 05H, 06H Y 07H. ;SE ASUME QUE LA PILA YA SE HA INICIADO. ;************************************************** ********************** ;NOTAS: ; ; ; ;************************************************** ********************** ;PROCESA EL ERROR DE INTERRUPCION 00H, 04H, 05H, 06 H O 07H. ;PARAMETROS: ; CL = CODIGO DE ERROR. PROCESA_ERR_INT PROC ;Regresa el control al mon itor, division entre cero. XOR AX, AX MOV DS, AX CALL SER0_INTERRUPCIONEDO ;Desactiva la interrupc ion del serial MOV BX, RETURN_ERR MOV BYTE PTR [BX], CL ;Carga en memoria el error . MOV BX, BIOS_ESTADO

Page 257: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

252

MOV BYTE PTR [BX], BIOSEDO_STP PUSH DS ;Estas son las banderas. MOV BX, BIOS_SEG MOV AX, [BX] PUSH AX ;Luego segemento. MOV BX, BIOS_OFF MOV AX, [BX] PUSH AX ;Finalmente el Offset. MOV BL, CMSERROR CALL SER0_SENDE ;Se envia el mensaje de cmsError IRET ENDP

E.34 DEPURA.ASM ;EN ESTE ARCHIVO ESTAN CONTENIDOS TODO EL CODIGO PARA LA DEPURACION ;DEL BIOS/MONITOR ;SE ASUME QUE EL DISPLAY YA SE INICIO, NO SE USA PI LA. ;************************************************** ********************** ;NOTAS: ;************************************************** ********************** ;************************************************** ******************* ;COLOCA UN NUMERO SEGUN UN CONTADOR EN MEMORIA DADO POR ;PARAMETROS ; AX = POSICION EN MEMORIA ; DX = POSICION EN PANTALLA NUMERO_DEPURA PROC PUSH AX PUSH BX PUSH CX PUSH DX PUSH DS XOR BX, BX MOV DS, BX MOV BX, MEM_DEPURA ADD BX, AX ;Se obtiene la posicion real INC BYTE PTR [BX] ;Se incrementa PUSH DX MOV AH, 03H INT 10H POP CX ;CX esta la posicion en pantalla PUSH DX ;Guarda la posicion ORIGINAL MOV AH, 02H MOV DX, CX INT 10H MOV AL, [BX] ADD AL, 30H MOV AH, 09H INT 10H ;Coloca el conteo POP DX MOV AH, 02H INT 10H ;Coloca la posicion ORIGINAL POP DS POP DX POP CX POP BX POP AX RET ENDP

Page 258: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

253

Apéndice F. Lista de interrupciones del BIOS.

F.1 ASMMAQ.H /*ESTE ARCHIVO CONTIENE LAS CADENAS EMPLEADAS POR EL PROGRAMA*/ #include <stdio.h> #include "define.h" #ifndef __LARGE__ #error Se necesita modelo de memoria LARGE #endif /*Definicion de las estructuras*/ typedef struct NODO nodo; /*Nodo que contiene cada token de la cadena*/ typedef struct ETIQUETA label; /*Nodo que contiene definicion de etiqueta*/ typedef struct INSTRUCT inst; /*Nodo que contiene la instruccion*/ typedef struct INCLUDE include; /*Nodo que contie ne el archivo include*/ struct NODO /*NODO: almacena cada token de una instruccion*/ byte bTipo; /*Tipo de nodo*/ byte bNumTipo; /*Numero de tipo de nodo*/ dword dNumero; /*En caso de ser numero*/ byte bPos; /*Posicion en cadena original*/ nodo *psnSig; /*Nodo Siguiente*/ ; struct ETIQUETA /*ETIQUETA: almacena las consta ntes o etiquetas*/ char *pcLabel; /*El nombre de la etiqueta*/ dword dRefVal; /*Posicion de la etiqueta o val or*/ byte bTipo; /*El tipo de elemento, solo pue de ser LBL o CTE*/ byte bNumTipo; /*El numero de tipo de elemento Numero (8, 16 y 32) o (definida o no definida)*/ word wCont; /*Contador para posicion entre instrucciones*/ label *pslSig; /*Etiqueta siguiente*/ ; struct INSTRUCT /*INSTRUCT: almacena la intrucc ion para segunda pasada*/ char *pcInst; /*Instruccion*/ byte bNumCod; /*Bytes de codigo*/ word wRef; /*Referencia*/ word wLin; /*Numero de linea de codigo*/ word wCont; /*Contador para posicion entre etiquetas*/ inst *psiSig; /*Siguiente instruccion*/ ; struct INCLUDE char scFile[MAX_NFILE]; /*Nombre del archivo co n extension, sin ruta*/ word wLin; /*Identificador (numero de linea do nde se declaro)*/ include *psincSig; ; #ifdef MAIN_ASMMAQ /*Constantes globales del ensamblador*/ word WConstASM; /*Banderas del ensamblador*/ byte BProcesador; /*Tipo de procesador empleado* / char *pCInclude; /*Nombre de archivo en include* / word WContInstLBL; /*Contador de instrucciones y etiquetas*/ label *psLEtiqueta; /*Lista de etiquetas y consta ntes*/ inst *psIInstruccion; /*Lista de instrucciones*/ label *psLActual; /*Para uso de etiquetas*/

Page 259: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

254

inst *psIActual; /*Para uso de instrucciones*/ char *pCMEM; /*Memoria para procesar instruccion es*/ word WMemCont; /*Manejo de memoria para instrucc iones*/ word WTamMEM; /*Tama¤o de memoria para instrucci ones*/ char *pcLBLMEM; /*Memoria para procesar etiqueta s y constantes*/ word WLblCont; /*Manejo de memoria*/ word WTamLBL; /*Tama¤o de memoria para etiquetas y constantes*/ word *pWMensajes; /*Mensajes*/ word *pWLineas; /*Lineas del ensamblador*/ byte BNumMensajes; /*Numero de mensajes introduc idos*/ byte BNumErrores; /*Numero de errores*/ byte BNumWarnings; /*Numero de warnings*/ byte BTotalMensajes; /*Numero de mensajes permit idos*/ byte *pBCodMaq; /*Memoria a desensamblar codigo m aquina*/ word WLenCodMaq; /*Tama¤o de memoria a desensambl ar codigo maquina*/ word WLenCod; /*Tama¤o del codigo cargado en memo ria*/ include *psINCInclude; /*Para uso de archivos inc lude*/ include *psINCActual; /*Para uso de archivos incl ude*/ char sCRegistro16[][3] = /*Registros simples*/ "AX", "CX", "DX", "BX", "SP", "BP", "SI", "DI" ; char sCRegistro08[][3] = /*Registros de 8 bits*/ "AL", "CL", "DL", "BL", "AH", "CH", "DH", "BH" ; char sCSegmento[][3] = /*Registros de segmento*/ "ES", "CS", "SS", "DS", "FS", "GS" ; char sCRegistro32[][4] = "EAX", "EBX", "EDX", "EBX", "ESP", "EBP", "ESI", "EDI" ; char sCInstNoArgs[][6] = /*Instrucciones sin arg umentos*/ "AAA", "AAD", "AAM", "AAS", "CBW", "CLC", "CLD", "CLI", "CMC", "CWD", "DAA", "DAS", "HLT", "INTO", "INT3", "IRET", "LAHF", "LOCK", "NOP", "POPF", "PUSHF","RET", "RETF", "SAHF","STC", "STD", "STI", "WAIT", "XLAT", "@CS", "@DS", "@ES", "@SS", "PUSHA", "POPA", "LEAVE" ; char sCInst1Args[][7] = /*Instrucciones de un ar gumento*/ "CALL", "JMP", "JA", "JAE", "JB", "J BE", "JC", "JCXZ", "JECXZ", "JE", "JZ", "JG", "J GE", "JL", "JLE", "JNA", "JNAE", "JNB", "JNBE", "J NC", "JNE", "JNG", "JNGE", "JNL", "JNLE", "JNO", "J NP", "JNS", "JNZ", "JO", "JP", "JPE", "JPO", "J S", "JZ", "LOOP", "LOOPE", "LOOPZ", "LOOPNE","LOOPNZ", "DEC", "DIV", "IDIV", "IMUL", "INC", "I NT", "MUL", "NEG", "NOT", "POP", "PUSH" ; char sCInst2Args[][7] = /*Instrucciones de dos a rgumentos*/ "ADC", "ADD", "AND", "CMP", "IN", "LEA", "L DS", "LES", "MOV", "OR", "OUT", "RCL", "RCR", "ROL", "R OR", "SAL", "SAR", "SHL", "SHR", "SBB", "SUB", "TEST", "X CHG", "XOR", "BOUND", "ESC", "ENTER" ; char sCInstEspe[][6] = /*Instrucciones especiale s*/ "REP", "REPE", "REPZ", "REPNE", "REPNZ", "CMPSB", "CMPSW", "LODSB", "LODSW", "MOVSB", "MO VSW", "SCASB", "SCASW", "STOSB", "STOSW", "INSB", "INSW", "OUTSB", "OUTSW", "BYTE", "WORD", "PTR", "FAR" ; char sCResWord[][8] = /*Palabras reservadas*/ "DB", "DW", "ORG", "EQU", "INCLUDE", " SETREF", "DELALL", "LSTCTE", "PROC", "ENDP",

Page 260: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

255

"P8086", "P80186", "P80286", "P80386", "P8088", "P80188" ; #include "codinst.h" /*Los codigos de las instruc ciones*/ #include "ewlst.h" #else extern word WConstASM; extern label *psLEtiqueta; extern inst *psIInstruccion; extern byte BProcesador; extern word *pWMensajes; extern word *pWLineas; extern byte BNumMensajes; extern label *psLActual; extern inst *psIActual; extern char *pCMEM; extern word WMemCont; extern char *pcLBLMEM; extern word WLblCont; extern byte BNumErrores; extern byte BNumWarnings; extern word WTamMEM; extern word WTamLBL; extern char *pCInclude; extern word WContInstLBL; extern byte *pBCodMaq; extern word WLenCodMaq; extern word WLenCod; extern include *psINCInclude; extern include *psINCActual; extern byte BTotalMensajes; extern char sCRegistro16[][3]; extern char sCRegistro08[][3]; extern char sCSegmento[][3]; extern char sCRegistro32[][4]; extern char sCInstNoArgs[][6]; extern char sCInst1Args[][7]; extern char sCInst2Args[][7]; extern char sCInstEspe[][6]; extern char sCResWord[][8]; /*Decodificadores de direccionamiento*/ extern byte sBModosDir[][2]; extern byte sBModosReg_1[8]; extern byte sBModosReg_2[8]; extern byte sBModosSeg_1[6]; extern byte sBModosSeg_2[6]; extern char sCDecodDir[][6]; /*Automata*/ extern byte sBSegPref[]; /*Estos son de los codigos de instruccion*/ extern byte sBCodIntNoArgs[][4]; /*Codigos de inst rucciones sin argumentos*/ extern byte sBCodInstEspe[][3]; /*Codigos de instr ucciones especiales*/ extern byte sBDesIntUnArg[][2]; /*Descriptor de lo s codigos para instrucciones de un argumento*/ extern byte sBCodIntUnArg[][8]; /*Los codigos de i ntrucciones de un argumento*/ extern byte sBDesIntDosArg[][2]; /*Descriptor de l os codigos para instrucciones de dos argumentos*/ extern byte sBCodIntDosArg[][12]; /*Los codigos de intrucciones de dos argumentos*/ extern char sCError[][MAX_LENMSG]; /*Mensajes de error o warnings*/ #endif /**************************** ASM a MAQ ********** *********************/

Page 261: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

256

/*La funcion principal */ word wASM2MAQ (char *pcText, byte *pbCod, word *pw Ref, word wLin); /*Para generar codigo*/ int iIniciaASM (word wMEM, word wLBLCTE, word wMa xMsg); /*Inicia las variables del ensamblador*/ void vTerminaASM (); /*Libera los recursos del en samblador*/ byte bFinCompilacion (); /*Indica si ya termino d e compilar*/ void vIniciaCompilacion (); /*Inicia el ambiente para compilar*/ byte bEsSegundoPaso (); /*Indica si esta en proce so el segundo paso*/ byte bEsSETREF (); /*Indica si se define SETREF*/ char *pcEsArchivoINCLUDE (); /*Avisa de archivo a nidado*/ word wCodINoArg (byte *pbCod, byte bNumTipo); /*I nstrucciones sin argumentos*/ word wCodIEsp (nodo *psnLista, byte *pbCod); /*In strucciones especiales*/ word wCodIUnArg (nodo *psnLista, byte *pbCod, word wRef); /*Instrucciones de un argumento*/ word wCodIDosArgs (nodo *psnLista, byte *pbCod, wo rd wLin); /*Instrucciones de dos argumentos*/ word wCodResWord (nodo *psnLista, byte *pbCod, cha r *pcText, word *pwRef, word wLin); /*Palabras reservadas*/ word wCodEtiqueta (nodo *psnLista, char *pcText, w ord wRef); word wChkCOMA (nodo **psnAux); word wAnalizaArgs (nodo **psnAux, word *pwFlagDir, word *pwIdArg, dword *pdNum, byte *pbSeg, byte *pbReg); word wAnalizaIEsp (nodo **psnAux, word *wFlag); word wAnalizaModoDir (nodo **psnAux, word *pwFDir, dword *pdNum); byte bObtenRegDirFlag (byte bNumTipo); byte bObtenModoDir (word wFDir); word wChkIdArgs (word wIdArg, word *pwFlagDir, dwo rd *pdNum); word wChk2IdArgs (word *pwIdArg, word *pwFlagDir, dword *pdNum); byte bByteRM (word *pwIdArg, word *pwFlagDir, byte *pbReg, byte *pbSeg); byte bChkSalto (nodo *psnAux); byte bChkIOPort (byte bTipo, byte bNumTipo); void vBorraLBLCTE (); /*Funciones de texto*/ word wM_LenCad (word *pwLen, char *pcText); int iBuscaChar (char *pcText, int iIni, char cC); word wObtenTokens (nodo **psnRet, char *pcText, wo rd wLen); void vObtenNombreArch (char *pcFile, char *pcIn, b yte bFlag, word wLen); void vObtenNombreDir (char *pcDir, char *pcIn); char cChkStr (char *pcText1, word wLen, char *pcTe xt2, char cMay); word wAnalizaCadena (char *pcText, word wIni, word wLen, dword *pdNum); char cEsNumero (char *pcText, word wIni, word wLen ); /*Funciones de memoria*/ int iIniciaMem (word wMEM, word wLBLCTE, word wMax Msg); void vTerminaMem (void); void *pvMemoria (word wMem); void vLiberaMem (void); void *pvMemLBL (word wMem); void vLiberaMemLBL (void); /*Funciones para el manejo de errores*/ void vImprimeMensajes (); int iAddMensaje (word wMsg, word wLin); void vResetMensajes (); /*Funciones para compilar archivos*/ void vCompilaArchivo (char *pcFile); void vCompilaPantalla (); byte bObtenLineaCod (FILE *psfIn, char *pcText, wo rd *pwLin); /*Funciones de depuracion*/ void vPrintFlag (word w, byte b); void vPrintInst (); void vPrintLbl (); void vPrintCte (); /*Funciones para el manejo de etiquetas y constant es*/ void vAddRefLBL (label *pslAux, inst *psiAux, byte bAdd); void vAddRefInst (inst *psiAux, byte bAdd);

Page 262: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

257

word wAddEtiqueta (char *pcText, word wPos, word w Len, byte bTipo, byte bNumTipo, word wRefVal); label *pslBuscaEtiquetaConstante (char *pcText, wo rd wPos, word wLen); word wAddInstruccion (char *pcText, word wLen, wor d wRef, word wLin); word wCodEtiqueta (nodo *psnLista, char *pcText, w ord wRef); byte bEsInstruccion (nodo *psnAux); void vAddRefInst (inst *psiAux, byte bAdd); void vAddRefLBL (label *pslAux, inst *psiAux, byte bAdd); void vLiberaLBLCTE (); word wResuelveRef (); word wSustituyeLBLCTE (nodo *psnAux, char *pcText) ; word wAddINCLUDE (char *pcFile, word wLin); byte bCreaMAP (char *pcFile); label *pslOrdenaLBLCTE (label *pslAux); /**************************** MAQ a ASM ********** *********************/ /*La funcion principal */ word wMAQ2ASM (char *pcTxt, char *pbCod, word wPos , word wRef, word wLen); /*Para decodificar el codigo (desensamblar)*/ byte bIniciaMAQ (word wMemoriaMAQ); void vTerminaMAQ (); word wDecodINoArg (char *pcTxt, char *pbCod, word wPos, word wLen); word wDecodIEsp (char *pcTxt, char *pbCod, word wP os, word wLen); word wDecodIUnArg (char *pcTxt, byte *pbCod, word wPos, word wLen, word wRef); word wDecodIDosArg (char *pcTxt, char *pbCod, word x, word wLen); void vFijaDB (char *pcTxt, byte bCod); word wChkCodigo (byte *pbCod, byte *pbCodArgs, wor d wPos); void vAgregaNum (char *pcTxt, dword dNum, word wTi po, char cPlus); byte bObtenArgumento (byte bArg, byte bTipo); byte bObtenArgumentoSeg (byte bArg); word wAgregaArg (char *pcTxt, byte *pbCod, word wC od, word wCMP, byte bArg, byte bPTR, byte bCOMA); /*Funciones de utileria*/ dword dCargaCODIGO (char *pcFile); void vColocaCODIGO (byte *pbCod, word wPos, byte b Insert); /************** FUNCIONES COMPARTIDAS ENTRE ASM Y MAQ *****************/ /*Funciones generales entre ASM y MAQ*/ void vCargaDescriptores (void); word wNumOpcDescriptor (byte bDesc); int iObtenPosDescriptor (byte bDesc, word wPos); dword dObtenNumero (char *pcText, word wLen, byte bTipo); /****************************** MACROS *********** *********************/ #define BYTE_MOD_RM(bb) (bb&(~RM_F)) /*Para obt ener los bits RM*/ #define BYTE_REG(bb) (bb&RM_F) /*Se usa pa ra segmentos*/ /*Para el manejo de errores*/ #define NUMERO_ERR() BNumErrores /*Numero de errores cargados*/ #define NUMERO_WAR() BNumWarnings /*Numero d e warnings cargados*/ #define MSG_SINNUM(aa) (0x0100|aa) /*Mensajes sin numero*/ #define MSG_NUMINI(aa) (0x0200|aa) /*Mensaje c on numero al inicio*/ #define MSG_NUMFIN(aa) (0x0300|aa) /*Mensaje c on numero al final*/ #define MENSAJE(aa) sCError[aa] /*Regresa e l mensaje dado por aa*/ #define NUMMENSAJES() BNumMensajes /*Numero de mensajes*/ /*Para el depurador*/ #define LEN_CODMAQ() WLenCod /*Longitud de l os bytes cargados en buffer*/ #define BUFF_CODMAQ(aa) *(pBCodMaq+aa) /*Bytes del buffer*/ #define PTR_CODMAQ() pBCodMaq /*Puntero al b uffer*/ #define TAM_CODMAQ() WLenCodMaq /*Tama¤o del buffer*/ /*Para el ensamblador, manejo de memoria*/ #define TAM_COMPILA() WTamMEM /*Tama¤o de me moria para instrucciones*/ #define TAM_LBLCTE() WTamLBL /*Tama¤o de me moria para Lbl's, Cte's, etc*/ #define USE_LBLCTE() WLblCont /*Memoria para lbl's, ctes, etc. empleada*/

F.2 BIOSVARS.H //CONTIENE LAS CONSTANTES QUE SE EMPLEAN TANTO EN L A UAMI188EB COMO

Page 263: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

258

//EN EL DEPURADOR. CUALQUIER CAMBIO EN EL ARCHIVO B IOSVARS.ASM O //BIOSVARS.H DEBERA VERSE REFLEJADO EN EL OTRO ARCH IVO. //ADEMAS TAMBIEN CONTIENE CONSTANTES EMPLEADAS EN EL ARCHIVO CONST.ASM //POR LO QUE SE DEBE SEGUIR LA MISMA RECOMENDACION ANTERIOR. //CONSTANTES EN BIOSVARS.ASM #define PROGRAMA_SEG 0x0070 //Segmento donde in ician los programas. #define PROGRAMA_OFF 0x0000 //Este es el offset #define STACK_SEG 0x0000 //Segmento de la PI LA #define STACK_OFF 0x2000 //Offset de la PILA //CONSTANTES EN CONST.ASM #define BIT_TRAMPA 0x0100 //Bit de trampa. #define BIT_INTERRUP 0x0200 //Bit de interrupcion . #define NBIT_TRAMPA 0xFEFF //Para eliminar el bi t de trampa

F.3 CM_SERIA.H //ESTE ARCHIV CONTIENE LA DEFINICION DE LOS COMANDO S EMPLEADOS PARA //COMUNICACION CON EL PUERTO SERIE ENTRE LA PC Y LA UAMI188EB //SI ALGO SE CAMBIA AQUI, SE DEBE CAMBIAR EN EL BIO S DE LA UAMI188EB const cmsNada = 0x00, //Se emplea como error cmsOK = 0x01, //Mensaje de acuerdo y esta do. cmsReset = 0x02, //Reinicia la UAMI cmsCarga = 0x03, //Carga algo a la UAMI (mem oria o archivo) cmsEjecutar = 0x04, //Ejecuta el programa cmsPaso = 0x05, //Ejecuta una instruccion cmsEnd = 0x06, //Se termino de ejecutar pr ograma cmsError = 0x07, //Se detuvo el programa por un error cmsObtenMem = 0x08, //Obtiene datos de la memor ia de la UAMI188EB cmsMueveMem = 0x09, //Mueve un bloque de memori a cmsObtenReg = 0x0A, //Obtiene el valor de los r egistros cmsDetener = 0x0B, //Detiene el programa en ej ecucion cmsDesconect = 0x0C, //La UAMI envia desconecxio n cmsConectar = 0x0D, //La UAMI se conecta de nue vo cmsObtenRet = 0x0E, //Obtiene el byte de retorn o de fin de programa cmsObtenErr = 0x0F, //Obtiene el error que gene ro el programa cmsObtenPrg = 0x10, //Obtiene el programa de la UAMI188EB cmsCargaReg = 0x11, //Cambia el valor de un reg istro. cmsCargaMem = 0x12, //Carga datos a la memoria cmsAcercaDe = 0x13, //Mensaje de acerca de ... cmsResidente = 0x14, //Hay codigo residente. cmsFijaHora = 0x15, //Fija la hora en la UAMI18 8EB cmsTEST = 0xF0, //Para pruebas. //Codigos de error cerrNinguno = 0x00, //No hay error. cerrDivCero = 0x01, //Division entre cero cerrOverFlow = 0x02, //Overflow cerrArrar = 0x03, //Array bounds exception. cerrUnused = 0x04, //Unused opcode exception. cerrEscape = 0x05, //Escape opcode exception. cmsNone = 0xFF;

F.4 CODINST.H /* CONTIENE LOS CODIGOS DE LAS INSTRUCCIONES */ /*NOTA: */ /*El orden debe ser el mismo que existe en el buffe r de sus */ /*respectivas instrucciones, si algo se cambia de p osicion */ /*hay que asegurarnos de cambiar alguna otra relaci on en su */ /*posicion. Es posible la optimizacion, sobre todo en los */ /*descriptores, ya que muchos codigos son semejante s, pero */ /*se ha dejado como esta, para mantener el esquema. */ /***DECODIFICAN EL DIRECCIONAMIENTO**************** *************/

Page 264: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

259

/*Formato: Dec, Bits Mod XXX R/M*/ byte sBModosDir[][2] = 0xA0, 0x00, /*[BX+SI] */ 0x90, 0x01, /*[BX+DI] */ 0x60, 0x02, /*[BP+SI] */ 0x50, 0x03, /*[BP+DI] */ 0x20, 0x04, /*[SI] */ 0x10, 0x05, /*[DI] */ 0x04, 0x06, /*[DISP] */ 0x80, 0x07, /*[BX] */ 0xA8, 0x40, /*[BX+SI+DISP08]*/ 0x98, 0x41, /*[BX+DI+DISP08]*/ 0x68, 0x42, /*[BP+SI+DISP08]*/ 0x58, 0x43, /*[BP+DI+DISP08]*/ 0x28, 0x44, /*[SI+DISP08] */ 0x18, 0x45, /*[DI+DISP08] */ 0x48, 0x46, /*[BP+DISP08] */ 0x88, 0x47, /*[BX+DISP08] */ 0xA4, 0x80, /*[BX+SI+DISP16]*/ 0x94, 0x81, /*[BX+DI+DISP16]*/ 0x64, 0x82, /*[BP+SI+DISP16]*/ 0x54, 0x83, /*[BP+DI+DISP16]*/ 0x24, 0x84, /*[SI+DISP16] */ 0x14, 0x85, /*[DI+DISP16] */ 0x44, 0x86, /*[BP+DISP16] */ 0x84, 0x87, /*[BX+DISP16] */ ; /*Formato: Bits Mod XXX R/M*/ byte sBModosReg_1[8] = 0xC0, /*AX / AL*/ 0xC1, /*CX / CL*/ 0xC2, /*DX / DL*/ 0xC3, /*BX / BL*/ 0xC4, /*SP / AH*/ 0xC5, /*BP / CH*/ 0xC6, /*SI / DH*/ 0xC7 /*DI / BH*/ ; /*Formato: Bits XX REG XXX*/ byte sBModosReg_2[8] = 0x00, /*AX / AL*/ 0x08, /*CX / CL*/ 0x10, /*DX / DL*/ 0x18, /*BX / BL*/ 0x20, /*SP / AH*/ 0x28, /*BP / CH*/ 0x30, /*SI / DH*/ 0x38 /*DI / BH*/ ; /*Formato: Bits XX REG XXX*/ byte sBModosSeg_2[6] = 0x00, /*ES*/ 0x08, /*CS*/ 0x10, /*SS*/ 0x18, /*DS*/ 0x20, /*FS*/ 0x28 /*GS*/ ; /*Formato: Bits Mod XXX R/M*/ byte sBModosSeg_1[6] = 0xC0, /*ES*/ 0xC1, /*CS*/ 0xC2, /*SS*/ 0xC3, /*DS*/ 0xC4, /*FS*/

Page 265: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

260

0xC5 /*GS*/ ; char sCDecodDir[][6] = /*Automata*/ -1, -1, -1, 1, 2, -2, 0, 0, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1 ; /************************************************** *************/ /***CODIGOS DE PREFIJO PARA SEGMENTO (EN -20H****** *************/ byte sBSegPref[] = 0x06, /*ES*/ 0x0E, /*CS*/ 0x16, /*SS*/ 0x1E /*DS*/ ; /************************************************** *************/ /***CODIGOS PARA INSTRUCCIONES SIN ARGUMENTOS****** *************/ /*Formato es # de bytes, OpCode*/ byte sBCodIntNoArgs[][4] = /*Instrucciones s in argumentos*/ 0x01, 0x37, 0x00, COD_P86, /*AAA*/ 0x02, 0xD5, 0x0A, COD_P86, /*AAD*/ 0x02, 0xD4, 0x0A, COD_P86, /*AAM*/ 0x01, 0x3F, 0x00, COD_P86, /*AAS*/ 0x01, 0x98, 0x00, COD_P86, /*CBW*/ 0x01, 0xF8, 0x00, COD_P86, /*CLC*/ 0x01, 0xFC, 0x00, COD_P86, /*CLD*/ 0x01, 0xFA, 0x00, COD_P86, /*CLI*/ 0x01, 0xF5, 0x00, COD_P86, /*CMC*/ 0x01, 0x99, 0x00, COD_P86, /*CWD*/ 0x01, 0x27, 0x00, COD_P86, /*DAA*/ 0x01, 0x2F, 0x00, COD_P86, /*DAS*/ 0x01, 0xF4, 0x00, COD_P86, /*HLT*/ 0x01, 0xCE, 0x00, COD_P86, /*INT0*/ 0x01, 0xCC, 0x00, COD_P86, /*INT3*/ 0x01, 0xCF, 0x00, COD_P86, /*IRET*/ 0x01, 0x9F, 0x00, COD_P86, /*LAHF*/ 0x01, 0xF0, 0x00, COD_P86, /*LOCK*/ 0x01, 0x90, 0x00, COD_P86, /*NOP*/ 0x01, 0x9D, 0x00, COD_P86, /*POPF*/ 0x01, 0x9C, 0x00, COD_P86, /*PUSHF*/ 0x01, 0xC3, 0x00, COD_P86, /*RET*/ 0x01, 0xCB, 0x00, COD_P86, /*RETF*/ 0x01, 0x9E, 0x00, COD_P86, /*SAHF*/ 0x01, 0xF9, 0x00, COD_P86, /*STC*/ 0x01, 0xFD, 0x00, COD_P86, /*STD*/ 0x01, 0xFB, 0x00, COD_P86, /*STI*/ 0x01, 0x9B, 0x00, COD_P86, /*WAIT*/ 0x01, 0xD7, 0x00, COD_P86, /*XLAT*/ 0x01, 0x2E, 0x00, COD_P86, /*CS:*/ 0x01, 0x3E, 0x00, COD_P86, /*DS:*/ 0x01, 0x26, 0x00, COD_P86, /*ES:*/ 0x01, 0x36, 0x00, COD_P86, /*SS:*/ 0x01, 0x60, 0x00, COD_P186, /*PUSHA*/ 0x01, 0x61, 0x00, COD_P186, /*POPA*/ 0x01, 0xC9, 0x00, COD_P186 /*LEAVE*/ ; /************************************************** *************/ /***CODIGOS PARA INSTRUCCIONES ESPECIALES********** *************/ /*Formato es # de bytes, OpCode*/ byte sBCodInstEspe[][3] = /*Instrucciones especi ales*/ 0x01, 0xF3, COD_P86, /*REP*/ 0x01, 0xF3, COD_P86, /*REPE*/ 0x01, 0xF3, COD_P86, /*REPZ*/ 0x01, 0xF2, COD_P86, /*REPNE*/ 0x01, 0xF2, COD_P86, /*REPNZ*/ 0x01, 0xA6, COD_P86, /*CMPSB*/ 0x01, 0xA7, COD_P86, /*CMPSW*/ 0x01, 0xAC, COD_P86, /*LODSB*/ 0x01, 0xAD, COD_P86, /*LODSW*/

Page 266: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

261

0x01, 0xA4, COD_P86, /*MOVSB*/ 0x01, 0xA5, COD_P86, /*MOVSW*/ 0x01, 0xAE, COD_P86, /*SCASB*/ 0x01, 0xAF, COD_P86, /*SCASW*/ 0x01, 0xAA, COD_P86, /*STOSB*/ 0x01, 0xAB, COD_P86, /*STOSW*/ 0x01, 0x6C, COD_P186, /*INSB*/ 0x01, 0x6D, COD_P186, /*INSB*/ 0x01, 0x6E, COD_P186, /*OUTSB*/ 0x01, 0x6F, COD_P186 /*OUTSB*/ ; /************************************************** *************/ /***CODIGOS PARA INSTRUCCIONES CON UN ARGUMENTO**** *************/ /*Este es un tabla que apunta a un descriptor, para saber donde*/ /*estan los codigos. Solo hay que especificar el nu mero de */ /*opciones, ya que vCargaDescriptores se encarga de calcular */ /*la posicion. */ /*Formato: Posicion, No Opciones*/ byte sBDesIntUnArg[][2] = /*Instrucciones de un argumento*/ 0x00, 0x04, /*CALL*/ 0x04, 0x05, /*JMP*/ 0x09, 0x01, /*JA*/ 0x0A, 0x01, /*JAE*/ 0x0B, 0x01, /*JB*/ 0x0C, 0x01, /*JBE*/ 0x0D, 0x01, /*JC*/ 0x0E, 0x01, /*JCXZ*/ 0x0F, 0x01, /*JECXZ*/ 0x10, 0x01, /*JE*/ 0x11, 0x01, /*JZ*/ 0x12, 0x01, /*JG*/ 0x13, 0x01, /*JGE*/ 0x14, 0x01, /*JL*/ 0x15, 0x01, /*JLE*/ 0x16, 0x01, /*JNA*/ 0x17, 0x01, /*JNAE*/ 0x18, 0x01, /*JNB*/ 0x19, 0x01, /*JNBE*/ 0x1A, 0x01, /*JNC*/ 0x1B, 0x01, /*JNE*/ 0x1C, 0x01, /*JNG*/ 0x1D, 0x01, /*JNGE*/ 0x1E, 0x01, /*JNL*/ 0x1F, 0x01, /*JNLE*/ 0x20, 0x01, /*JNO*/ 0x21, 0x01, /*JNP*/ 0x22, 0x01, /*JNS*/ 0x23, 0x01, /*JNZ*/ 0x24, 0x01, /*JO*/ 0x25, 0x01, /*JP*/ 0x26, 0x01, /*JPE*/ 0x27, 0x01, /*JPO*/ 0x28, 0x01, /*JS*/ 0x29, 0x01, /*JZ*/ 0x2A, 0x01, /*LOOP*/ 0x2B, 0x01, /*LOOPE*/ 0x2C, 0x01, /*LOOPZ*/ 0x2D, 0x01, /*LOOPNE*/ 0x2E, 0x01, /*LOOPNZ*/ 0x2F, 0x03, /*DEC*/ 0x32, 0x02, /*DIV*/ 0x34, 0x02, /*IDIV*/ 0x36, 0x02, /*IMUL*/ 0x38, 0x03, /*INC*/ 0x3B, 0x01, /*INT*/ 0x3C, 0x02, /*MUL*/ 0x3E, 0x02, /*NEG*/ 0x40, 0x02, /*NOT*/ 0x42, 0x06, /*POP*/ 0x47, 0x03, /*PUSH*/ ;

Page 267: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

262

/*Descriptor */ /*Formato: #Bytes por Inst, (2)Inst, MOD, Dec(2), ExBy = 7 bytes por Opcion*/ /*El simbolo /# es el MOD/RM byte y se compone de los bits: */ /* Bit 7: 1 El numero se trata como direccion JXX X y CALL */ /* Para instrucciones de un argumento y para dos */ /* este bit indica que se debe tomar el numero */ /* como si este fuera de 8 bits y no de 16 bits */ /* Bit 6: 1 Se suman los registros al codigo */ /* Bit 5: R/M */ /* Bit 4: R/M */ /* Bit 3: R/M */ /* Bit 2: 1 Se usa siguiente byte para Seg, Reg o Mem */ /* Bit 1: 1 Se emplea AND como comparador de otra forma = */ /* Bit 0: 1 No existen bits R/M se construyen */ /* */ /*NOTA: Siempre la ultima opcion es cuando se acti va el bit GRAL */ /*Muchos se rep¡ten, se puede optimizar esta matri z, de hecho, */ /*sobra la ultima columna, pero fue pensada para u n actualizacion*/ /*a 32 bits */ /*Lleva un orden, primero los que son igual y lueg o AND */ /*Los AND se deben ordenar segun se pueda optimiza r, ya que hay */ /*instrucciones iguales pero con 1 o 2 bytes */ byte sBCodIntUnArg[][8] = /*Instrucciones de un argumento*/ /*Num Codigos R/M Comparadores EX BY PROC*/ /* 1 2 Baja Alta /*CALL*/ 0x01, 0xE8, 0x00, RM_D|RM_N|RM_A, LCOD_NUMH16, H COD_NUMH16, 0x00, COD_P86, 0x01, 0x9A, 0x00, RM_N, COD_PUNTERO, 0x00, 0x00, COD_P86, 0x01, 0xFF, 0x00, RM_3, LCOD_FAR, HCOD_FAR, 0x00, COD_P86, 0x01, 0xFF, 0x00, RM_2|RM_A, COD_rm16, 0x00, 0x0 0, COD_P86, /*JMP*/ 0x01, 0xEB, 0x00, RM_D|RM_N, COD_IMM08, 0x00, 0x 00, COD_P86, 0x01, 0xE9, 0x00, RM_D|RM_N, COD_IMM16, 0x00, 0x 00, COD_P86, 0x01, 0xEA, 0x00, RM_N, COD_PUNTERO, 0x00, 0x00, COD_P86, 0x01, 0xFF, 0x00, RM_5, LCOD_FAR, HCOD_FAR, 0x00, COD_P86, 0x01, 0xFF, 0x00, RM_4|RM_A, COD_rm16, 0x00, 0x0 0, COD_P86, /*JXXX*/ 0x01, 0x77, 0x00, RM_D|RM_N, COD_IMM08, 0x00, 0x 00, COD_P86, /*JA*/ 0x01, 0x73, 0x00, RM_D|RM_N, COD_IMM08, 0x00, 0x 00, COD_P86, /*JAE*/ 0x01, 0x72, 0x00, RM_D|RM_N, COD_IMM08, 0x00, 0x 00, COD_P86, /*JB*/ 0x01, 0x76, 0x00, RM_D|RM_N, COD_IMM08, 0x00, 0x 00, COD_P86, /*JBE*/ 0x01, 0x72, 0x00, RM_D|RM_N, COD_IMM08, 0x00, 0x 00, COD_P86, /*JC*/ 0x01, 0xE3, 0x00, RM_D|RM_N, COD_IMM08, 0x00, 0x 00, COD_P86, /*JCXZ*/ 0x01, 0xE3, 0x00, RM_D|RM_N, COD_IMM08, 0x00, 0x 00, COD_P86, /*JCXZ*/ 0x01, 0x74, 0x00, RM_D|RM_N, COD_IMM08, 0x00, 0x 00, COD_P86, /*JE*/ 0x01, 0x74, 0x00, RM_D|RM_N, COD_IMM08, 0x00, 0x 00, COD_P86, /*JZ*/ 0x01, 0x7F, 0x00, RM_D|RM_N, COD_IMM08, 0x00, 0x 00, COD_P86, /*JG*/ 0x01, 0x7D, 0x00, RM_D|RM_N, COD_IMM08, 0x00, 0x 00, COD_P86, /*JGE*/ 0x01, 0x7C, 0x00, RM_D|RM_N, COD_IMM08, 0x00, 0x 00, COD_P86, /*JL*/ 0x01, 0x7E, 0x00, RM_D|RM_N, COD_IMM08, 0x00, 0x 00, COD_P86, /*JLE*/ 0x01, 0x76, 0x00, RM_D|RM_N, COD_IMM08, 0x00, 0x 00, COD_P86, /*JNA*/ 0x01, 0x72, 0x00, RM_D|RM_N, COD_IMM08, 0x00, 0x 00, COD_P86, /*JNAE*/ 0x01, 0x73, 0x00, RM_D|RM_N, COD_IMM08, 0x00, 0x 00, COD_P86, /*JNB*/ 0x01, 0x77, 0x00, RM_D|RM_N, COD_IMM08, 0x00, 0x 00, COD_P86, /*JNBE*/ 0x01, 0x73, 0x00, RM_D|RM_N, COD_IMM08, 0x00, 0x 00, COD_P86, /*JNC*/ 0x01, 0x75, 0x00, RM_D|RM_N, COD_IMM08, 0x00, 0x 00, COD_P86, /*JNE*/ 0x01, 0x7E, 0x00, RM_D|RM_N, COD_IMM08, 0x00, 0x 00, COD_P86, /*JNG*/ 0x01, 0x7C, 0x00, RM_D|RM_N, COD_IMM08, 0x00, 0x 00, COD_P86, /*JNGE*/ 0x01, 0x7D, 0x00, RM_D|RM_N, COD_IMM08, 0x00, 0x 00, COD_P86, /*JNL*/ 0x01, 0x7F, 0x00, RM_D|RM_N, COD_IMM08, 0x00, 0x 00, COD_P86, /*JNLE*/ 0x01, 0x71, 0x00, RM_D|RM_N, COD_IMM08, 0x00, 0x 00, COD_P86, /*JNO*/ 0x01, 0x7B, 0x00, RM_D|RM_N, COD_IMM08, 0x00, 0x 00, COD_P86, /*JNP*/ 0x01, 0x79, 0x00, RM_D|RM_N, COD_IMM08, 0x00, 0x 00, COD_P86, /*JNS*/ 0x01, 0x75, 0x00, RM_D|RM_N, COD_IMM08, 0x00, 0x 00, COD_P86, /*JNZ*/ 0x01, 0x70, 0x00, RM_D|RM_N, COD_IMM08, 0x00, 0x 00, COD_P86, /*JO*/ 0x01, 0x7A, 0x00, RM_D|RM_N, COD_IMM08, 0x00, 0x 00, COD_P86, /*JP*/ 0x01, 0x7A, 0x00, RM_D|RM_N, COD_IMM08, 0x00, 0x 00, COD_P86, /*JPE*/ 0x01, 0x7B, 0x00, RM_D|RM_N, COD_IMM08, 0x00, 0x 00, COD_P86, /*JPO*/ 0x01, 0x78, 0x00, RM_D|RM_N, COD_IMM08, 0x00, 0x 00, COD_P86, /*JS*/ 0x01, 0x74, 0x00, RM_D|RM_N, COD_IMM08, 0x00, 0x 00, COD_P86, /*JZ*/

Page 268: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

263

/*LOOPXX*/ 0x01, 0xE2, 0x00, RM_D|RM_N, COD_IMM08, 0x00, 0x 00, COD_P86, /*LOOP*/ 0x01, 0xE1, 0x00, RM_D|RM_N, COD_IMM08, 0x00, 0x 00, COD_P86, /*LOOPE*/ 0x01, 0xE1, 0x00, RM_D|RM_N, COD_IMM08, 0x00, 0x 00, COD_P86, /*LOOPZ*/ 0x01, 0xE0, 0x00, RM_D|RM_N, COD_IMM08, 0x00, 0x 00, COD_P86, /*LOOPNE*/ 0x01, 0xE0, 0x00, RM_D|RM_N, COD_IMM08, 0x00, 0x 00, COD_P86, /*LOOPNZ*/ /*DEC*/ 0x01, 0x48, 0x00, RM_S|RM_N|RM_A, COD_REG16, 0x0 0, 0x00, COD_P86, 0x01, 0xFE, 0x00, RM_1|RM_A, COD_rm08, 0x00, 0x0 0, COD_P86, 0x01, 0xFF, 0x00, RM_1|RM_A, COD_rm16, 0x00, 0x0 0, COD_P86, /*DIV*/ 0x01, 0xF6, 0x00, RM_6|RM_A, COD_rm08, 0x00, 0x0 0, COD_P86, 0x01, 0xF7, 0x00, RM_6|RM_A, COD_rm16, 0x00, 0x0 0, COD_P86, /*IDIV*/ 0x01, 0xF6, 0x00, RM_7|RM_A, COD_rm08, 0x00, 0x0 0, COD_P86, 0x01, 0xF7, 0x00, RM_7|RM_A, COD_rm16, 0x00, 0x0 0, COD_P86, /*IMUL*/ 0x01, 0xF6, 0x00, RM_5|RM_A, COD_rm08, 0x00, 0x0 0, COD_P86, 0x01, 0xF7, 0x00, RM_5|RM_A, COD_rm16, 0x00, 0x0 0, COD_P86, /*INC*/ 0x01, 0x40, 0x00, RM_S|RM_N|RM_A, COD_REG16, 0x0 0, 0x00, COD_P86, 0x01, 0xFE, 0x00, RM_0|RM_A, COD_rm08, 0x00, 0x 00, COD_P86, 0x01, 0xFF, 0x00, RM_0|RM_A, COD_rm16, 0x00, 0x 00, COD_P86, /*INT*/ 0x01, 0xCD, 0x00, RM_N, COD_IMM08, 0x00, 0x00, C OD_P86, /*MUL*/ 0x01, 0xF6, 0x00, RM_4|RM_A, COD_rm08, 0x00, 0x0 0, COD_P86, 0x01, 0xF7, 0x00, RM_4|RM_A, COD_rm16, 0x00, 0x0 0, COD_P86, /*NEG*/ 0x01, 0xF6, 0x00, RM_3|RM_A, COD_rm08, 0x00, 0x0 0, COD_P86, 0x01, 0xF7, 0x00, RM_3|RM_A, COD_rm16, 0x00, 0x0 0, COD_P86, /*NOT*/ 0x01, 0xF6, 0x00, RM_2|RM_A, COD_rm08, 0x00, 0x0 0, COD_P86, 0x01, 0xF7, 0x00, RM_2|RM_A, COD_rm16, 0x00, 0x0 0, COD_P86, /*POP*/ 0x01, 0x8F, 0x00, RM_0, COD_MEM16, 0x00, 0x 00, COD_P86, 0x01, 0x58, 0x00, RM_S, COD_REG16, 0x00, 0x 00, COD_P86, 0x01, 0x07, 0x00, RM_N|RM_B, COD_SEG, 0x00, SE G_ES, COD_P86, 0x01, 0x1F, 0x00, RM_N|RM_B, COD_SEG, 0x00, SE G_DS, COD_P86, 0x01, 0x17, 0x00, RM_N|RM_B, COD_SEG, 0x00, SE G_SS, COD_P86, 0x01, 0x0F, 0x00, RM_N|RM_B, COD_SEG, 0x00, SE G_CS, COD_P86, /*PUSH*/ 0x01, 0xFF, 0x00, RM_6, COD_MEM16, 0x00, 0x 00, COD_P86, 0x01, 0x00, 0x00, RM_S|RM_N, COD_SEG, 0x00, 0x 00, COD_P86, 0x01, 0x50, 0x00, RM_S, COD_REG16, 0x00, 0x 00, COD_P86 ; /************************************************** *************/ /***CODIGOS PARA INSTRUCCIONES CON DOS ARGUMENTOS***************/ /*Este es un tabla que apunta a un descriptor, para saber donde*/ /*estan los codigos. Solo hay que especificar el nu mero de */ /*opciones, ya que vCargaDescriptores se encarga de calcular */ /*la posicion. */ /*Formato: Posicion, No Opciones*/ byte sBDesIntDosArg[][2] = /*Instrucciones de do s argumentos*/ 0x00, 0x09, /*ADC*/ 0x09, 0x09, /*ADD*/ 0x12, 0x09, /*AND*/ 0x1B, 0x09, /*CMP*/ 0x24, 0x04, /*IN*/ 0x28, 0x01, /*LEA*/ 0x29, 0x01, /*LDS*/ 0x2A, 0x01, /*LES*/ 0x2B, 0x10, /*MOV*/ 0x3B, 0x09, /*OR*/ 0x44, 0x04, /*OUT*/ 0x48, 0x06, /*RCL*/ 0x4C, 0x06, /*RCR*/ 0x50, 0x06, /*ROL*/ 0x54, 0x06, /*ROR*/ 0x58, 0x06, /*SAL*/

Page 269: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

264

0x5C, 0x06, /*SAR*/ 0x60, 0x06, /*SHL*/ 0x64, 0x06, /*SHR*/ 0x68, 0x09, /*SBB*/ 0x71, 0x09, /*SUB*/ 0x7A, 0x06, /*TEST*/ 0x80, 0x06, /*XCHG*/ 0x86, 0x09, /*XOR*/ 0x8F, 0x01, /*BOUND*/ 0x90, 0x08, /*ESC*/ 0x91, 0x01 /*ENTER*/ ; /*Descriptor */ /*Formato: #Bytes por Inst, Inst(2), MOD1, Dec1(2) , ExBy1, MOD2, Dec2(2), ExBy2 = 11 bytes por Opcion*/ /*El simbolo /# es el MOD/RM byte y se compone de los bits: */ /* Bit 7: 1 El numero se trata como direccion JXX X y CALL */ /* Para instrucciones de un argumento y para dos */ /* este bit indica que se debe tomar el numero */ /* como si este fuera de 8 bits y no de 16 bits */ /* Bit 6: 1 Se suman los registros al codigo */ /* Bit 5: R/M */ /* Bit 4: R/M */ /* Bit 3: R/M */ /* Bit 2: 1 Se usa siguiente byte para Seg, Reg o Mem */ /* Bit 1: 1 Se emplea AND como comparador de otra forma = */ /* Bit 0: 1 No existen bits R/M se construyen */ /* */ /*Para instrucciones de dos argumentos se tienen d os MOD/RM */ /*si en ambos no existen los bit RM no se hace nad a. */ /*Si solo en el primero no existen los bits RM se crea. */ /* */ /*NOTA: Siempre la ultima opcion es cuando se acti va el bit GRAL*/ /*Muchos se rep¡ten, se puede optimizar esta matri z, de hecho */ /*Algunos se pueden olvidar, pero se tomo encuenta una futura */ /*aplicacion de 32 bits. */ /*Lleva un orden, primero los que son igual y lueg o AND */ /*Los AND se deben ordenar segun se pueda optimiza r, ya que hay */ /*instrucciones iguales pero con 1 o 2 bytes. */ /*En el caso de intrucciones de dos argumentos, en algunas */ /*instrucciones, uno de los argumentos es el forzo so y el otro el*/ /*opcional, por ejemplo: rm08, r08 en este caso r8 es el forzoso.*/ /*Se puede optimizar la tabla, ya que muchos se re piten */ byte sBCodIntDosArg[][12] = /*Instrucciones de d os argumentos*/ /*#byts INSTRUCCION MOD1 MOD2 DEC1 DEC2 EXBY1 EXBY2 PROC*/ /*ADC*/ 0x01, 0x14, 0x00, RM_N|RM_B, RM_N, COD_REG0 8, 0x00, COD_IMM08, 0x00, REG_AL, 0x00, COD_P86, 0x01, 0x15, 0x00, RM_N|RM_B, RM_N|RM_A, COD_REG1 6, 0x00, LCOD_NUMH16, HCOD_NUMH16, REG_AX, 0x00, COD_P86, 0x01, 0x12, 0x00, RM_N|RM_A, RM_A, COD_REG0 8, 0x00, COD_rm08, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x13, 0x00, RM_N|RM_A, RM_A, COD_REG1 6, 0x00, COD_rm16, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x10, 0x00, RM_N|RM_A, 0x00, COD_rm08 , 0x00, COD_REG08, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x11, 0x00, RM_N|RM_A, 0x00, COD_rm16 , 0x00, COD_REG16, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x80, 0x00, RM_A|RM_2, 0x00, COD_rm08 , 0x00, COD_IMM08, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x81, 0x00, RM_A|RM_2, 0x00, COD_rm16 , 0x00, COD_IMM16, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x83, 0x00, RM_A|RM_2, 0x00, COD_rm16 , 0x00, COD_IMM08, 0x00, 0x00, 0x00, COD_P86, /*ADD*/ 0x01, 0x04, 0x00, RM_N|RM_B, RM_N, COD_REG0 8, 0x00, COD_IMM08, 0x00, REG_AL, 0x00, COD_P86,

Page 270: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

265

0x01, 0x05, 0x00, RM_N|RM_B, RM_N|RM_A, COD_REG1 6, 0x00, LCOD_NUMH16, HCOD_NUMH16, REG_AX, 0x00, COD_P86, 0x01, 0x02, 0x00, RM_N|RM_A, RM_A, COD_REG0 8, 0x00, COD_rm08, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x03, 0x00, RM_N|RM_A, RM_A, COD_REG1 6, 0x00, COD_rm16, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x00, 0x00, RM_N|RM_A, 0x00, COD_rm08 , 0x00, COD_REG08, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x01, 0x00, RM_N|RM_A, 0x00, COD_rm16 , 0x00, COD_REG16, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x80, 0x00, RM_A|RM_0, 0x00, COD_rm08 , 0x00, COD_IMM08, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x81, 0x00, RM_A|RM_0, 0x00, COD_rm16 , 0x00, COD_IMM16, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x83, 0x00, RM_A|RM_0, 0x00, COD_rm16 , 0x00, COD_IMM08, 0x00, 0x00, 0x00, COD_P86, /*AND*/ 0x01, 0x24, 0x00, RM_N|RM_B, RM_N, COD_REG0 8, 0x00, COD_IMM08, 0x00, REG_AL, 0x00, COD_P86, 0x01, 0x25, 0x00, RM_N|RM_B, RM_N|RM_A, COD_REG1 6, 0x00, LCOD_NUMH16, HCOD_NUMH16, REG_AX, 0x00, COD_P86, 0x01, 0x22, 0x00, RM_N|RM_A, RM_A, COD_REG0 8, 0x00, COD_rm08, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x23, 0x00, RM_N|RM_A, RM_A, COD_REG1 6, 0x00, COD_rm16, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x20, 0x00, RM_N|RM_A, 0x00, COD_rm08 , 0x00, COD_REG08, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x21, 0x00, RM_N|RM_A, 0x00, COD_rm16 , 0x00, COD_REG16, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x80, 0x00, RM_A|RM_4, 0x00, COD_rm08 , 0x00, COD_IMM08, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x81, 0x00, RM_A|RM_4, 0x00, COD_rm16 , 0x00, COD_IMM16, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x83, 0x00, RM_A|RM_4, 0x00, COD_rm16 , 0x00, COD_IMM08, 0x00, 0x00, 0x00, COD_P86, /*CMP*/ 0x01, 0x3C, 0x00, RM_N|RM_B, RM_N, COD_REG0 8, 0x00, COD_IMM08, 0x00, REG_AL, 0x00, COD_P86, 0x01, 0x3D, 0x00, RM_N|RM_B, RM_N|RM_A, COD_REG1 6, 0x00, LCOD_NUMH16, HCOD_NUMH16, REG_AX, 0x00, COD_P86, 0x01, 0x3A, 0x00, RM_N|RM_A, RM_A, COD_REG0 8, 0x00, COD_rm08, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x3B, 0x00, RM_N|RM_A, RM_A, COD_REG1 6, 0x00, COD_rm16, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x38, 0x00, RM_N|RM_A, 0x00, COD_rm08 , 0x00, COD_REG08, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x39, 0x00, RM_N|RM_A, 0x00, COD_rm16 , 0x00, COD_REG16, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x80, 0x00, RM_A|RM_7, 0x00, COD_rm08 , 0x00, COD_IMM08, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x81, 0x00, RM_A|RM_7, 0x00, COD_rm16 , 0x00, COD_IMM16, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x83, 0x00, RM_A|RM_7, 0x00, COD_rm16 , 0x00, COD_IMM08, 0x00, 0x00, 0x00, COD_P86, /*IN*/ 0x01, 0xE4, 0x00, RM_N|RM_B, RM_N|RM_D, COD_REG0 8, 0x00, COD_IMM08, 0x00, REG_AL, 0x00, COD_P86, 0x01, 0xE5, 0x00, RM_N|RM_B, RM_N|RM_D, COD_REG1 6, 0x00, COD_IMM08, 0x00, REG_AX, 0x00, COD_P86, 0x01, 0xEC, 0x00, RM_N|RM_B, RM_N|RM_B, COD_REG0 8, 0x00, COD_REG16, 0x00, REG_AL, REG_DX, COD_P86, 0x01, 0xED, 0x00, RM_N|RM_B, RM_N|RM_B, COD_REG1 6, 0x00, COD_REG16, 0x00, REG_AX, REG_DX, COD_P86, /*LEA*/ 0x01, 0x8D, 0x00, RM_N, RM_A, COD_REG1 6, 0x00, LCOD_MEM, HCOD_MEM, 0x00, 0x00, COD_P86, /*LDS*/ 0x01, 0xC5, 0x00, RM_N, RM_A, COD_REG1 6, 0x00, LCOD_MEM, HCOD_MEM, 0x00, 0x00, COD_P86, /*LES*/

Page 271: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

266

0x01, 0xC4, 0x00, RM_N, RM_A, COD_REG1 6, 0x00, LCOD_MEM, HCOD_MEM, 0x00, 0x00, COD_P86, /*MOV*/ 0x01, 0xA0, 0x00, RM_N|RM_B, RM_N|RM_B|RM_A, COD _REG08, 0x00, LCOD_MEM, HCOD_MEM, REG_AL, DIR_OFF16, COD_P86, 0x01, 0xA1, 0x00, RM_N|RM_B, RM_N|RM_B|RM_A, COD _REG16, 0x00, LCOD_MEM, HCOD_MEM, REG_AX, DIR_OFF16, COD_P86, 0x01, 0xA2, 0x00, RM_N|RM_B|RM_A, RM_N|RM_B, LCO D_MEM, HCOD_MEM, COD_REG08, 0x00, DIR_OFF16, REG_AL, COD_P86, 0x01, 0xA3, 0x00, RM_N|RM_B|RM_A, RM_N|RM_B, LCO D_MEM, HCOD_MEM, COD_REG16, 0x00, DIR_OFF16, REG_AX, COD_P86, 0x01, 0xB0, 0x00, RM_S|RM_N, RM_N, COD_REG0 8, 0x00, COD_IMM08, 0x00, 0x00, 0x00, COD_P86, 0x01, 0xB8, 0x00, RM_S|RM_N, RM_N|RM_A, COD_REG1 6, 0x00, LCOD_NUMH16, HCOD_NUMH16, 0x00, 0x00, COD_P86, 0x01, 0x8A, 0x00, RM_N|RM_A, RM_A, COD_REG0 8, 0x00, COD_rm08, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x8B, 0x00, RM_N|RM_A, RM_A, COD_REG1 6, 0x00, COD_rm16, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x88, 0x00, RM_N|RM_A, 0x00, COD_rm08 , 0x00, COD_REG08, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x89, 0x00, RM_N|RM_A, 0x00, COD_rm16 , 0x00, COD_REG16, 0x00, 0x00, 0x00, COD_P86, 0x01, 0xC6, 0x00, RM_A|RM_0, 0x00, COD_rm08 , 0x00, COD_IMM08, 0x00, 0x00, 0x00, COD_P86, 0x01, 0xC7, 0x00, RM_A|RM_0, RM_A, COD_rm16 , 0x00, LCOD_NUMH16, HCOD_NUMH16, 0x00, 0x00, COD_P86, 0x01, 0x8C, 0x00, RM_N|RM_A, 0x00, COD_rm16 , 0x00, COD_SEG, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x8E, 0x00, RM_N|RM_B, RM_A, COD_SEG, 0x00, COD_rm16, 0x00, SEG_ES, 0x00, COD_P86, 0x01, 0x8E, 0x00, RM_N|RM_B, RM_A, COD_SEG, 0x00, COD_rm16, 0x00, SEG_DS, 0x00, COD_P86, 0x01, 0x8E, 0x00, RM_N|RM_B, RM_A, COD_SEG, 0x00, COD_rm16, 0x00, SEG_SS, 0x00, COD_P86, /*OR*/ 0x01, 0x0C, 0x00, RM_N|RM_B, RM_N, COD_REG0 8, 0x00, COD_IMM08, 0x00, REG_AL, 0x00, COD_P86, 0x01, 0x0D, 0x00, RM_N|RM_B, RM_N|RM_A, COD_REG1 6, 0x00, LCOD_NUMH16, HCOD_NUMH16, REG_AX, 0x00, COD_P86, 0x01, 0x0A, 0x00, RM_N|RM_A, RM_A, COD_REG0 8, 0x00, COD_rm08, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x0B, 0x00, RM_N|RM_A, RM_A, COD_REG1 6, 0x00, COD_rm16, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x08, 0x00, RM_N|RM_A, 0x00, COD_rm08 , 0x00, COD_REG08, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x09, 0x00, RM_N|RM_A, 0x00, COD_rm16 , 0x00, COD_REG16, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x80, 0x00, RM_A|RM_1, 0x00, COD_rm08 , 0x00, COD_IMM08, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x81, 0x00, RM_A|RM_1, 0x00, COD_rm16 , 0x00, COD_IMM16, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x83, 0x00, RM_A|RM_1, 0x00, COD_rm16 , 0x00, COD_IMM08, 0x00, 0x00, 0x00, COD_P86, /*OUT*/ 0x01, 0xE6, 0x00, RM_N, RM_N|RM_B, COD_IMM0 8, 0x00, COD_REG08, 0x00, 0x00, REG_AL, COD_P86, 0x01, 0xE7, 0x00, RM_N, RM_N|RM_B, COD_IMM0 8, 0x00, COD_REG16, 0x00, 0x00, REG_AX, COD_P86, 0x01, 0xEE, 0x00, RM_N|RM_B, RM_N|RM_B, COD_REG1 6, 0x00, COD_REG08, 0x00, REG_DX, REG_AL, COD_P86, 0x01, 0xEF, 0x00, RM_N|RM_B, RM_N|RM_B, COD_REG1 6, 0x00, COD_REG16, 0x00, REG_DX, REG_AX, COD_P86, /*RCL*/ 0x01, 0xD0, 0x00, RM_2|RM_A, RM_B|RM_A|RM_N, COD _rm08, 0x00, LCOD_NUMH16, HCOD_NUMH16, 0x00, 0x01, COD_P86, 0x01, 0xD2, 0x00, RM_2|RM_A, RM_B, COD_rm08 , 0x00, COD_REG08, 0x00, 0x00, REG_CL, COD_P86, 0x01, 0xD1, 0x00, RM_2|RM_A, RM_B|RM_A|RM_N, COD _rm16, 0x00, LCOD_NUMH16, HCOD_NUMH16, 0x00, 0x01, COD_P86,

Page 272: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

267

0x01, 0xD3, 0x00, RM_2|RM_A, RM_B, COD_rm16 , 0x00, COD_REG08, 0x00, 0x00, REG_CL, COD_P86, 0x01, 0xC0, 0x00, RM_2|RM_A, 0x00, COD_rm08 , 0x00, COD_IMM08, 0x00, 0x00, 0x00, COD_P186, 0x01, 0xC1, 0x00, RM_2|RM_A, 0x00, COD_rm16 , 0x00, COD_IMM08, 0x00, 0x00, 0x00, COD_P186, /*RCR*/ 0x01, 0xD0, 0x00, RM_3|RM_A, RM_B|RM_A|RM_N, COD _rm08, 0x00, LCOD_NUMH16, HCOD_NUMH16, 0x00, 0x01, COD_P86, 0x01, 0xD2, 0x00, RM_3|RM_A, RM_B, COD_rm08 , 0x00, COD_REG08, 0x00, 0x00, REG_CL, COD_P86, 0x01, 0xD1, 0x00, RM_3|RM_A, RM_B|RM_A|RM_N, COD _rm16, 0x00, LCOD_NUMH16, HCOD_NUMH16, 0x00, 0x01, COD_P86, 0x01, 0xD3, 0x00, RM_3|RM_A, RM_B, COD_rm16 , 0x00, COD_REG08, 0x00, 0x00, REG_CL, COD_P86, 0x01, 0xC0, 0x00, RM_3|RM_A, 0x00, COD_rm08 , 0x00, COD_IMM08, 0x00, 0x00, 0x00, COD_P186, 0x01, 0xC1, 0x00, RM_3|RM_A, 0x00, COD_rm16 , 0x00, COD_IMM08, 0x00, 0x00, 0x00, COD_P186, /*ROL*/ 0x01, 0xD0, 0x00, RM_0|RM_A, RM_B|RM_A|RM_N, COD _rm08, 0x00, LCOD_NUMH16, HCOD_NUMH16, 0x00, 0x01, COD_P86, 0x01, 0xD2, 0x00, RM_0|RM_A, RM_B, COD_rm08 , 0x00, COD_REG08, 0x00, 0x00, REG_CL, COD_P86, 0x01, 0xD1, 0x00, RM_0|RM_A, RM_B|RM_A|RM_N, COD _rm16, 0x00, LCOD_NUMH16, HCOD_NUMH16, 0x00, 0x01, COD_P86, 0x01, 0xD3, 0x00, RM_0|RM_A, RM_B, COD_rm16 , 0x00, COD_REG08, 0x00, 0x00, REG_CL, COD_P86, 0x01, 0xC0, 0x00, RM_0|RM_A, 0x00, COD_rm08 , 0x00, COD_IMM08, 0x00, 0x00, 0x00, COD_P186, 0x01, 0xC1, 0x00, RM_0|RM_A, 0x00, COD_rm16 , 0x00, COD_IMM08, 0x00, 0x00, 0x00, COD_P186, /*ROR*/ 0x01, 0xD0, 0x00, RM_1|RM_A, RM_B|RM_A|RM_N, COD _rm08, 0x00, LCOD_NUMH16, HCOD_NUMH16, 0x00, 0x01, COD_P86, 0x01, 0xD2, 0x00, RM_1|RM_A, RM_B, COD_rm08 , 0x00, COD_REG08, 0x00, 0x00, REG_CL, COD_P86, 0x01, 0xD1, 0x00, RM_1|RM_A, RM_B|RM_A|RM_N, COD _rm16, 0x00, LCOD_NUMH16, HCOD_NUMH16, 0x00, 0x01, COD_P86, 0x01, 0xD3, 0x00, RM_1|RM_A, RM_B, COD_rm16 , 0x00, COD_REG08, 0x00, 0x00, REG_CL, COD_P86, 0x01, 0xC0, 0x00, RM_1|RM_A, 0x00, COD_rm08 , 0x00, COD_IMM08, 0x00, 0x00, 0x00, COD_P186, 0x01, 0xC1, 0x00, RM_1|RM_A, 0x00, COD_rm16 , 0x00, COD_IMM08, 0x00, 0x00, 0x00, COD_P186, /*SAL*/ 0x01, 0xD0, 0x00, RM_4|RM_A, RM_B|RM_A|RM_N, COD _rm08, 0x00, LCOD_NUMH16, HCOD_NUMH16, 0x00, 0x01, COD_P86, 0x01, 0xD2, 0x00, RM_4|RM_A, RM_B, COD_rm08 , 0x00, COD_REG08, 0x00, 0x00, REG_CL, COD_P86, 0x01, 0xD1, 0x00, RM_4|RM_A, RM_B|RM_A|RM_N, COD _rm16, 0x00, LCOD_NUMH16, HCOD_NUMH16, 0x00, 0x01, COD_P86, 0x01, 0xD3, 0x00, RM_4|RM_A, RM_B, COD_rm16 , 0x00, COD_REG08, 0x00, 0x00, REG_CL, COD_P86, 0x01, 0xC0, 0x00, RM_4|RM_A, 0x00, COD_rm08 , 0x00, COD_IMM08, 0x00, 0x00, 0x00, COD_P186, 0x01, 0xC1, 0x00, RM_4|RM_A, 0x00, COD_rm16 , 0x00, COD_IMM08, 0x00, 0x00, 0x00, COD_P186, /*SAR*/ 0x01, 0xD0, 0x00, RM_7|RM_A, RM_B|RM_A|RM_N, COD _rm08, 0x00, LCOD_NUMH16, HCOD_NUMH16, 0x00, 0x01, COD_P86, 0x01, 0xD2, 0x00, RM_7|RM_A, RM_B, COD_rm08 , 0x00, COD_REG08, 0x00, 0x00, REG_CL, COD_P86, 0x01, 0xD1, 0x00, RM_7|RM_A, RM_B|RM_A|RM_N, COD _rm16, 0x00, LCOD_NUMH16, HCOD_NUMH16, 0x00, 0x01, COD_P86, 0x01, 0xD3, 0x00, RM_7|RM_A, RM_B, COD_rm16 , 0x00, COD_REG08, 0x00, 0x00, REG_CL, COD_P86, 0x01, 0xC0, 0x00, RM_7|RM_A, 0x00, COD_rm08 , 0x00, COD_IMM08, 0x00, 0x00, 0x00, COD_P186, 0x01, 0xC1, 0x00, RM_7|RM_A, 0x00, COD_rm16 , 0x00, COD_IMM08, 0x00, 0x00, 0x00, COD_P186,

Page 273: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

268

/*SHL*/ 0x01, 0xD0, 0x00, RM_4|RM_A, RM_B|RM_A|RM_N, COD _rm08, 0x00, LCOD_NUMH16, HCOD_NUMH16, 0x00, 0x01, COD_P86, 0x01, 0xD2, 0x00, RM_4|RM_A, RM_B, COD_rm08 , 0x00, COD_REG08, 0x00, 0x00, REG_CL, COD_P86, 0x01, 0xD1, 0x00, RM_4|RM_A, RM_B|RM_A|RM_N, COD _rm16, 0x00, LCOD_NUMH16, HCOD_NUMH16, 0x00, 0x01, COD_P86, 0x01, 0xD3, 0x00, RM_4|RM_A, RM_B, COD_rm16 , 0x00, COD_REG08, 0x00, 0x00, REG_CL, COD_P86, 0x01, 0xC0, 0x00, RM_4|RM_A, 0x00, COD_rm08 , 0x00, COD_IMM08, 0x00, 0x00, 0x00, COD_P186, 0x01, 0xC1, 0x00, RM_4|RM_A, 0x00, COD_rm16 , 0x00, COD_IMM08, 0x00, 0x00, 0x00, COD_P186, /*SHR*/ 0x01, 0xD0, 0x00, RM_5|RM_A, RM_B|RM_A|RM_N, COD _rm08, 0x00, LCOD_NUMH16, HCOD_NUMH16, 0x00, 0x01, COD_P86, 0x01, 0xD2, 0x00, RM_5|RM_A, RM_B, COD_rm08 , 0x00, COD_REG08, 0x00, 0x00, REG_CL, COD_P86, 0x01, 0xD1, 0x00, RM_5|RM_A, RM_B|RM_A|RM_N, COD _rm16, 0x00, LCOD_NUMH16, HCOD_NUMH16, 0x00, 0x01, COD_P86, 0x01, 0xD3, 0x00, RM_5|RM_A, RM_B, COD_rm16 , 0x00, COD_REG08, 0x00, 0x00, REG_CL, COD_P86, 0x01, 0xC0, 0x00, RM_5|RM_A, 0x00, COD_rm08 , 0x00, COD_IMM08, 0x00, 0x00, 0x00, COD_P186, 0x01, 0xC1, 0x00, RM_5|RM_A, 0x00, COD_rm16 , 0x00, COD_IMM08, 0x00, 0x00, 0x00, COD_P186, /*SBB*/ 0x01, 0x1C, 0x00, RM_N|RM_B, RM_N, COD_REG0 8, 0x00, COD_IMM08, 0x00, REG_AL, 0x00, COD_P86, 0x01, 0x1D, 0x00, RM_N|RM_B, RM_N|RM_A, COD_REG1 6, 0x00, LCOD_NUMH16, HCOD_NUMH16, REG_AX, 0x00, COD_P86, 0x01, 0x1A, 0x00, RM_N|RM_A, RM_A, COD_REG0 8, 0x00, COD_rm08, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x1B, 0x00, RM_N|RM_A, RM_A, COD_REG1 6, 0x00, COD_rm16, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x18, 0x00, RM_N|RM_A, 0x00, COD_rm08 , 0x00, COD_REG08, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x19, 0x00, RM_N|RM_A, 0x00, COD_rm16 , 0x00, COD_REG16, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x80, 0x00, RM_A|RM_3, 0x00, COD_rm08 , 0x00, COD_IMM08, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x81, 0x00, RM_A|RM_3, 0x00, COD_rm16 , 0x00, COD_IMM16, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x83, 0x00, RM_A|RM_3, 0x00, COD_rm16 , 0x00, COD_IMM08, 0x00, 0x00, 0x00, COD_P86, /*SUB*/ 0x01, 0x2C, 0x00, RM_N|RM_B, RM_N, COD_REG0 8, 0x00, COD_IMM08, 0x00, REG_AL, 0x00, COD_P86, 0x01, 0x2B, 0x00, RM_N|RM_B, RM_N|RM_A, COD_REG1 6, 0x00, LCOD_NUMH16, HCOD_NUMH16, REG_AX, 0x00, COD_P86, 0x01, 0x2A, 0x00, RM_N|RM_A, RM_A, COD_REG0 8, 0x00, COD_rm08, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x2B, 0x00, RM_N|RM_A, RM_A, COD_REG1 6, 0x00, COD_rm16, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x28, 0x00, RM_N|RM_A, 0x00, COD_rm08 , 0x00, COD_REG08, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x29, 0x00, RM_N|RM_A, 0x00, COD_rm16 , 0x00, COD_REG16, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x80, 0x00, RM_A|RM_5, 0x00, COD_rm08 , 0x00, COD_IMM08, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x81, 0x00, RM_A|RM_5, 0x00, COD_rm16 , 0x00, COD_IMM16, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x83, 0x00, RM_A|RM_5, 0x00, COD_rm16 , 0x00, COD_IMM08, 0x00, 0x00, 0x00, COD_P86, /*TEST*/ 0x01, 0xA8, 0x00, RM_N|RM_B, RM_N, COD_REG0 8, 0x00, COD_IMM08, 0x00, REG_AL, 0x00, COD_P86, 0x01, 0xA9, 0x00, RM_N|RM_B, RM_N|RM_A, COD_REG1 6, 0x00, LCOD_NUMH16, HCOD_NUMH16, REG_AX, 0x00, COD_P86, 0x01, 0x84, 0x00, RM_N|RM_A, 0x00, COD_rm08 , 0x00, COD_REG08, 0x00, 0x00, 0x00, COD_P86,

Page 274: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

269

0x01, 0x85, 0x00, RM_N|RM_A, 0x00, COD_rm16 , 0x00, COD_REG16, 0x00, 0x00, 0x00, COD_P86, 0x01, 0xF6, 0x00, RM_A|RM_0, 0x00, COD_rm08 , 0x00, COD_IMM08, 0x00, 0x00, 0x00, COD_P86, 0x01, 0xF7, 0x00, RM_A|RM_0, RM_A, COD_rm16 , 0x00, LCOD_NUMH16, HCOD_NUMH16, 0x00, 0x00, COD_P86, /*XCHG*/ 0x01, 0x90, 0x00, RM_N|RM_B, RM_N|RM_S, COD_REG1 6, 0x00, COD_REG16, 0x00, REG_AX, 0x00, COD_P86, 0x01, 0x90, 0x00, RM_N|RM_S, RM_N|RM_B, COD_REG1 6, 0x00, COD_REG16, 0x00, 0x00, REG_AX, COD_P86, 0x01, 0x86, 0x00, RM_N|RM_A, 0x00, COD_rm08 , 0x00, COD_REG08, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x87, 0x00, RM_N|RM_A, 0x00, COD_rm16 , 0x00, COD_REG16, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x86, 0x00, RM_N, RM_A, COD_REG0 8, 0x00, COD_rm08, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x87, 0x00, RM_N, RM_A, COD_REG1 6, 0x00, COD_rm16, 0x00, 0x00, 0x00, COD_P86, /*XOR*/ 0x01, 0x34, 0x00, RM_N|RM_B, RM_N, COD_REG0 8, 0x00, COD_IMM08, 0x00, REG_AL, 0x00, COD_P86, 0x01, 0x35, 0x00, RM_N|RM_B, RM_N|RM_A, COD_REG1 6, 0x00, LCOD_NUMH16, HCOD_NUMH16, REG_AX, 0x00, COD_P86, 0x01, 0x32, 0x00, RM_N|RM_A, RM_A, COD_REG0 8, 0x00, COD_rm08, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x33, 0x00, RM_N|RM_A, RM_A, COD_REG1 6, 0x00, COD_rm16, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x30, 0x00, RM_N|RM_A, 0x00, COD_rm08 , 0x00, COD_REG08, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x31, 0x00, RM_N|RM_A, 0x00, COD_rm16 , 0x00, COD_REG16, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x80, 0x00, RM_A|RM_6, 0x00, COD_rm08 , 0x00, COD_IMM08, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x81, 0x00, RM_A|RM_6, 0x00, COD_rm16 , 0x00, COD_IMM16, 0x00, 0x00, 0x00, COD_P86, 0x01, 0x83, 0x00, RM_A|RM_6, 0x00, COD_rm16 , 0x00, COD_IMM08, 0x00, 0x00, 0x00, COD_P86, /*BOUND*/ 0x01, 0x62, 0x00, RM_N|RM_A, RM_A, COD_REG1 6, 0x00, COD_rm16, 0x00, 0x00, 0x00, COD_P186, /*ESC*/ 0x01, 0xD8, 0x00, RM_N, RM_N|RM_A, COD_IMM0 8, 0x00, COD_rm16, 0x00, 0x00, 0x00, COD_P186, 0x01, 0xD9, 0x00, RM_N|RM_B, RM_N|RM_A, COD_IMM0 8, 0x00, COD_rm16, 0x00, 0x08, 0x00, COD_P186, 0x01, 0xDA, 0x00, RM_N|RM_B, RM_N|RM_A, COD_IMM0 8, 0x00, COD_rm16, 0x00, 0x10, 0x00, COD_P186, 0x01, 0xDB, 0x00, RM_N|RM_B, RM_N|RM_A, COD_IMM0 8, 0x00, COD_rm16, 0x00, 0x18, 0x00, COD_P186, 0x01, 0xDC, 0x00, RM_N|RM_B, RM_N|RM_A, COD_IMM0 8, 0x00, COD_rm16, 0x00, 0x20, 0x00, COD_P186, 0x01, 0xDD, 0x00, RM_N|RM_B, RM_N|RM_A, COD_IMM0 8, 0x00, COD_rm16, 0x00, 0x28, 0x00, COD_P186, 0x01, 0xDE, 0x00, RM_N|RM_B, RM_N|RM_A, COD_IMM0 8, 0x00, COD_rm16, 0x00, 0x30, 0x00, COD_P186, 0x01, 0xDF, 0x00, RM_N|RM_B, RM_N|RM_A, COD_IMM0 8, 0x00, COD_rm16, 0x00, 0x38, 0x00, COD_P186, /*ENTER*/ 0x01, 0xC8, 0x00, RM_N|RM_A, RM_N, LCOD_NUM H16, HCOD_NUMH16, COD_IMM08, 0x00, 0x00, 0x00, COD_P186 ;

F.5 COLOR.H //DEFINICION DE LOS COLORES PARA LA APLICACION //Colores de fondo #define BNEGRO 0x00 #define BAZUL 0x10

Page 275: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

270

#define BVERDE 0x20 #define BCYAN 0x30 #define BROJO 0x40 #define BVIOLETA 0x50 #define BNARANJA 0x60 #define BGRIS 0x70 #define BINEGRO 0x80 #define BIAZUL 0x90 #define BIVERDE 0xA0 #define BICYAN 0xB0 #define BIROJO 0xC0 #define BIVIOLETA 0xD0 #define BINARANJA 0xE0 #define BIGRIS 0xF0 //Colores de letras #define FNEGRO 0x00 #define FAZUL 0x01 #define FVERDE 0x02 #define FCYAN 0x03 #define FROJO 0x04 #define FVIOLETA 0x05 #define FNARANJA 0x06 #define FGRIS 0x07 #define FINEGRO 0x08 #define FIAZUL 0x09 #define FIVERDE 0x0A #define FICYAN 0x0B #define FIROJO 0x0C #define FIVIOLETA 0x0D #define FIAMARILLO 0x0E #define FIBLANCO 0x0F //Macro para unir colores #define CREA_COLOR(bb, ff) (bb|ff)

F.6 COMMAND.H /*CONTIENE LAS CONSTANTES DEL MENU, EMPLEADAS EN EL EDITOR */ const //Algunas constantes que son de uso general para el editor //Constantes dentro del editor //Estos son los comandos del menu cmAbrir = 100, cmNuevo = 101, cmCambiarDir = 102, cmDosShell = 103, cmShowClip = 105, cmCompilarD = 106, cmAcercade = 107, cmAbrirPrima = 108, cmClosePrima = 109, cmCloseAll = 110, cmOpciones = 111, cmMensajes = 112, cmGuardarTodo = 113, cmDebug = 114, cmCompilarM = 115, cmSelPrg = 116, cmCargaPrg = 117, cmDefReadMem = 118, cmChkConexion = 119, cmReset = 120, cmReadPrg = 121, cmReadMem = 122, cmReadRegs = 123,

Page 276: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

271

cmMoveMem = 124, cmCargaSelPrg = 125, cmCargaMemPrg = 126, cmEjecutar = 127, cmPasoAPaso = 128, cmDetener = 129, cmAddIns = 138, cmChgReg = 139, cmChgValMem = 140, cmReiniciaSerie = 141, cmAbrirMAP = 142, cmActualizaEditor = 145, //Para actualizacion d e los editores cmPrueba = 180, //Solo para pruebas!!!! cmNone = 190;

F.7 DEBUG.H /*CONTIENE EL CODIGO PARA EL MANEJO DE LAS VENTANAS DEL DEPURADOR*/ #define Uses_TEventQueue #define Uses_TEvent #define Uses_TProgram #define Uses_TApplication #define Uses_TKeys #define Uses_TRect #define Uses_TMenuBar #define Uses_TSubMenu #define Uses_TMenuItem #define Uses_TStatusLine #define Uses_TStatusItem #define Uses_TStatusDef #define Uses_TDeskTop #define Uses_TView #define Uses_TWindow #define Uses_TFrame #define Uses_TScroller #define Uses_TScrollBar #define Uses_TDialog #define Uses_TButton #define Uses_TSItem #define Uses_TCheckBoxes #define Uses_TRadioButtons #define Uses_TLabel #define Uses_TInputLine #include <tv.h> #include <lib.h> //Referencia del depurador #define DEPURA_REF 0x0000 //Inicia en CERO sie mpre #define DBGMAQ_MAXREN 32 //Maximo numero de rengl ones //Estas clases no modifican ninguno de sus buffer, solo presnetan class MAQWINDOW : public TScroller //Ventana que muestra el codigo maquina y ensamb lador private: int iPosCur; //Posicion del cursor (en renglon es), inicia en 1 word wPosExe; //Posicion ejecutable (en posicio n de memoria) word wPosRen[DBGMAQ_MAXREN]; //Localizacion de los renglones byte *pbBufCod; //Buffer donde se almacena el c odigo word wLenBuf; //Longutid del buffer word wLenFirst; //Longitud de la primera instru ccion

Page 277: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

272

public: //Constructor MAQWINDOW (const TRect& pstrBounds, TScrollBar * pstsbHScrollBar, TScrollBar *pstsbVScrollBar, byte *pbBuf, word wLen); virtual void handleEvent(TEvent& psteEvent); virtual void draw(); inline void vCambiaVScroll (int iPos); void vResetParams (); //Reinicia los parametros word wObtenPosicion (); //Posicion del cursor word wObtenPosicionEXE (); //Posicion de la eje cucion void vFijaPosicionEXE (word wPos); //Fija posic ion del ejecutable byte bBytesPosEXE (); //Regresa la longitud en bytes del ejecutable ; class MEMWINDOW : public TScroller //Ventana que muestra el volcado de memoria private: int iPosCur; //Posicion del cursor (en renglone s), inicia en 0 byte *pbBufMem; //Buffer de memoria donde se al macena lo que se desplega word wLenBuf; //Longitud del bloque completo de memoria a leer en bytes byte bTamBlk; //Longitud de cada bloque de memo ria a presentar word wSegMem; //Segmento que se esta manejando word wOffSet; //Offset del segmento public: //Constructor MEMWINDOW (const TRect& pstrBounds, TScrollBar * pstsbHScrollBar, TScrollBar *pstsbVScrollBar, byte *pbBuf, word wLen, byte bTBlk, w ord wSeg, word wOffS); virtual void draw(); void vFijaSegmentoOffset (word wSeg, word wOff); //Fija segmento y offset de volcado virtual void handleEvent(TEvent& psteEvent); ; class REGWINDOW : public TScroller //Ventana que muestra los registros private: int iPosCur; //Posicion del cursor (en renglone s), inicia en 0 char *pcBufReg; //Buffer de registros byte bNumReg; //Numero de registros byte bLenReg; //Longitud de cada linea de regis tro public: //Constructor REGWINDOW (const TRect& pstrBounds, TScrollBar * pstsbHScrollBar, TScrollBar *pstsbVScrollBar, char *pcBuf, byte bNumR, byte bLenR); virtual void handleEvent(TEvent& event); inline void vCambiaVScroll (int iPos); virtual void draw(); word wRegistroSel (); ; class DEBUGWINDOW : public TWindow private: byte bTamVolMem; //Tama¤o de la ventana de volc ado de memoria public: MAQWINDOW *psmawMW; //Ventata de codigo maquina MEMWINDOW *psmewMW; //Ventana de volcado de mem oria REGWINDOW *psrwRW; //Ventana de registros //Constructor DEBUGWINDOW (const TRect& pstrBounds, byte bTVol Mem, byte *pbVolMem, word wLenMem, byte bTBlkMemVol, word wSeg, word wOffS, //Volcado de memoria byte *pbBuf, word wLenCod, //Para debug char *pcBug, byte bLenR, byte bNumR ); //A los registros ~DEBUGWINDOW (); virtual void sizeLimits (TPoint& pstpminP, TPoin t& pstpmaxP ); //Tama¤o de ventana virtual void close (); //Oculta la ventana void vCerrar (); //Cierra definitivamente void vMostrar (); //Muestra la ventana void vActualiza (); //Actualiza la ventana (tod a) void vResetAll (); word wObtenPosInstruccion (); //Obtiene la posi cion actual de la instruccion (cursor)

Page 278: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

273

word wObtenRegistroSel (); //Obtiene el valor r egistro seleccionado void vFijaSegOffVolMem (word wSeg, word wOff); //Fija el segmento y offset del volcado de memoria void vFijaPosEXE (word wPos); //Fija la posicio n de la ejecucion word wObtenPosEXE (); //Obtiene la posicion act ual de la ejecucion ;

F.8 DEFINE.H /* CONTIENE LAS DEFINICIONES EMPLEADAS POR EL PROGR AMA */ #ifndef DEFINE_H_ #define DEFINE_H_ /*Definiciones generales*/ #define LEN_COD 0 /*Posicion de la longit ud del codigo*/ #define MAX_LEN_CAD 128 /*Maxima longitud de la cadena y c¢digo en ensamblador*/ #define MAX_LEN_NUM 35 /*Maxima longitu de un numero (el binario es el mayor)*/ #define CHK_ERROR 0x00FF /*Para veficar cuando h ay error*/ #define SEG_PREF 0x20 /*Prefixo para registro s de segmento*/ #define MDIR_ERR 0xFF /*Modo de direccionamie nto no valido*/ #define BASE_NUMP 16 /*Base numerica a impri mir*/ #define DEF_SALTO 2 /*Un salto auxiliar, de be ser menor a 80H*/ #define MAX_PATH 130 /*Longitud maxima del p ath*/ #define MAX_NFILE 14 /*Tama¤o maximo de nomb re de archivo 8.3*/ #define MAX_NESTFILE 2 /*Maximo numero de arch ivos anidados con INCLUDE*/ #define MAX_LENMSG 65 /*Maxima longitud de me nsajes*/ #define LEN_ARRAY 64 /*Maxima longitud para un array con DB, depende de MAX_LEN_CAD*/ /*Definiciones para los mensajes (Errores, warning s, etc*/ //#define SCROLL_MIN_MSG 1 /*Numero minimo de me nsajes (en cuanto a tama¤o)*/ /*NOTA: Si cambiamos las instrucciones o sus codigo s, es posible que*/ /*sea necesario modificar el valor de las siguiente s constantes */ /*Banderas del ensamblador*/ /*Que se emplean por el usuario*/ #define CTEASM_LBL 0x0010 /*Acepta etiquetas y asigna memoria*/ #define CTEASM_CTE 0x0020 /*Acepta constante s y asigna memoria*/ #define CTEASM_ARCHIVO 0x0004 /*Se compila desde archivo (SIRVE en instrucciones especiales)*/ /*Que se emplean por el ensamblador*/ #define CTEASM_ 0x0001 /* */ #define CTEASM_NOREF 0x0002 /*Las siguientes e tiquetas no tendran referencia*/ #define CTEASM_NESTFILE 0x0008 /*Hay un archivo a nidado es espera*/ #define CTEASM_SAVEI 0x0040 /*Guarda la instru ccion. NOTA: NO USAR*/ #define CTEASM_2PASO 0x0080 /*Define segundo p aso del compilador. NO USAR*/ #define CTEASM_NO1INST 0x0100 /*Si es 1 ya se co mpilo la primera instruccion*/ #define CTEASM_SETREF 0x0200 /*Se define SETREF */ /*Tipos de NUMEROS*/ #define NUM_TIPO_HEX 1 /*Numero hexadecimal*/ #define NUM_TIPO_DEC 2 /*Numero decimal*/ #define NUM_TIPO_BIN 3 /*Numero binario*/ /*Identificadores de cada elemento de la cadena*/ #define ID_NADA 0 /*Cadena desconocida, pue de ser una etiqueta o variable*/ #define ID_REG16 1 /*Registro de 16 bits*/ #define ID_REG16_A 0 /*Registro AX*/ #define ID_REGDIR 2 /*Registro de direcciones son de 16 bits*/ #define ID_REGDIR0 3 /*Registro BX*/ #define ID_REGDIR1 5 /*Registro BP*/ #define ID_REGDIR2 6 /*Registro SI*/ #define ID_REGDIR3 7 /*Registro DI*/ #define ID_REG08 3 /*Registro de 08 bits*/ #define ID_REG08_A 0 /*Registro AL*/ #define ID_SEG 4 /*Registro de segmento*/ #define ID_INOARG 5 /*Instrucciones sin argum entos*/ #define ID_IUNARG 6 /*Instrucciones de un arg umento*/ #define ID_IUNARGJ 40 /*Donde termina los salto s*/ #define ID_IDOSARG 7 /*Instrucciones de dos ar gumentos*/ #define ID_IDOSARGI 4 /*Instruccion IN*/

Page 279: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

274

#define ID_IESP 8 /*Instrucciones especiale s*/ #define ID_IESP_C 5 /*Posicion de las instruc ciones especiales de cadena*/ #define ID_IESP_E 19 /*Posicion de las instruc ciones especiales de tipo*/ #define ID_IESP_B 19 /*Posicion de BYTE*/ #define ID_IESP_W 20 /*Posicion de WORD*/ #define ID_IESP_P 21 /*Posicion de PTR*/ #define ID_IESP_F 22 /*Posicion de FAR*/ #define ID_NUMERO 9 /*Numero de 8 o 16 bits*/ #define ID_NUM08 0 /*Numero de 8 bits*/ #define ID_NUM16 1 /*Numero de 16 bits*/ #define ID_NUM32 2 /*Numero de 32 bits*/ #define ID_OPERADOR 10 /*Es un operador, se defi nen por el que es*/ #define ID_REG32 11 /*Registro de 32 bits*/ #define ID_RESWORD 12 /*Palabras reservadas*/ #define ID_RW_DB 0 /*Palabra reservada DB*/ #define ID_RW_DW 1 /*Palabra reservada DW*/ #define ID_RW_ORG 2 /*Palabra reservada ORG*/ #define ID_RW_EQU 3 /*Palabra reservada EQU*/ #define ID_RW_INC 4 /*Palabra reservada INCLU DE*/ #define ID_RW_SREF 5 /*Palabra reservada REF*/ #define ID_RW_DELA 6 /*Palabra reservada DELAL L*/ #define ID_RW_LSTC 7 /*Palabra reservada LSTCT E*/ #define ID_RW_PROC 8 /*Palabra reservada PROC* / #define ID_RW_ENDP 9 /*Palabra reservada ENDP* / #define ID_RW_86 10 /*Palabra reservada 86*/ #define ID_RW_186 11 /*Palabra reservada 186*/ #define ID_RW_286 12 /*Palabra reservada 286*/ #define ID_RW_386 13 /*Palabra reservada 386*/ #define ID_RW_88 14 /*Palabra reservada 88*/ #define ID_RW_188 15 /*Palabra reservada 188*/ #define ID_ETIQUETA 13 /*Etiqueta*/ #define ID_LBL_NDF 00 /*La etiqueta no tiene re ferencia*/ #define ID_LBL_DEF 01 /*La etiqueta tiene refer encia*/ #define ID_LBL_TST 02 /*La etiqueta esta en pru eba*/ #define ID_CONSTANTE 14 /*Es una constante, se ap lica lo mismo a ID_NUMERO*/ /*#define ID_NUM08 0 /*Numero de 8 bits*/ /*#define ID_NUM16 1 /*Numero de 16 bits*/ /*#define ID_NUM32 2 /*Numero de 32 bits*/ #define ID_LBLCTE 15 /*Puede ser una constante o etiqueta*/ #define ID_CADENA 16 /*Cadena de texto, encerr ada en comillas*/ //#define ID_TERMINA 80 /*Termina, ya que no se pudo compilar por etiqueta o constante*/ /*Longitudes de las cadenas empleadas*/ #define LEN_REG16 8 /*Registro de 16 bits*/ #define LEN_REG08 8 /*Registro de 08 bits*/ #define LEN_SEG 4 /*Registro de segmento + 2 en el 386*/ #define LEN_REG32 8 /*Registro de 32 bits*/ #define LEN_INOARG 36 /*Instrucciones sin argum entos*/ #define LEN_IUNARG 51 /*Instrucciones de un arg umento*/ #define LEN_IDOSARG 27 /*Instrucciones de dos ar gumentos*/ #define LEN_IESP 23 /*Instrucciones especiale s*/ #define LEN_RESWORD 16 /*Palabras reservadas*/ #define LEN_RM_DIR 24 /*Modos de direccionamiento */ #define LEN_RM_REG 8 /*Numero de registros en R/ M*/ /*El error se forma de una WORD con dos variantes, la palabra alta HWORD*/ /*y la palabra baja LWORD. En HWORD se almacena la posicion del error*/ /*o alguna otra caracteristica cuando no hay error ; en LWORD se encuentra*/ /*el codigo de error, basado en la siguiente lista */ #define ERR_NE 0 /*No hay error*/ #define ERR_CDL 1 /*Cadena demasiado larga*/ #define ERR_NOM 2 /*No hay memoria suficiente* / #define ERR_CNI 3 /*Cadena o instruccion no va lidas*/ #define ERR_EIE 4 /*Error en instruccion o en etiqueta*/ #define ERR_ONV 5 /*Operadores no validos*/ #define ERR_SEN 6 /*Se esperaba un numero*/ #define ERR_MUI 7 /*Mal uso de instruccion*/ #define ERR_HAE 8 /*Existe un archivo en esper a*/ #define ERR_SIC 9 /*Se espera MOVS, SCAS, etc* /

Page 280: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

275

#define ERR_FA 10 /*Falta argumento(s)*/ #define ERR_EEA 11 /*En uso de argumento(s)*/ #define ERR_MUS 12 /*Mal uso de registro de seg mento*/ #define ERR_SPI 13 /*Se esperaba parentesis [*/ #define ERR_EDO 14 /*Mal uso de operador*/ #define ERR_ANV 15 /*Argumento no valido*/ #define ERR_SUN 16 /*Solo un numero a la vez*/ #define ERR_CNV 17 /*Caracter no valido*/ #define ERR_INV 18 /*Instruccion no valida*/ #define ERR_SEP 19 /*Se esperaba PTR*/ #define ERR_RR 20 /*Registro repetido*/ #define ERR_ANI 21 /*Argumentos no validos en i nstruccion*/ #define ERR_ELA 22 /*Error al leer archivo*/ #define ERR_SEC 23 /*Se esperaba ,*/ #define ERR_EEI 24 /*Mal uso de instruccion*/ #define ERR_DNV 25 /*Direccionamiento no valido */ #define ERR_MUF 26 /*Mal uso de FAR*/ #define ERR_I2M 27 /*Imposible usar dos localid ades de memoria a la vez*/ #define ERR_I2N 28 /*Imposible usar dos numeros a la vez*/ #define ERR_NUD 29 /*Mal uso de una direccion*/ #define ERR_EAA 30 /*No se puede abrir archivo a compilar*/ #define ERR_EAI 31 /*No se puede abrir archivo en INCLUDE*/ #define ERR_ECA 32 /*No se puede crear archivo de salida (.COM)*/ #define ERR_NNV 33 /*Numero no valido*/ #define ERR_NPR 34 /*No se puede resolver refer encia*/ #define ERR_FCC 35 /*Falta cerrar comillas*/ #define ERR_EER 36 /*Referencia no valida o Fal ta.*/ #define ERR_NCA 37 /*Nombre de constante o etiq ueta ya asignado*/ #define ERR_SEL 38 /*Se espera EQU o : */ #define ERR_VPI 39 /*Valida solo como primera i nstruccion*/ #define ERR_TAI 40 /*No es posible un mayor ani damiento en archivos INCLUDE*/ #define ERR_PNV 41 /*Argumentos validos para 38 6 o superior*/ #define ERR_LBL 42 /*No es posible definir etiq uetas*/ #define ERR_CTE 43 /*No es posible definir cons tantes*/ #define ERR_MPR 44 /*Mal uso de palabra reserva da*/ #define ERR_INP 45 /*Instruccion no valida en e ste modo*/ #define ERR_INR 46 /*Inctruccion no valida para este procesador*/ #define ERR_ORG 47 /*La nueva direccion es meno r a la actual*/ #define ERR_TPU 48 /*Cancelado por el usuario*/ #define ERR_AML 49 /*Array muy largo*/ /******************* HASTA AQUI LOS ERRORES ******* *************/ #define ERR_LSTERR 49 /*Tope maximo de errores des pues de este numero hay warnings*/ #define WAR_NDP 50 /*No se asigno tipo de proce sador, se fija: 8086*/ #define WAR_ES 51 /*Es posible que el numero s e tome con signo en la operacion*/ #define WAR_NAP 52 /*No se puede asignar otro p rocesador*/ /******************* HASTA AQUI LOS WARNINGS ****** *************/ #define ERR_LSTWAR 52 /*Tope maximo de errores des pues de este numero hay mensajes*/ #define MSG_NLE 53 /*Numero de lineas examinada s:*/ #define MSG_NLC 54 /*Numero de lineas compilada s:*/ #define MSG_NER 55 /*Numero de errores: */ #define MSG_NWA 56 /*Numero de warnings: */ #define MSG_DMM 57 /*Demasiados mensajes*/ #define MSG_LBL 58 /*LIBRE PARA USUARIO*/ #define MSG_SCA 59 /*Se cerro archivo en INCLUD E*/ #define MSG_SGS 60 /*Se generaron los siguiente s mensajes:*/ #define MSG_ACE 61 /*El archivo fue compilado c on exito*/ #define MSG_ACO 62 /*El archivo fue compilado*/ #define MSG_ANC 63 /*El archivo no fue compilad o*/ #define MSG_SGA 64 /*Se genero archivo .COM de longitud (bytes):*/ #define MSG_MEM 65 /*Memoria empleada:*/ /******************* HASTA AQUI LOS MENSAJES ****** *************/ /************************************************** *************/ /*Caracteres especiales*/ #define CHAR_PLUS 43 /*+*/ #define CHAR_COMA 44 /*,*/ #define CHAR_MENOS 45 /*-*/ #define CHAR_PIZQ 91 /*[*/ #define CHAR_PDER 93 /*]*/ #define CHAR_ESP 32 /* */

Page 281: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

276

#define CHAR_TAB 9 /* */ #define CHAR_AT 64 /*@*/ #define CHAR_2PUN 58 /*:*/ #define CHAR_PCOMA 59 /*;*/ #define CHAR_COMLL 34 /*"*/ #define CHAR_13 13 /*ENTER*/ #define CHAR_10 10 /*ENTER*/ #define CHAR_SLASH 92 /*\*/ #define CHAR_DOT 46 /*.*/ #define CHAR_STRING 36 /*$*/ #define CHAR_IGUAL 61 /*=*/ #define CHAR_MENOR 60 /*<*/ /*Bits de bandera para argumentos*/ #define IDARG_R08 0x0001 /*Registro de 8 bits*/ #define IDARG_R16 0x0002 /*Registro de 16 bits*/ #define IDARG_M08 0x0004 /*Direccion a memoria d e 8 bits*/ #define IDARG_M16 0x0008 /*Direccion a memoria d e 16 bits*/ #define IDARG_IM08 0x0010 /*Numero de 8 bits*/ #define IDARG_IM16 0x0020 /*Numero de 16 bits*/ #define IDARG_P 0x0040 /*Puntero SEG:OFF*/ #define IDARG_SEG 0x0080 /*Registro de segmento* / #define IDARG_FAR 0x0100 /*FAR*/ #define IDARG_PRE 0x0200 /*Prefijo de segmento*/ #define IDARG_R32 0x0400 /*Registro de 32 bits*/ #define IDARG_M32 0x0800 /*Direccion de memoria de 32 bits*/ #define IDARG_IM32 0x1000 /*Numero de 32 bits*/ #define IDARG_ 0x2000 /**/ #define IDARG_FILARG 0xFCFF /*Este es el filtro ent re argumentos, con & separa PRE y FAR*/ /*Bits de las banderas de direccionamiento*/ #define FDIR_N32 0x01 /*Numero de 32 bits*/ #define FDIR_SIG 0x02 /*Signo del numero 0=- y 1 =+*/ #define FDIR_N16 0x04 /*Numero de 16 bits*/ #define FDIR_N08 0x08 /*Numero de 8 bits*/ #define FDIR_DI 0x10 /*Registro de DI*/ #define FDIR_SI 0x20 /*Registro de SI*/ #define FDIR_BP 0x40 /*Registro de BP*/ #define FDIR_BX 0x80 /*Registro de BX*/ /*Constantes para codificadores de instrucciones e speciales y sin argumentos*/ #define DESI_NCOD 0x00 /*Numero de codigos*/ #define DESI_COD 0x01 /*Codigos*/ #define DESI_PROC 0x03 /*Procesador*/ /*Identificador del tipo de descriptor*/ #define DESCRIP_UN 0x00 /*Descriptor de instruccio nes de un argumento*/ #define DESCRIP_DOS 0x01 /*Descriptor de instruccio nes de dos argumento*/ /*Constantes para los descriptores de un y dos arg umentos*/ #define DESIA_POS 0x00 /*Posicion del codigo*/ #define DESIA_OPC 0x01 /*Numero de opciones*/ /*Las posiciones en la matriz de codigos de UNA IN ST*/ #define CI1A_POS_LEN 0 /*Bytes por Inst*/ #define CI1A_POS_COD 1 /*Codigos de instruccion */ #define CI1A_POS_RM 3 /*Los bits MOD/RM*/ #define CI1A_POS_CMPL 4 /*Posicion de comparacio n para obtener la instruccion*/ #define CI1A_POS_CMPH 5 /*Posicion de comparacio n para obtener la instruccion*/ #define CI1A_POS_EB 6 /*Byte extra de comparac ion*/ #define CI1A_POS_PROC 7 /*Tipo de procesador*/ /*Las posiciones en la matriz de codigos de DOS IN ST*/ #define CI2A_POS_LEN 0 /*Bytes por Inst*/ #define CI2A_POS_COD 1 /*Codigos de instruccion */ #define CI2A_POS_RM1 3 /*Los bits MOD/RM*/ #define CI2A_POS_RM2 4 /*Los bits MOD/RM*/ #define CI2A_POS_CMPL1 5 /*Posicion de comparacio n para obtener la instruccion Arg 1*/ #define CI2A_POS_CMPH1 6 /*Posicion de comparacio n para obtener la instruccion Arg 1*/ #define CI2A_POS_CMPL2 7 /*Posicion de comparacio n para obtener la instruccion Arg 2*/

Page 282: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

277

#define CI2A_POS_CMPH2 8 /*Posicion de comparacio n para obtener la instruccion Arg 2*/ #define CI2A_POS_EB1 9 /*Byte extra de comparac ion*/ #define CI2A_POS_EB2 10 /*Byte extra de comparac ion*/ #define CI2A_POS_PROC 11 /*Tipo de procesador*/ /*Definiciones dentro de la matriz de codigo de IU NARG*/ #define RM_D 0x80 /*Bit de numero como direccion / tomar 8 bits*/ #define RM_S 0x40 /*Suma los registros al codigo*/ #define RM_F 0x38 /*Filtro al RM*/ #define RM_C 0xC7 /*Inverso del filtro */ #define RM_A 0x02 /*Se emplea AND como comparador 1*/ #define RM_B 0x04 /*Se usa siguiente b yte para Reg o Seg*/ #define RM_N 0x01 /*No existen bits R/ M*/ #define RM_0 0x00 /*RM 0*/ #define RM_1 0x08 /*RM 1*/ #define RM_2 0x10 /*RM 2*/ #define RM_3 0x18 /*RM 3*/ #define RM_4 0x20 /*RM 4*/ #define RM_5 0x28 /*RM 5*/ #define RM_6 0x30 /*RM 6*/ #define RM_7 0x38 /*RM 7*/ /******** DEFINICIONES PARA LA TABLA DE INSTRUCCIO NES *************/ /*Identificadores de argumentos, son similares de IDARG_XXXX*/ #define COD_REG08 0x0001 /*Registro de 16 b its*/ #define COD_REG16 0x0002 /*Registro de 8 bi ts*/ #define COD_REG32 0x0400 /*Registro de 32 b its*/ #define COD_MEM08 0x0004 /*A memoria de 8 b its*/ #define COD_MEM16 0x0008 /*A memoria de 16 bits*/ #define COD_MEM32 0x0800 /*A memoria de 32 bits*/ #define COD_IMM08 0x0010 /*Numero inmediato de 8 bits*/ #define COD_IMM16 0x0020 /*Numero inmediato de 16 bits*/ #define COD_IMM32 0x1000 /*Numero inmediato de 32 bits*/ #define COD_SEG 0x0080 /*Registro de segm ento*/ #define COD_PUNTERO 0x0040 /*Puntero tipo SEG :OFFSET*/ /*Estos tienen mas de 2 bits encendidos*/ #define COD_FAR 0x0108 /*A puntero FAR*/ #define COD_rm08 0x0005 /*Registro/memoria de 8 bits*/ #define COD_rm16 0x000A /*Registro/memoria de 16 bits*/ #define COD_NUMH16 0x0030 /*Numero de 8 o 16 bits*/ #define COD_NUMH32 0x1030 /*Numero de 8, 16 o 32 bits*/ #define COD_rm32 0x0C00 /*Registro/memoria de 32 bits*/ #define COD_MEMORIA 0x080C /*A direccion de m emoria de 8, 16 o 32 bits*/ #define COD_NOOPER 0x0F0F /*Para indicar que no va hacer nada*/ /*Lo anterior, pero partidos en parte alta y baja*/ #define HCOD_REG32 0x04 /*Registro de 32 b its*/ #define HCOD_MEM32 0x08 /*A memoria de 32 bits*/ #define HCOD_IMM32 0x10 /*Numero inmediato de 32 bits*/ #define LCOD_NUMH16 0x30 /*Numero de 8, 16 bits*/ #define HCOD_NUMH16 0x00 /*Numero de 8, 16 bits*/ #define LCOD_NUMH32 0x30 /*Numero de 8, 16 o 32 bits*/ #define HCOD_NUMH32 0x10 /*Numero de 8, 16 o 32 bits*/ #define LCOD_MEM 0x0C /*A direccion de m emoria de 8, 16 y 32 bits*/ #define HCOD_MEM 0x08 /*A direccion de m emoria de 8, 16 y 32 bits*/ #define LCOD_FAR 0x08 /*A puntero far*/ #define HCOD_FAR 0x01 /*A puntero far*/ /*Estos separan bits*/ #define COD_MEM 0x080C /*Con & elimina lo s bits de registro, se usa en COD_rmXX*/ #define COD_REG 0x0403 /*Con & elimina lo s bits de memoria, se usa en COD_rmXX*/ /*Tipo de procesador*/ #define COD_NOPROC 0xFF /*No hay procesador*/ #define COD_P86 0x00 /*Procesador 86*/ #define COD_P186 0x01 /*Procesador 186*/ #define COD_P286 0x02 /*Procesador 286*/ #define COD_P386 0x03 /*Procesador 386*/ /************************************************** ****************/ /*Poscion general de los registros*/ #define REG_AX 0x00 /*AX*/ #define REG_CX 0x01 /*CX*/

Page 283: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

278

#define REG_DX 0x02 /*DX*/ #define REG_BX 0x03 /*BX*/ #define REG_SP 0x04 /*SP*/ #define REG_BP 0x05 /*BP*/ #define REG_SI 0x06 /*SI*/ #define REG_DI 0x07 /*DI*/ #define REG_AL 0x00 /*AL*/ #define REG_CL 0x01 /*CL*/ #define REG_DL 0x02 /*DL*/ #define REG_BL 0x03 /*BL*/ #define REG_AH 0x04 /*AH*/ #define REG_CH 0x05 /*CH*/ #define REG_DH 0x06 /*DH*/ #define REG_BH 0x07 /*BH*/ #define TOT_REG 0x08 /*8 registros de 16 y 8 bits */ #define SEG_ES 0x00 /*Registro ES*/ #define SEG_CS 0x01 /*Registro CS*/ #define SEG_SS 0x02 /*Registro SS*/ #define SEG_DS 0x03 /*Registro DS*/ #define SEG_FS 0x04 /*Registro FS*/ #define SEG_GS 0x05 /*Registro GS*/ #define TOT_SEG 0x04 /*Por lo pronto son solo 4 segmentos*/ #define CMP_REG 0xF0 /*Comparador de registro vs memoria en byte R/M*/ /*Posicion general para direccionamiento*/ #define DIR_OFF08 0x08 /*Offset de 8 bits*/ #define DIR_OFF16 0x04 /*Offset de 16 bits*/ /*Para asignar el BYTE/WORD PTR*/ #define PTR_NO 0x00 /*No coloca PTR*/ #define PTR_BYTE 0x01 /*BYTE PTR*/ #define PTR_WORD 0x02 /*WORD PTR*/ /*Para identificar el byte MOD R/M*/ #define MODRM_REG 0x00 /*Bits REG*/ #define MODRM_MRM 0x01 /*Bits Mod R/M*/ /*Para la instruccion ESC*/ #define ESC_COD_L 0x07 /*3 bits menos significativo s*/ #define ESC_COD_H 0x38 /*Los siguientes 3 bits*/ #define ESC_COD_R 0x03 /*Rotaci¢n*/ /*Error de referencia, debe agregar cualquie cosa* / #define ADD_REF_ERR 3 #endif

F.9 EDITOR.H #define Uses_TEditor #include <tv.h> #include <lib.h> class EDITOR : public TEditor public: byte bTextColor; EDITOR (const TRect& bounds, TScrollBar *aHScrol lBar, TScrollBar *aVScrollBar, TIndicator *anI ndicator, ushort usBufferSize); virtual void draw (); void drawLines (int y, int count, ushort linePtr ); void vFormatLine (void *DrawBuf, ushort *vNumCha r, ushort LinePtr, int Width, ushort Colors); virtual void handleEvent (TEvent& psteEvent); ;

F.10 EDIT188.H /*CONTIENE LAS DEFINICIONES PARA LA PARTE PRINCIPAL DEL DEPURADOR*/

Page 284: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

279

#include <lib.h> #include <stdio.h> #include "define.h" #include "newkey.h" //Archivo para eliminar los kb XXX de Turbo Vision //Zona de definiciones //Para las opciones del D188 #define ARCHIVO_OPTS "D188.OPT" //Nombre del archi vo de opciones del D188 //Para los numeros en dialogos (Se agrega un byte mas para el fin de cadena #define CHARNUM_DEC16 6 //Numero en decimal de 16 bits #define CHARNUM_HEX16 5 //Numero en hexadecimal de 16 bits //Banderas del D188 #define FLAG188_ACTAP 0x0001 //Archivo primario a ctivo #define FLAG188_CARGA 0x0002 //Se cargo a UAMI188 #define FLAG188_SELEC 0x0004 //Hay archivo selecc ionado #define FLAG188_CHINS 0x0008 //Se modifico una in struccion //Banderas del editor #define FLAGEDIT_AI 0x01 //AutoIdent #define FLAGEDIT_Mm 0x02 //MAYUSCULAS/minusculas #define FLAGEDIT_RE 0x04 //Resalta el texto //Banderas Generales #define FLAGGRAL_MAP 0x01 //Crear archivo MAP #define FLAGGRAL_UAM 0x02 //Verificar UAMI188EB a l inicio //Para la ventana de registros del depurador #define DBGREG_NUMREG 14 //Numero de registros a imprimir #define DBGREG_LENREG 12 //Longitud de los regist ros #define DBGREG_POSVAL 6 //Posicion donde inicia el valor #define DBGREG_NUMDIG 4 //Numero de digitos #define DBGREG_AX 0x00 //Posicion de los regist ros, segun la tabla #define DBGREG_BX 0x01 #define DBGREG_CX 0x02 #define DBGREG_DX 0x03 #define DBGREG_DI 0x04 #define DBGREG_SI 0x05 #define DBGREG_BP 0x06 #define DBGREG_SP 0x07 #define DBGREG_DS 0x08 #define DBGREG_ES 0x09 #define DBGREG_SS 0x0A #define DBGREG_CS 0x0B #define DBGREG_IP 0x0C #define DBGREG_FLAG 0x0D //Definicion de la bandera MAY/min del teclado #define FLAG_KEY_Mm 0x40 //Definicion para el video #define VIDEO_BN 0x00 //Blanco y negro 80x25 #define VIDEO_CO 0x01 //Color 80x25 #define VIDEO_COE 0x02 //Color 80x(43 ¢ 50) //Clases empleadas class TMenuBar; class TStatusLine; class EDITWINDOW; class TDialog; class RELOJ; class INDICADOR; class MENSAJES; class TXTWINDOW; class DEBUGWINDOW; #ifdef MAIN_EDITD188 //ES CONVIENTE QUE ESTE ORDEN SEA EL MISMO QUE PAR A EL BUFFER DE

Page 285: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

280

//REGISTROS DE LA UAMI188EB. SI SE MODIFICA LA POS ICION AQUI EN ALGUN //REGISTRO, ES NECESARIO MODIFICAR EN EL ARCHIVO B IOSVARS.ASM EDITWINDOW *psTEWClipWindow; ushort USFlagEditores; //Banderas para los editor es, NO TOCAR char sCRegWindow[] = " AX = 0000H " //Para los registros " BX = 0000H " " CX = 0000H " " DX = 0000H " " DI = 0000H " " SI = 0000H " " BP = 0000H " " SP = 0000H " " DS = 0000H " " ES = 0000H " " SS = 0000H " " CS = 0000H " " IP = 0000H " " FG = 0000H " ; #else extern char sCRegWindow[]; extern EDITWINDOW *psTEWClipWindow; extern ushort USFlagEditores; #endif typedef struct EDITFILE efile; typedef struct OPCIONES opt; typedef struct ADDINST addi; typedef struct CHGREG chkr; typedef struct LEERMEMUAMI188 lmuami; typedef struct MOVERMEMUAMI188 mmuami; typedef struct CARGAMEMUAMI cmuami; typedef struct SETLEERMEMUAMI188 slmuami; typedef struct CHGVALMEM chkm; /*Estructuras*/ struct EDITFILE /*Estructura de un archivo en el editor*/ EDITWINDOW *pstewF; //Apuntador al archivo char *pcFileName; //Apuntador al nombre de a rchivo ushort usCont; //Contador ; //En las siguientes estructuras es importante la p osicion de los elementos struct OPCIONES //Opciones del D188 ushort usPuerto; //Puerto serie ushort usVelocidad; //Velocidad de tr anmision char scPathEXE[MAXPATH]; //Path donde se c oloca el .COM char scBytesCom[CHARNUM_DEC16]; //Bytes para com pilar char scBytesVar[CHARNUM_DEC16]; //Bytes para var iables char scBytesDep[CHARNUM_DEC16]; //Bytes para Dep urar char scBytesVol[CHARNUM_DEC16]; //Bytes para vol cado de memoria char scNumMsg[CHARNUM_DEC16]; //Numero de mensa jes permitidos char scSegundos[CHARNUM_DEC16]; //Segundos de e spera en el puerto ushort usVideo; //Seleccion del v ideo ushort usGeneral; //Opciones genera les ushort usFlagEditor; //Opciones de la ventana de opciones ; //La estructura OPCIONES contiene informacion en t odo momento del sistema; //sin embargo, es conveniente no emplearla como fu ente de informacion. La //estructura solo debe ser usada como medio de cap tura de informacion, si //se desea consultar alguna informacion, es necesa rio emplear las variables //correspondientes y no los valores de la estructu ra. struct ADDINST //Para agregar una instruccion ushort usOpt; //Insertar o remplazar el codigo char scInst[MAX_LEN_CAD]; //La instruccion, del tama¤o maximo de cadena ;

Page 286: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

281

struct CHGREG //Para cambiar un registro char scReg[CHARNUM_HEX16]; //Valor del registro ; struct LEERMEMUAMI188 //Lee memoria de la UAMI188 char scOffSet[CHARNUM_HEX16]; char scNumBytes[CHARNUM_DEC16]; char scSegmento[CHARNUM_HEX16]; ; struct MOVERMEMUAMI188 //Mover memoria de la UAMI 188 char scIOffSet[CHARNUM_HEX16]; char scFSegmento[CHARNUM_HEX16]; char scFOffSet[CHARNUM_HEX16]; char scNumBytes[CHARNUM_DEC16]; char scISegmento[CHARNUM_HEX16]; ; struct CARGAMEMUAMI //Para cargar desde memoria ( Debug->UAMI188) char scFin[CHARNUM_HEX16]; //Fin de memoria char scInicio[CHARNUM_HEX16]; //Inicio de memor ia ; struct SETLEERMEMUAMI188 //Valores de memoria a l eer de la UAMI188 char scOffSet[CHARNUM_HEX16]; char scNumBytes[CHARNUM_DEC16]; ushort usActivo; char scSegmento[CHARNUM_HEX16]; ; struct CHGVALMEM //Cambio de valores en memoria d e la UAMI188EB char scOffSet[CHARNUM_HEX16]; char scValor[MAX_LEN_CAD]; char scSegmento[CHARNUM_HEX16]; ; //Declaracion de las clases empleadas en el depura dor class DUAMI188 : public TApplication private: byte *pbBuffVolMem; //Puntero a el volcado de m emoria word wTamVolMem; //Tama¤o del volcado word wDUAMI188Flag; //Banderas del objeto word wEsperaPuerto; //Segundos de espera del pu erto word wBufferCS; //Buffer para guardar el regist ro CS RELOJ *psReloj; //Reloj INDICADOR *psIndica; //Indicador de comunicacio n DEBUGWINDOW *psdwDWin; //Ventana de depuracion MENSAJES *psmMsg; //Ventana de mensajes TXTWINDOW *pstwMsgUAMI; //Mensajes de conexion de la UAMI TXTWINDOW *pstwMsgComp; //Mensajes al momento d e compilar TCommandSet stcArchivo; //Comandos del editor, para activar y desactivar TCommandSet stcWindow; //Comandos de las ventan as, para activar y desactivar TCommandSet stcCompilar; //Comandos de compilac ion TCommandSet stcDebug; //Comandos del debug TCommandSet stcCarga; //Comandos de carga a UAM I TCommandSet stcMemoria; //Comandos para acceso a memoria de la UAMI TCommandSet stcEjecutar; //Comandos de ejecucio n opt soOpciones; //Opciones del editor lmuami slmuLMU; //Leer memoria de la UAMI188 lmuami slmuLPU; //Leer programa de la UAMI188 mmuami smmuMMU; //Mover memoria de la UAMI188 cmuami scmuCMU; //Cargar memoria de la UAMI188

Page 287: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

282

slmuami slmuSLMU; //Lectura de memoria al depur ar char scArchPrimario[MAXPATH]; //Nombre del arch ivo primario char scArchUAMI[MAXPATH]; //Archivo que se carg a en UAMI char scDirFuenteOPT[MAXPATH]; //Directorio del ejecutable y del archivo de opciones public: //EDIT188A.CPP DUAMI188(int iArg, char **pscArg); virtual void handleEvent (TEvent &psteEvent); virtual void idle (); ~DUAMI188 (); //EDIT188C.CPP static TMenuBar *initMenuBar (TRect); static TStatusLine *initStatusLine (TRect); virtual void outOfMemory(); void vAcercaDe(); private: //EDIT188A.CPP EDITWINDOW *pstewAbrirEditor (const char *fileNa me, Boolean visible); void vAbrirArchivo (); void vNuevoArchivo (); void vCambiarDir (); void vDOSShell(); void vMostrarClip (); void vMosaico (); void vCascada (); //FUNCION.CPP byte bIniciaASMMAQ (); TView *pstvPrimeraVentana (Boolean (*bFun)(TView *, void *), void *pvArgs); TView *pstvBuscaVentanaArch (char *pcArch); EDITWINDOW *pstewObtenTopEditor (); void vCompilar (byte bDisk); int iSetArchivoPrimario (); void vCerrarTodo (); void vGuardarTodo (); //COMPILAE.CPP void vCompilaArchivo (char *pcFile, efile *psefA ux, byte bDisk); //DIALOGOS.CPP void vOpcionesDialog (); void vActualizaEditores (); void vAgregaInstruccionDialog (); void vCambiaRegistroDialog (); void vLeerMemoriaUAMI188Dialog (); void vLeerProgramaUAMI188Dialog (); void vMoverMemoriaUAMI188Dialog (); void vCargaMemoriaUAMIDialog (); void vSetLeerMemoriaDialog (); void vCambiaMemoriaDialog (); //UAMI188.CPP byte bChkConexion (); void vReiniciaUAMI (); void vSelecCargaUAMI (); void vLeerMemoriaUAMI188 (word wSeg, word wOffSe t, word wNBytes, void *pvMem); void vLeerRegistrosUAMI188 (); void vMoverMemoriaUAMI188 (word wISeg, word wFSe g, word wIOffSet, word wFOffSet, word wNBytes); void vCargaProgramaArchivoUAMI (); void vCargaProgramaUAMI (word wInicio, word wFin al); void vEjecutaPasoPaso (); void vEjecutar (); void vLeerRetorno (); void vLeerError (); void vDetenerEjecucion (); void vCargaRegistro (byte bReg); void vCargaMemoria (word wSeg, word wOff, word w NBytes, byte *pbDatos); void vFijaHoraUAMI188EB (); byte bEnviaEsperaDato (byte bSend); void vFalloConexion (); byte bEsperaTransDato (byte *pbDato); byte bEnviaComandoEstado (byte bDatoSend); byte bEsperaDatoCola (byte *pbDato, word wTmp); void vDepuradorVolcado (word wSeg, word wOffSet) ;

Page 288: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

283

//FUNDEBUG.CPP void vCargaFileDebug (); void vAbrirMAP (); ; //EDIT188B.CPP ushort usEjecutarDialogo (TDialog *pstdD, void *pv Data); TDialog *pstdBuscarDialogo (); TDialog *pstdReplazarDialogo (); //EDIT188C.CPP ushort usDialogosEdicion (int dialog, ...); //COMPILAE.CPP byte bObtenLineaCod (char *pcText, FILE *psfIn, ef ile *psefIn, word *pwLin); byte bCreaEditFile (efile *psefF, EDITWINDOW *pste wAux); void vAsignaEditFile (efile *psefF1, efile *psefF2 ); char *pcEditFile (efile *psefF); byte befof (efile *psefAux); byte bEFValido (efile *psefAux); char cGetc (efile *psefAux); void vResetPunteros (FILE *psfIn, efile *psefIn); //FUNCION.CPP void vEsperaEvento (); //REGISTRO.CPP void vIniciaRegistros (); void vCambiaRegistro (byte bReg, word wVal); word wObtenRegistro (byte bReg); //UAMI188.CPP void vContadorEspera ();

F.11 EWLST.H /*CONTIENE TODOS LOS MENSAJES DE ERRORES O WARNINGS DEL COMPILADOR*/ #include "define.h" char sCError[][MAX_LENMSG] = "No hay error", "Cadena demasiado larga", "No hay memoria suficiente", "Cadena o instruccion no validas", "Error en instruccion o en etiqueta", "Operadores no validos", "Se esperaba un numero", "Mal uso de instruccion", "Existe un archivo en espera", "Se espera instruccion de cadena", "Falta argumento(s)", "Mal uso de argumento(s)", "Mal uso de registro de segmento", "Se esperaba parentesis [", "Mal uso de operador", "Argumento no valido", "Solo un numero a la vez", "Caracter no valido", "Instruccion no valida", "Se esperaba PTR", "Registro repetido", "Argumentos no validos en instruccion", "Error al leer archivo", "Se esperaba ,", "Mal uso de instruccion", "Direccionamiento no valido", "Mal uso de FAR", "Imposible usar dos localidades de memoria a la vez", "Imposible usar dos numeros a la vez", "Mal uso de una direccion", "No se puede abrir archivo a compilar", "No se puede abrir archivo en INCLUDE", "No se puede crear archivo de salida (.COM)", "Numero no valido", "No se puede resolver referencia",

Page 289: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

284

"Falta cerrar comillas", "Referencia no valida o falta", "Nombre de constante o etiqueta ya asignado", "Se espera EQU o :", "Valida solo como primera instruccion", "No es posible un mayor anidamiento en archivos INCLUDE", "Argumentos validos para 386 o superior", "No es posible definir etiquetas", "No es posible definir constantes", "Mal uso de palabra reservada", "Instruccion no valida en este modo", "Instruccion no valida para este procesador", "La nueva direccion es menor a la actual", "Cancelado por el usuario", "Array muy largo", /*Despues de esta linea se definen los warnings, si se agrega un*/ /*nuevo error, hay que modificar ERR_LSTERR en d efine.h */ "No se asigno tipo de procesador, se fija: 8086" , "Es posible que el numero se tome con signo en l a operacion", "No se puede asignar otro procesador", /*Despues de esta linea se definen los mensajes, si se agrega un*/ /*nuevo error, hay que modificar ERR_LSTWAR en d efine.h */ "Numero de lineas examinadas:", "Numero de lineas compiladas:", "Numero de errores: ", "Numero de warnings: ", "Demasiados mensajes", "Se abrio archivo INCLUDE: ", "Se cerro archivo en INCLUDE", "LISTA DE MENSAJES GENERADOS:", "El archivo fue compilado con exito", "El archivo fue compilado", "El archivo no fue compilado", "Se genero archivo .COM de longitud (bytes):", "Memoria empleada:" ;

F.12 FILEEDIT.H #include <lib.h> #include "editor.h" class FILEEDITOR : public EDITOR public: char fileName[MAXPATH]; FILEEDITOR (const TRect&, TScrollBar *, TScrollB ar *, TIndicator *, const char *); byte FILEEDITOR::bEsArchivoASM (); virtual void doneBuffer(); virtual void handleEvent( TEvent& ); virtual void initBuffer(); Boolean loadFile(); Boolean save(); Boolean saveAs(); Boolean saveFile(); virtual Boolean setBufSize( ushort ); virtual void shutDown(); virtual void updateCommands(); virtual Boolean valid( ushort ); private: char backupExt[10]; byte bEsASM; //Inidica si el archivo abier to es fuente ;

F.13 INDICA.H /*CONTIENE LAS DEFINICIONES PARA EL RELOJ EN EL DEP URADOR*/ #define Uses_TRect

Page 290: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

285

#define Uses_TView #include <tv.h> #include <lib.h> //Estados de la UAMI188EB const INDICA_OK = 0x00, //La UAMI188EB esta esperando un programa INDICA_STP = 0x01, //Hay programa detenido INDICA_RUN = 0x02, //Programa ejecutandose INDICA_DBG = 0x04, //Trazando programa INDICA_DSC = 0x08, //UAMI188EB desconectada INDICA_UKN = 0x10; //Estado desconocido class INDICADOR : public TView private: byte bEstado; public: INDICADOR (TRect& pstrR); virtual void draw(); void vIndicador (byte bInc); byte bObtenIndicador (); ;

F.14 INPUTNUM.H /*Archivo con la definicion de la ventana de mensa jes*/ #define Uses_TEventQueue #define Uses_TEvent #define Uses_TInputLine #include <tv.h> #include <lib.h> #define INPUTNUM_DEC 0 #define INPUTNUM_HEX 1 #define INPUTNUM_BIN 2 class INPUTNUM : public TInputLine //Clase venta na de mensajes private: char cTipoNum; public: INPUTNUM (const TRect& pstrR, int iMaxLen, char cTipo); virtual void handleEvent(TEvent& event); ; dword dConvierteCadNum (char *pcCad, char cTipo);

F.15 MAXIMO.H //CONTIENE LAS CONSTANTES QUE DEFINEN VALORES MAXIMOS #define MAX_BYTES_COMP 0x0400 //1Kb #define MAX_BYTES_DEBUG 0xD000 //52Kb #define MAX_BYTES_VAR 0xD000 //32Kb #define MAX_BYTES_VOLM 0x4000 //16Kb #define MAX_NUM_MENSAJES 0xFA //250 mensajes como maximo

F.16 MENSAJE.H /*Archivo con la definicion de la ventana de mensa jes*/ #define Uses_TEventQueue #define Uses_TEvent #define Uses_TProgram

Page 291: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

286

#define Uses_TApplication #define Uses_TKeys #define Uses_TRect #define Uses_TMenuBar #define Uses_TSubMenu #define Uses_TMenuItem #define Uses_TStatusLine #define Uses_TStatusItem #define Uses_TStatusDef #define Uses_TDeskTop #define Uses_TView #define Uses_TWindow #define Uses_TScroller #define Uses_TScrollBar #include <tv.h> #include <lib.h> /*Esta clase emplea las variables de las constante s, pero no las modifica*/ /*directamente, ya que hace uso de las funciones e n el archivo */ /*ERROR.H */ class SCROLLMSG : public TScroller //Scroll de la ventana de mensaje private: word wMaxLineas; //Numero maximo de lineas int iPosCur; //Posicion del cursor (en numero de mensajes), inicia en 0 public: SCROLLMSG (const TRect& bounds, TScrollBar *aHSc rollBar, TScrollBar *aVScrollBar ); virtual void draw(); virtual void handleEvent(TEvent& psteEvent); inline void vCambiaVScroll (int iPos); ; class MENSAJES : public TWindow //Clase ventana d e mensajes private: SCROLLMSG *pstsmScroll; public: MENSAJES (const TRect& bounds); ~MENSAJES (); void vCreaInterior(); virtual void close (); //Para que no se cierre, solo la oculta void vCerrar (); //Cierra la ventana definitiva mente void vMostrar (); //Muestra la ventana de mensa jes ;

F.17 NEWKEY.H //ESTE ARCHIVO CONTIENE LOS CODIGOS DE ESCANEO DE L A TECLAS EMPLEADAS const nkbCtrlM = 0x320D, nkbCtrlD = 0x2004, nkbCtrlS = 0x1F13, nkbCtrlP = 0x1910, nkbCtrlL = 0x260C, nkbCtrlA = 0x1E01, nkbCtrlI = 0x1709, nkbCtrlR = 0x1312, nkbCtrlX = 0x2D18, nkbCtrlV = 0x2F16, nkbCtrlC = 0x2E03, nkbCtrlBack = 0x0E7F, //Las teclas que se emplean en MAY/min kbPtoComa = 0x333B, //Caracter ; kbDbComilla = 0x0322, //Caracter "

Page 292: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

287

nkbNone = 0xFFFF;

F.18 PSERIE.H //CONTIENE EL CODIGO PARA EL MANEJO DEL PUERTO SERI E #include <lib.h> #define LEN_COLA_SERIAL 64 //Tama¤o de la cola pa ra recepcion #define INT_MAXENTRADAS 100 //Maximo numero de ent radas en INT despues de cola llena //Los puertos #define COMM1 0 //Puerto COM 1 #define COMM2 1 //Puerto COM 2 #define DIRCOM1 0x03F8 //Direccion del puerto COM1 #define DIRCOM2 0x02F8 //Direccion del puerto COM2 #define IRQCOM1 0x04 //IRQ para COM1 #define IRQCOM2 0x03 //IRQ para COM1 //Selecion de bit de paridad y bit de parada #define COM_SINPARIDAD 0x00 //Sin paridad #define COM_PARIDADPAR 0x18 //Con paridad p ar #define COM_PARIDADIMPAR 0x08 //Con paridad i mpar #define COM_PARIDADPARSTICK 0x38 //Paridad par c on stick bit #define COM_PARIDADIMPARSTICK 0x28 //Paridad impar con stick bit #define COM_STOPBIT 0x04 //1 bit de para da #define COM_NOSTOPBIT 0x00 //0 bit de para da //Numero de bits #define COM_6_BITS 6 #define COM_7_BITS 7 #define COM_8_BITS 8 //Para la interrupcio #define INTSER_NONE 1 #define INTSER_ERROR 6 #define INTSER_RECDAT 4 #define INTSER_TIMEOUT 12 #define INTSER_TRANS 2 #define INTSER_MODEM 0 //Estas son algunas constantes para accesar a los registros de la UART #define RBR 0 #define THR 0 #define IER 1 #define IIR 2 #define FCR 2 #define LCR 3 #define MCR 4 #define LSR 5 #define MSR 6 #define SCR 7 #define DLL 0 #define DLM 1 #define PT8259 0x20 //Puerto del 8259 (controlado r de interrupciones) #define OCW1 1 #define OCW2 0 #define BASE_IRQ 8 //Se le agrega a la interrupc ion ya qu es IRQ+8 //Velocidad del puerto #define COMVEL_1200 0 #define COMVEL_2400 1 #define COMVEL_4800 2 #define COMVEL_9600 3 #define COMVEL_19200 4 #ifdef MAIN_SERIAL byte sbCola[LEN_COLA_SERIAL+4]; //Cola circular p ara recepcion

Page 293: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

288

byte bInicioCola; //Posicion de inicio de cola byte bFinCola; //Fin de inicio de cola word wDirPuerto; //Direccion del puerto byte bNumIRQ; //Numero de interrupcion IRQ + BASE _IRQ byte bInterrupcion; //Indica si la interrupcion e sta activa o no void interrupt (*ViVectAnt)(...); //Codigo de int errupcion anterior byte bContadorEmerg; //Contador emergente, funcio na cuando se reciben muchas interrupciones #endif void vIniciaPuertoSerie (byte bCOM, byte bNumBits, byte bStopBits, byte bParidad, byte bVel); void vTerminaPuertoSerie (); byte bEnviaDato (byte bDato); //Envia dato byte bRecibeDato (byte *pbDato); //Recibe dato s in interrupcion void vInterrupcionPtoSerie (byte bFlag); //Activa /Desactiva interrupcion byte bEstadoInterrupcion (); //Muestra el estado de la interrupcion byte bObtenDatoCola (byte *pbDato); //Obtiene el dato de la cola byte bAgregaCola (byte bDato); //Agrega un dato a la cola byte bColaLlena (); //Verifica que la cola este l lena byte bColaVacia (); //Verifica si la cola esta va cia byte bNumeroElementos (); //Numero de elementos e n la cola void bLimpiaCola (); //Elimina los elementos de l a cola void interrupt viInterrupcionSerieRecev (...); // Interrupcion del puerto serie void vCambiaVelocidad (byte bVel); //Cambia la ve locidad void vLimpiaPuerto (); //Limpia el puerto de basu ra byte bLeeEstado (); //Estado del puerto serie

F.19 RELOJ.H /*CONTIENE LAS DEFINICIONES PARA EL RELOJ EN EL DEP URADOR*/ #define Uses_TRect #define Uses_TView #include <tv.h> class RELOJ : public TView public: RELOJ (TRect& pstrR); virtual void draw(); virtual void update(); private: char scLTime[9]; char scCTime[9]; ;

F.20 TEDITWND.H #define Uses_TEditor #define Uses_TWindow #include <tv.h> #include <lib.h> class EDITOR; class FILEEDITOR; static const char sCClipboardTitle[] = "Clipboard" ; static const char sCUntitled[] = "Sin titulo"; class EDITWINDOW : public TWindow public: EDITWINDOW (const TRect&, const char *, int); virtual void close(); virtual const char *getTitle( short ); virtual void handleEvent (TEvent& psteEvent); virtual void sizeLimits (TPoint& min, TPoint& ma x); FILEEDITOR *pfeFEditor; private: ;

Page 294: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

289

F.21 TIMER.H //ENCABEZADO DEL ARCHIVO TIMER.CPP #ifdef MAIN_TIMER word WTmrContadorSeg; byte BTmrFlag; void interrupt (*VIVectAntTemp)(...); #endif #define TEMP_INT 0x1C //Interrupcio del tempor izador #define TEMP_MAXSEG 3600 //Maxima cantidad de seg undos void vIniciaTemporizador (); //Inicia el temporiz ador para conteo void vTerminaTemporizador (); //Termina el tempor izador void interrupt viInterrupcionNuevoTemp (...); //E l temporizador void vFijaTemporizador (word wSeg); //Fijamos los segundos a contar byte bChkTemporizador (); //Retorna TRUE cuando s e ha alcanzado la cuenta

F.22 TXTWIN.H /*Archivo con la definicion de la ventana de mensa jes*/ #define Uses_TEventQueue #define Uses_TEvent #define Uses_TProgram #define Uses_TApplication #define Uses_TKeys #define Uses_TRect #define Uses_TMenuBar #define Uses_TSubMenu #define Uses_TMenuItem #define Uses_TStatusLine #define Uses_TStatusItem #define Uses_TStatusDef #define Uses_TDeskTop #define Uses_TView #define Uses_TWindow #define Uses_TScroller #define Uses_TScrollBar #include <tv.h> #include <lib.h> class TXTWINDOW : public TWindow //Clase ventana de mensajes private: byte bLX; /*Longitud en X*/ byte bLY; /*Longitud en Y*/ public: TXTWINDOW (const TRect& pstrR, const char *pcTit le, short sPalette); void vImprimeText (byte bX, byte bY, char *pcTex t, ushort usAtt); //Imprime texto void vImprimeNum (byte bX, byte bY, byte bBase, dword dNum, ushort usAtt); //Imprime un numero void vImprimeNFile (byte bX, byte bY, char *pcTe xt, ushort usAtt); //Imprime nombre de archivo void vImprimeChar (byte bX, byte bY, char cChar, ushort usAtt); //Imprime un caracter void vLimpiaVentana (); void vLimpiaRenglon (byte bLY); void vMuestra (); ;

F.23 COD2MAQ.CPP #include <stdio.h> #include <stdlib.h> #include <string.h> #include <malloc.h> #include <ctype.h>

Page 295: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

290

#include <lib.h> #include "define.h" #include "asmmaq.h" int iIniciaASM (word wMEM, word wLBLCTE, word wMax Msg) /*WConstASM Ya se debio haber iniciado*/ psLEtiqueta = CERO; /*Ninguna etiqueta definida */ psIInstruccion = CERO; /*Ninguna instruccion po r compilar*/ BProcesador = COD_NOPROC; /*Por default no hay procesador*/ pWLineas = CERO; /*Lineas del ensamblador*/ BNumMensajes = CERO; /*Numero de mensajes intro ducidos*/ pWMensajes = CERO; /*Mensajes*/ BNumErrores = CERO; /*Numero de errores*/ BNumWarnings = CERO; /*Numero de warnings*/ vCargaDescriptores (); /*Descriptores de codigo* / pCInclude = CERO; /*Memoria de nombre de archiv o en INCLUDE*/ WContInstLBL = CERO; /*Contador de instruccione s y etiquetas*/ psINCInclude = CERO; /*No hay archivo INCLUDE*/ psINCActual = CERO; /*Para uso de archivos incl ude*/ BTotalMensajes = LBYTE(wMaxMsg); /*Numero de me nsajes permitidos*/ return (iIniciaMem(wMEM, wLBLCTE, wMaxMsg+2)); /*Carga la memoria*/ void vTerminaASM () /*Termina ensamblador, libera memoria y demas re cursos*/ vTerminaMem (); /*Primer libera la memoria*/ /*La palabra baja es el error y la alta la posicio n */ /*Parametros: (Codigo en ASM, Codigo MAQU, Pos Ref er)*/ /*Codigo MAQU es con el formato: */ /* */ /*En la posicion LEN_COD esta la longitud del codi go */ /*los bytes siguientes son el codigo; esta variabl e */ /*debe tener al menos 130 bytes, ya que hay */ /*instrucciones que pueden emplear esta longitud. */ word wASM2MAQ (char *pcText, byte *pbCod, word *pw Ref, word wLin) word wLen=0, wRet, x, y; nodo *psnLista; wRet = ERR_NE; *(pbCod+LEN_COD) = CERO; /*La longitud del codi go es cero*/ /*NO TOCAR EL BIT CTEASM_SAVEI EN WConstASM, USO INTERNO*/ WConstASM = CLSBIT (WConstASM, CTEASM_SAVEI); / *No guarda la instruccion*/ wRet = wM_LenCad (&wLen, pcText); if (wRet) return (wRet); if (!wLen) return (ERR_NE); /*Cadena vacia, no hay error*/ vLiberaMem (); /*Libera la memoria de los token s*/ wRet = wObtenTokens (&psnLista, pcText, wLen+1); if ((wRet)||(!psnLista)) return (wRet); /*Si no hay error se obtuvo la lista*/ if (psnLista->bTipo!=ID_RESWORD) /*Ya se definio procesador?*/ if (BProcesador==COD_NOPROC) wRet = iAddMensaje (WAR_NDP, CERO); /*Agreg a mensaje y continua*/ BProcesador = COD_P86; /*Procesador default */ WConstASM = SETBIT(WConstASM, CTEASM_NO1INST); /*Ya no es primera instruccion*/ if (TSTBIT(WConstASM, CTEASM_SAVEI)) /*Se guard a la instruccion, pero no en segunda pasda*/ if (!TSTBIT(WConstASM, CTEASM_2PASO)) /*Segun do paso no puede guardar, es error*/ return (wAddInstruccion (pcText, wLen, *pwRe f, wLin)); else return (ERR_EER); /*No existe la referen cia*/ switch (psnLista->bTipo) case ID_INOARG: /*Instrucciones sin argumentos */ wRet = wCodINoArg (pbCod, psnLista->bNumTipo ); if (!wRet) if (psnLista->psnSig) wRet = CREAWORD (psn Lista->bPos, ERR_ONV); /*Ya no debe haber mas en la lista*/ break;

Page 296: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

291

case ID_IUNARG: /*Instrucciones de un argument o*/ wRet = wCodIUnArg (psnLista, pbCod, *pwRef); break; case ID_IDOSARG: /*Instrucciones de dos argume ntos*/ wRet = wCodIDosArgs (psnLista, pbCod, wLin); break; case ID_IESP: /*Instrucciones especiales*/ wRet = wCodIEsp (psnLista, pbCod); break; case ID_RESWORD: /*Palabra reservada*/ wRet = wCodResWord (psnLista, pbCod, pcText, pwRef, wLin); break; case ID_LBLCTE: /*Se procesan constantes y et iquetas*/ /*Solo se agragan constantes y etiquetas*/ if (!TSTBIT(WConstASM, CTEASM_2PASO)) /*Segu ndo paso, no se agregan LBL ni CTE*/ wRet = wCodEtiqueta (psnLista, pcText, *pw Ref); break; default: /*Se espera instruccion, etiqueta o c onstante*/ wRet = CREAWORD (psnLista->bPos, ERR_EIE); break; if (wRet!=ERR_NE) *(pbCod+LEN_COD) = CERO; return (wRet); byte bFinCompilacion () /*Retorna TRUE si hay errores o ya esta en segun do paso*/ /*Si es segundo paso, debe salir*/ WConstASM = CLSBIT (WConstASM, CTEASM_NO1INST); BProcesador = COD_NOPROC; /*No hay procesador*/ if (TSTBIT(WConstASM, CTEASM_2PASO)) /*Fin de compilacion, libera las etiquetas emp leadas*/ WConstASM = CLSBIT(WConstASM, CTEASM_2PASO); WConstASM = CLSBIT(WConstASM, CTEASM_NOREF); return (TRUE); if (NUMERO_ERR()) return (TRUE); WConstASM = SETBIT (WConstASM, CTEASM_2PASO); / *Fija el segundo paso*/ return (FALSE); void vIniciaCompilacion () /*Inicia las variables necesarias para compilar* / vResetMensajes (); //Limpia los mensajes vLiberaLBLCTE (); /*Libera memoria de constante s, instrucciones y etiquetas*/ WConstASM = CLSBIT (WConstASM, CTEASM_NO1INST); BProcesador = COD_NOPROC; /*No hay procesador*/ WConstASM = CLSBIT(WConstASM, CTEASM_2PASO); WConstASM = CLSBIT(WConstASM, CTEASM_NOREF); WConstASM = CLSBIT(WConstASM, CTEASM_NESTFILE); WConstASM = CLSBIT(WConstASM, CTEASM_SAVEI); byte bEsSegundoPaso () /*Retorna TRUE si ya se esta cumpliendo el segun do paso*/ if (TSTBIT(WConstASM, CTEASM_2PASO)) return (TRU E); return (FALSE); byte bEsSETREF () if (TSTBIT(WConstASM, CTEASM_SETREF)) WConstASM = CLSBIT (WConstASM, CTEASM_SETREF); return (TRUE); return (FALSE); char *pcEsArchivoINCLUDE () /*Regresa el nombre del archivo INCLUDE*/

Page 297: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

292

if (!TSTBIT(WConstASM, CTEASM_NESTFILE)) return (CERO); WConstASM = CLSBIT (WConstASM, CTEASM_NESTFILE); /*Se le hizo caso*/ return (pCInclude); word wCodINoArg (byte *pbCod, byte bNumTipo) /*Decodificacion de instrucciones sin argumentos */ int x; for (x=LEN_COD; x<=sBCodIntNoArgs[bNumTipo][DESI _NCOD]; x++) *(pbCod+x) = sBCodIntNoArgs[bNumTipo][x]; if (sBCodIntNoArgs[bNumTipo][DESI_PROC]>BProcesa dor) return (ERR_INR); return (ERR_NE); word wCodIEsp (nodo *psnLista, byte *pbCod) /*Decodificacion de instrucciones especiales*/ word wRet, x, y; wRet = ERR_NE; if (sBCodInstEspe[psnLista->bNumTipo][DESI_PROC] >BProcesador) return (ERR_INR); if (psnLista->bNumTipo<ID_IESP_C) /*Para REPXXX*/ for (x=LEN_COD; x<=sBCodInstEspe[psnLista->bNu mTipo][DESI_NCOD]; x++) *(pbCod+x) = sBCodInstEspe[psnLista->bNumTip o][x]; psnLista = psnLista->psnSig; if (!psnLista) return (wRet); if (psnLista->bTipo!=ID_IESP) wRet = CREAWORD (psnLista->bPos, ERR_SIC); else if (psnLista->bNumTipo>=ID_IESP_E) wRet = CREAWORD (psnLista->bPos, ERR_SIC); /*se espera MOVS, etc*/ else for (y=x, x=1; x<=sBCodInstEspe[psnLista-> bNumTipo][DESI_NCOD]; x++, y++) *(pbCod+y) = sBCodInstEspe[psnLista->bNu mTipo][x]; *(pbCod+LEN_COD) = y - 1; else if (psnLista->bNumTipo<ID_IESP_E) /*MOVSX, SCA SX, etc*/ for (x=LEN_COD; x<=sBCodInstEspe[psnLista->b NumTipo][DESI_NCOD]; x++) *(pbCod+x) = sBCodInstEspe[psnLista->bNumT ipo][x]; else wRet = CREAWORD (psnLista->bPos, ERR_MUI) ; /*Se espera REPx*/ if ((psnLista->psnSig)&&(!wRet)) wRet = CREAWORD (psnLista->psnSig->bPos, ERR_ONV); /*Ya no debe haber mas en la lista*/ return (wRet); word wAnalizaArgs (nodo **psnAux, word *pwFlagDir, word *pwIdArg, dword *pdNum, byte *pbSeg, byte *pbReg) /*Verifica los argumentos, obtiene bFlagDir y wI dArg*/ byte bSalir; word wRet=ERR_NE; if (!(*psnAux)) return (ERR_FA); /*Hay argument os?*/ do bSalir = TRUE; /*Para una sola revision*/ switch ((*psnAux)->bTipo) case ID_IESP: /*Puede ser word/byte ptr o fa r*/ wRet = wAnalizaIEsp (&*psnAux, pwIdArg); if (!wRet) bSalir = FALSE; /*Continua*/ break; case ID_REG32: case ID_REG16: /*Solo se espera el registro* / case ID_REGDIR: /*Registro de 16 bits para d ireccionamiento*/ case ID_REG08: /*Registro de 8 bits*/ *pbReg = (*psnAux)->bNumTipo; /*El regist ro, si hay*/ if ((*psnAux)->bTipo==ID_REG08) *pwIdArg = SETBIT (*pwIdArg, IDARG_R08); /*Registro de 8 bits*/ else

Page 298: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

293

switch ((*psnAux)->bTipo) case ID_REG16: case ID_REGDIR: *pwIdArg = SETBIT (*pwIdArg, IDARG_R 16); /*Registro de 16 bits*/ break; case ID_REG32: *pwIdArg = SETBIT (*pwIdArg, IDARG_R 32); /*Registro de 16 bits*/ break; *psnAux = (*psnAux)->psnSig; break; case ID_NUMERO: /*Numero o puntero*/ *(pdNum+0) = (*psnAux)->dNumero; if ((*psnAux)->bNumTipo==ID_NUM08) *pwIdArg = SETBIT (*pwIdArg, IDARG_IM08) ; else if ((*psnAux)->bNumTipo==ID_NUM16) *pwIdArg = SETBIT (*pwIdArg, IDARG_IM1 6); else *pwIdArg = SETBIT (*pwIdArg, IDARG_IM3 2); if ((*psnAux)->psnSig) if (((*psnAux)->psnSig->bTipo==ID_OPERAD OR)&&((*psnAux)->psnSig->bNumTipo==CHAR_2PUN)) /*Se espera que sea otro numero*/ *psnAux = (*psnAux)->psnSig; /*Paso a dos puntos*/ *pwIdArg = SETBIT (*pwIdArg, IDARG_P); *pwIdArg = CLSBIT (*pwIdArg, IDARG_IM1 6); *pwIdArg = CLSBIT (*pwIdArg, IDARG_IM0 8); *psnAux = (*psnAux)->psnSig; /*Debe s er un numero*/ if (!(*psnAux)) return (CREAWORD((*psn Aux)->bPos, ERR_EEA)); if ((*psnAux)->bTipo!=ID_NUMERO) retur n (CREAWORD((*psnAux)->bPos, ERR_EEA)); *(pdNum+1) = (*psnAux)->dNumero; *psnAux = (*psnAux)->psnSig; break; case ID_SEG: /*El segmento puede o no puede ir solo*/ *pwIdArg = SETBIT (*pwIdArg, IDARG_SEG); *pbSeg = (*psnAux)->bNumTipo; if ((*psnAux)->psnSig) if (((*psnAux)->psnSig->bTipo==ID_OPERAD OR)&&((*psnAux)->psnSig->bNumTipo==CHAR_2PUN)) *psnAux = (*psnAux)->psnSig; /*Estos son los dos puntos*/ bSalir = FALSE; /*Para el siguiente a rgumento*/ *pwIdArg = CLSBIT (*pwIdArg, IDARG_SEG ); *pwIdArg = SETBIT (*pwIdArg, IDARG_PRE ); *psnAux = (*psnAux)->psnSig; break; case ID_OPERADOR: /*Solo se espera [*/ wRet = wAnalizaModoDir (&*psnAux, pwFlagDi r, pdNum); if ((*pwFlagDir)&&(!TSTBIT(*pwIdArg, IDARG _M08|IDARG_M16))) *pwIdArg = SETBIT (*pwIdArg, IDARG_M16); break; default: wRet = CREAWORD ((*psnAux)->bPos, ERR_EEA) ; break; while (!bSalir); return (wRet); word wAnalizaIEsp (nodo **psnAux, word *pwFlag) /*Verifica expresiones WORD/BYTE PTR y FAR*/ byte bFlag=0; /*Controla la seleccion WORD/BYTE PTR*/ switch ((*psnAux)->bNumTipo) case ID_IESP_B: /*Posicion de BYTE*/ bFlag = 1; *pwFlag = SETBIT (*pwFlag, IDARG_M08); /*Se supone direccionamiento*/ case ID_IESP_W: /*Posicion de WORD*/ if (!bFlag) *pwFlag = SETBIT (*pwFlag, IDARG _M16);

Page 299: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

294

*psnAux = (*psnAux)->psnSig; if (!(*psnAux)) return (ERR_SEP); if ((*psnAux)->bTipo==ID_IESP) if ((*psnAux)->bNumTipo!=ID_IESP_P) return (CREAWORD((*psnAux)->bPos, ERR_SE P)); else return (ERR_NE); /*No es necesario el PTR* / break; case ID_IESP_F: /*Posicion de FAR*/ *pwFlag = SETBIT (*pwFlag, IDARG_FAR); break; default: return (CREAWORD((*psnAux)->bPos, ERR_INV)); *psnAux = (*psnAux)->psnSig; if (!(*psnAux)) return (ERR_FA); return (ERR_NE); word wAnalizaModoDir (nodo **psnAux, word *pwFDir, dword *pdNum) /*Verifica modo de direccionamiento*/ char cNodo, cSign; byte bF; if (!(*psnAux)) return (ERR_EEA); if ((*psnAux)->bNumTipo!=CHAR_PIZQ) return (CREA WORD((*psnAux)->bPos, ERR_SPI)); cNodo = 1; cSign = FALSE; *psnAux = (*psnAux)->psnSig; /*Este es el inici o*/ if (!(*psnAux)) return (ERR_EEA); while (cNodo!=-2) switch ((*psnAux)->bTipo) case ID_NUMERO: cNodo = sCDecodDir[cNodo][0]; cSign = TRU E; if (TSTBIT(*pwFDir, FDIR_N16|FDIR_N08)) return (CREAWORD((*psnAux)->bPos, ERR_SU N)); if ((*psnAux)->bNumTipo==ID_NUM16) *pwFDir = SETBIT (*pwFDir, FDIR_N16); else *pwFDir = SETBIT (*pwFDir, FDIR_N08); *pdNum = (*psnAux)->dNumero; /*El numero obtenido*/ break; case ID_REGDIR: cNodo = sCDecodDir[cNodo][1]; bF = bObtenRegDirFlag ((*psnAux)->bNumTipo ); if (TSTBIT(*pwFDir, bF)) return (CREAWORD( (*psnAux)->bPos, ERR_RR)); *pwFDir = SETBIT (*pwFDir, bF); break; case ID_OPERADOR: switch ((*psnAux)->bNumTipo) case CHAR_PIZQ: cNodo = sCDecodDir[cNodo][2]; break; case CHAR_PLUS: cNodo = sCDecodDir[cNodo][3]; if (!cSign) *pwFDir = CLSBIT (*pwFDir, FDIR_SIG); break; case CHAR_MENOS: cNodo = sCDecodDir[cNodo][4]; if (!cSign) *pwFDir = SETBIT (*pwFDir, FDIR_SIG); break; case CHAR_PDER: cNodo = sCDecodDir[cNodo][5]; break; default: return (CREAWORD((*psnAux)->bPos, ERR_ EDO)); break; default:

Page 300: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

295

return (CREAWORD((*psnAux)->bPos, ERR_ANV) ); if (cNodo==-1) return (CREAWORD((*psnAux)->bPo s, ERR_ANV)); *psnAux = (*psnAux)->psnSig; if (cNodo!=-2) return (ERR_EEA); return (ERR_NE); byte bObtenRegDirFlag (byte bNumTipo) /*Obtiene la bandera del registro para FlagDir*/ switch (bNumTipo) case ID_REGDIR0: return (FDIR_BX); /*Registro BX*/ case ID_REGDIR1: return (FDIR_BP); /*Registro BP*/ case ID_REGDIR2: return (FDIR_SI); /*Registro SI*/ case ID_REGDIR3: return (FDIR_DI); /*Registro DI*/ default: return (CERO); /*ERR: DEBE HABER ERRO R; PERO NO SE TOMA*/ word wCodIUnArg (nodo *psnLista, byte *pbCod, word wRef) /*Genera codigo para instrucciones de un argument o*/ nodo *psnAux; word wFlagDir=CERO; byte bSeg=CERO, bReg=CERO; word wIdArg=CERO; word wRet; /*Para errores y puntero de pbCod*/ dword sdNum[2]=CERO, CERO; /*Los numeros, se usan 2 para SEG:OFF*/ word x, y, wCMP, wRes; byte bPosI, bOpcI; psnAux = psnLista->psnSig; /*En psnLista queda la instruccion*/ *(pbCod+LEN_COD) = CERO; /*No hay instruccion*/ /*Obtenemos los argumentos*/ wRet = wAnalizaArgs (&psnAux, &wFlagDir, &wIdArg , sdNum, &bSeg, &bReg); // vPrintFlag (wIdArg, bFlagDir); /*QUITAR!!!! */ if (wRet) return (wRet); wRet = wChkIdArgs (wIdArg, &wFlagDir, sdNum); if (wRet) return (wRet); if (psnAux) return (CREAWORD(psnAux->bPos, ERR_E EA)); /*Modificacion al salto, cuando es un numero*/ if (bChkSalto (psnLista)) /*Es un salto*/ if (TSTBIT(wIdArg, IDARG_IM08|IDARG_IM16)) /*S olo es el numero*/ /*32! Para 32 bits habra que modificar aqui* / wIdArg = CLSBIT(wIdArg, IDARG_IM08|IDARG_IM1 6); /*Borra los bits*/ if (sdNum[0]>wRef) wCMP = sdNum[0] - wRef; else wCMP = wRef - sdNum[0]; if (wCMP>0x81) /*Ya es salto de 16 bits*/ wIdArg = SETBIT(wIdArg, IDARG_IM16); else wIdArg = SETBIT(wIdArg, IDARG_IM08); sdNum[0] = sdNum[0] - wRef; /*Calcula el des plazamiento*/ wRet = LEN_COD + 1; if (TSTBIT(wIdArg, IDARG_PRE)) /*Hay prefijo de segmento?*/ *(pbCod+wRet) = sBSegPref[bSeg] + SEG_PREF; w Ret++; wIdArg = CLSBIT (wIdArg, IDARG_PRE); /*Borra l a bandera*/ /*Procede a generar el codigo*/ bPosI = sBDesIntUnArg[psnLista->bNumTipo][DESIA_ POS]; /*Posicion*/ bOpcI = sBDesIntUnArg[psnLista->bNumTipo][DESIA_ OPC]; /*Num Opciones*/ for (x=0; x<bOpcI; x++) wCMP = CREAWORD (sBCodIntUnArg[bPosI+x][CI1A_P OS_CMPH], sBCodIntUnArg[bPosI+x][CI1A_POS_CMPL]); if (TSTBIT(sBCodIntUnArg[bPosI+x][CI1A_POS_RM] , RM_A)) wRes = wCMP & wIdArg; else if (wCMP==wIdArg) wRes = TRUE;

Page 301: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

296

else wRes = FALSE; if ((wRes)&&(TSTBIT(sBCodIntUnArg[bPosI+x][CI1 A_POS_RM], RM_B))) /*El byte extra para argumentos especificos* / switch (wCMP) case COD_REG16: /*Registro*/ case COD_REG08: if (bReg!=sBCodIntUnArg[bPosI+x][CI1A_PO S_EB]) wRes = FALSE; break; case COD_MEM16: /*Direccion a memoria*/ case COD_MEM08: if (LBYTE(wFlagDir)!=sBCodIntUnArg[bPosI +x][CI1A_POS_EB]) wRes = FALSE; break; case COD_SEG: /*Segmento*/ if (bSeg!=sBCodIntUnArg[bPosI+x][CI1A_PO S_EB]) wRes = FALSE; break; default: wRes = FALSE; if (wRes) /*Acepta codigo para 32 bits*/ /*Genera el codigo y sale*/ /*Verifica que la instruccion correspoda con el proc*/ if (sBCodIntUnArg[bPosI+x][CI1A_POS_PROC]>BP rocesador) return (ERR_INR); for (y=0; y<sBCodIntUnArg[bPosI+x][CI1A_POS_ LEN]; y++, wRet++) *(pbCod+wRet) = sBCodIntUnArg[bPosI+x][CI1 A_POS_COD+y]; /*El codigo*/ /*Viene el ModR/M y/o los operandos*/ switch (wCMP) case COD_REG16: /*Registro de 16 bits*/ case COD_MEM16: /*A memoria de 16 bits*/ case COD_rm16: /*Registro/memoria de 16 bi ts*/ case COD_REG08: /*Registro de 16 bits*/ case COD_MEM08: /*A memoria de 8 bits*/ case COD_rm08: /*Registro/memoria de 8 bit s*/ case COD_FAR: /*A puntero FAR*/ if (TSTBIT(wIdArg, IDARG_R16|IDARG_R08)) /*Registro 16 u 8 bits*/ if (TSTBIT(sBCodIntUnArg[bPosI+x][CI1A _POS_RM], RM_S)) /*Suma registro, solo en 16 bits par a un argumento*/ wRet--; *(pbCod+wRet) = *(pbCod+wRet) + bReg ; else /*El MOD R/M*/ *(pbCod+wRet) = sBModosReg_1[bReg] | (sBCodIntUnArg[bPosI+x][CI1A_POS_RM] & RM_F); wRet++; else /*Memoria*/ y = bObtenModoDir (wFlagDir); if (y>=MDIR_ERR) return (CREAWORD(CERO , ERR_DNV)); *(pbCod+wRet) = (sBCodIntUnArg[bPosI+x ][CI1A_POS_RM] & RM_F) | LBYTE (y); wRet++; if (TSTBIT(wFlagDir, FDIR_N16|FDIR_N08 )) /*Hay numeros*/ if (TSTBIT(wFlagDir, FDIR_SIG)) sdNu m[0] = ~sdNum[0] + 1; /*Complemento*/ *(pbCod+wRet) = LBYTE(sdNum[0]); wR et++; if (TSTBIT(wFlagDir, FDIR_N16)) *(pbCod+wRet) = HBYTE(sdNum[0]); wRet++; break; case COD_IMM08: /*Numero inmediato de 8 bi ts*/ if (sBCodIntUnArg[bPosI+x][CI1A_POS_RM]& RM_D) /*Direccion*/ sdNum[0] = sdNum[0] - (1+sBCodIntUnArg [bPosI+x][CI1A_POS_LEN]); /*2 bytes tiene la instruccion*/ *(pbCod+wRet) = LBYTE(sdNum[0]); wRet++ ; break;

Page 302: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

297

case COD_PUNTERO: /*Puntero tipo SEG:OFFSE T*/ *(pbCod+wRet) = LBYTE(sdNum[1]); wRet++ ; *(pbCod+wRet) = HBYTE(sdNum[1]); wRet++ ; case COD_NUMH16: /*Numero de 8 o 16 bits, no importa*/ case COD_IMM16: /*Numero inmediato de 8 bi ts*/ if (sBCodIntUnArg[bPosI+x][CI1A_POS_RM]& RM_D) /*Direccion*/ sdNum[0] = sdNum[0] - (2+sBCodIntUnArg [bPosI+x][CI1A_POS_LEN]); /*3 bytes tiene la instruccion*/ *(pbCod+wRet) = LBYTE(sdNum[0]); wRet++ ; *(pbCod+wRet) = HBYTE(sdNum[0]); wRet++ ; break; case COD_SEG: /*Registro de segmento*/ if (sBCodIntUnArg[bPosI+x][CI1A_POS_RM]& RM_S) /*Suma registro*/ wRet--; *(pbCod+wRet) = *(pbCod+wRet) + sBSegP ref[bSeg]; wRet++; break; default: return (CREAWORD(0, ERR_ANI)); break; /*Termina el for*/ if (x>=bOpcI) return (CREAWORD(0, ERR_EEI)); /*E ncontro codigo?*/ *(pbCod+LEN_COD) = LBYTE (--wRet); return (ERR_NE); byte bObtenModoDir (word wFDir) int x; wFDir = wFDir & 0x00FC; /*32! Modificar a 32 bit s*/ for (x=CERO; x<LEN_RM_DIR; x++) if (LWORD(wFDir)==sBModosDir[x][0]) return (sB ModosDir[x][1]); return (MDIR_ERR); /*ERR: Este es un error grave , que ocurre si no existe*/ /*PARA LAS DOS SIGUIENTES FUNCIONES wChkIdArgs y w Chk2IdArgs */ /*NOTA: Este es a modo de parche, debido a que no existe el modo [BP]*/ /*en su lugar el que si existe es el [BP+00]; algo similar ocurre con*/ /*[DESP08], en su lugar existe [DESP16]. */ /*Por otra parte el desplazamiento ya no es de 8 b its cuando es mayor*/ /*a 7E. Ademas el signo se hace presente, si el bi t mas significativo*/ /*esta activo, se cambia a 16 bits automaticamente , esto ocurre en */ /*argumentos rm16, imm08. */ word wChkIdArgs (word wIdArg, word *pwFlagDir, dwo rd *pdNum) /*Revisa un unico argumento*/ word wAux; byte x, y; /*Revisa que solo exista un opcion*/ wAux = wIdArg & IDARG_FILARG; /*Solo hay argume ntos, solo un bit activado*/ for (x=0, y=0; x<16; x++) wAux = wAux >> 1; y = y + (wAux & 1); if (y>1) return (ERR_EEA); /*Error en argumento* / /*Revisa que no existan argumentos de 32 bits*/ if (TSTBIT(wIdArg, IDARG_M32|IDARG_IM32|IDARG_R3 2)) if (BProcesador<COD_P386) return (ERR_PNV); if (*pwFlagDir==FDIR_BP) /*Conversion de [BP] -> [BP+00]*/ *pwFlagDir = SETBIT (*pwFlagDir, FDIR_N08); *pwFlagDir = SETBIT (*pwFlagDir, FDIR_SIG); *pdNum = CERO; if (TSTBIT(*pwFlagDir, FDIR_N08)) /*Corrige argumentos del tipo [BX+-XX]*/

Page 303: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

298

if (TSTBIT(*pwFlagDir, FDIR_SIG)) /*Signo neg ativo*/ if (*pdNum>0x80) /*Se transforma en 16 bits*/ *pwFlagDir = CLSBIT (*pwFlagDir, FDIR_N08) ; *pwFlagDir = SETBIT (*pwFlagDir, FDIR_N16) ; else if (*pdNum>0x7F) /*Se transforma en 16 bits*/ *pwFlagDir = CLSBIT (*pwFlagDir, FDIR_N08) ; *pwFlagDir = SETBIT (*pwFlagDir, FDIR_N16) ; if (*pwFlagDir==FDIR_N08) /*[disp08] -> [disp16]*/ *pwFlagDir = CLSBIT (*pwFlagDir, FDIR_N08); *pwFlagDir = SETBIT (*pwFlagDir, FDIR_N16); if ((TSTBIT(wIdArg, IDARG_FAR))&&(TSTBIT(wIdArg, IDARG_IM08|IDARG_IM16|IDARG_R08|IDARG_R16))) return (ERR_MUF); /*Imposible usar FAR en nume ros y registros*/ return (ERR_NE); word wChk2IdArgs (word *pwIdArg, word *pwFlagDir, dword *pdNum) /*Revisa cuando dos argumentos*/ word wRet, x; if ((TSTBIT(*pwIdArg, IDARG_M16))&&(TSTBIT(*(pwI dArg+1), IDARG_R08))) *pwIdArg = CLSBIT (*pwIdArg, IDARG_M16); *pwIdArg = SETBIT (*pwIdArg, IDARG_M08); if ((TSTBIT(*pwIdArg, IDARG_R08))&&(TSTBIT(*(pwI dArg+1), IDARG_M16))) *(pwIdArg+1) = CLSBIT (*(pwIdArg+1), IDARG_M16 ); *(pwIdArg+1) = SETBIT (*(pwIdArg+1), IDARG_M08 ); if ((TSTBIT(*pwIdArg, IDARG_SEG))&&(TSTBIT(*(pwI dArg+1), IDARG_SEG))) return (CREAWORD(CERO, ERR_MUS)); /*Dos segment os a la vez*/ if ((TSTBIT(*pwIdArg, IDARG_FAR))||(TSTBIT(*(pwI dArg+1), IDARG_FAR))) return (CREAWORD(CERO, ERR_MUF)); /*Uso de FAR en instrucciones de dos argumentos*/ if ((*pwFlagDir)&&(*(pwFlagDir+1))) return (CREAWORD(CERO, ERR_I2M)); /*Dos direcc iones a memoria a la vez*/ /*if ((TSTBIT(*pwIdArg, IDARG_IM08|IDARG_IM16))& &(TSTBIT(*(pwIdArg+1), IDARG_IM08|IDARG_IM16))) return (CREAWORD(CERO, ERR_I2N)); /*Dos numero s a la vez*/ if ((TSTBIT(*pwIdArg, IDARG_P))||(TSTBIT(*(pwIdA rg+1), IDARG_P))) return (CREAWORD(CERO, ERR_NUD)); /*Usar apunt adores en instrucciones de dos argumentos*/ for (x=0; x<2; x++) /*Hace una revision argumento a argumento*/ wRet = wChkIdArgs (*(pwIdArg+x), (pwFlagDir+x) , (pdNum+x)); if (wRet) return (wRet); return (ERR_NE); word wCodIDosArgs (nodo *psnLista, byte *pbCod, wo rd wLin) /*Genera codigo para instrucciones de dos argume ntos*/ nodo *psnAux; word swFlagDir[2]=CERO, CERO; byte sbSeg[2]=CERO, CERO; byte sbReg[2]=CERO, CERO; word swIdArg[2]=CERO, CERO; word wRet=ERR_NE; /*De entrada no hay error*/ dword sdNum[3]=CERO, CERO, CERO; /*Los numero s*/ byte bPosI, bOpcI; word x, y, swCMP[2], swRes[2]; psnAux = psnLista->psnSig; /*En psnLista queda la instruccion*/ *(pbCod+LEN_COD) = CERO; /*No hay instruccion*/ /*Revisamos que la expresion sea = arg1, arg2*/

Page 304: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

299

wRet = wAnalizaArgs (&psnAux, swFlagDir, swIdArg , sdNum, sbSeg, sbReg); if (wRet) return (wRet); /*Se reviso primer agu mento*/ wRet = wChkCOMA (&psnAux); /*Verifica que exista COMA entre dos argumentos*/ if (wRet) return (wRet); wRet = wAnalizaArgs (&psnAux, &swFlagDir[1], &sw IdArg[1], &sdNum[1], &sbSeg[1], &sbReg[1]); if (wRet) return (wRet); /*Se reviso segundo ar gumento*/ if (psnAux) return (CREAWORD(psnAux->bPos, ERR_E EA)); /*Hace algunas revisiones, de los argumentos*/ wRet = wChk2IdArgs (swIdArg, swFlagDir, sdNum); if (wRet) return (wRet); /*Esta es una correccion por bit de signo, esto es: */ /*Cuando se tiene una instruccion del tipo ADC BX, IMM08 (no existe */ /*ningun problema en ADC BX, IMM16); en este cas o el registro destino */ /*es de 16 bits, pero el valor origen es de 8 bi ts, de esta forma el */ /*signo (el bit mas significativo) del numero IM M08 es tomado encuenta.*/ /*En los ensambladores el tener una instruccion del tipo ADC BX, 0FEH */ /*autmaticamente se tranforma en ADC BX, 00FEH d ebido al signo. */ /*En este caso, el deber del programador tomar e ncuenta el signo, y se */ /*asume que no existen signos en los numeros emp leados; por lo que la */ /*instruccion es valida como ADC BX, 0FEH, pero que en realidad se */ /*interpleta por el procesador como ADC BX, 0FFF EH; de ahi que los */ /*ensambladores tranformen a ADC BX, 00FEH. Ento nces hay que tomar */ /*encuenta esta nota, ya que algunas intruccione s se pueden ver */ /*afectadas. Unicamente las instrucciones I/O no se afecta por esto. */ /*El siguiente codigo corrige lo anterio, lo que hace que el */ /*ensamblador se comporte como los demas, sin to mar encuenta las */ /*instrucciones I/O (tales como IN). */ /* if (!bChkIOPort(psnLista->bTipo, psnLista-> bNumTipo)) if (TSTBIT(swIdArg[0], IDARG_M16|IDARG_R16)) if (TSTBIT(swIdArg[1], IDARG_IM08)) if (swNum[1]&0x80) swIdArg[1] = CLSBIT (swIdArg[1], IDARG_I M08); swIdArg[1] = SETBIT (swIdArg[1], IDARG_I M16); */ /*En lugar de lo anterior, se coloca un Warning* / if (TSTBIT(swIdArg[0], IDARG_M16|IDARG_R16)) if (TSTBIT(swIdArg[1], IDARG_IM08)) if (sdNum[1]&0x80) iAddMensaje (WAR_ES, wLin ); /*Precaucion de signo* /*Inicia la construccion del codigo*/ wRet = LEN_COD + 1; /*wRet lleva el contador de codigo*/ /*Solo se puede una vez el prefijo de segmento*/ for (y=0; y<2; y++) /*Para el prefijo de segment o*/ if (TSTBIT(swIdArg[y], IDARG_PRE)) *(pbCod+wRet) = sBSegPref[sbSeg[y]] + SEG_PR EF; wRet++; /*Codigo de segmento*/ swIdArg[y] = CLSBIT (swIdArg[y], IDARG_PRE); y = 2; /*Procede a generar el codigo, se obtienen datos del descriptor*/ bPosI = sBDesIntDosArg[psnLista->bNumTipo][DESIA _POS]; /*Posicion*/ bOpcI = sBDesIntDosArg[psnLista->bNumTipo][DESIA _OPC]; /*Num Opciones*/ for (x=CERO; x<bOpcI; x++) swCMP[0] = CREAWORD (sBCodIntDosArg[bPosI+x][C I2A_POS_CMPH1], sBCodIntDosArg[bPosI+x][CI2A_POS_CMPL1]); swCMP[1] = CREAWORD (sBCodIntDosArg[bPosI+x][C I2A_POS_CMPH2], sBCodIntDosArg[bPosI+x][CI2A_POS_CMPL2]); for (y=0; y<2; y++) /*Solo son 2 argumentos*/ if (TSTBIT(sBCodIntDosArg[bPosI+x][CI2A_POS_ RM1+y], RM_A)) swRes[y] = swCMP[y] & swIdArg[y]; else if (swCMP[y]==swIdArg[y]) swRes[y] = TRUE; else swRes[y] = FALSE; if ((swRes[y])&&(TSTBIT(sBCodIntDosArg[bPosI +x][CI2A_POS_RM1+y], RM_B))) /*El byte extra para argumentos especifico s*/ switch (swCMP[y])

Page 305: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

300

case COD_REG16: /*Registro*/ case COD_REG08: if (sbReg[y]!=sBCodIntDosArg[bPosI+x][ CI2A_POS_EB1+y]) swRes[y] = FALSE; break; case COD_MEM16: /*Direccion a memoria*/ case COD_MEM08: case COD_MEMORIA: if (LWORD(swFlagDir[y])!=sBCodIntDosAr g[bPosI+x][CI2A_POS_EB1+y]) swRes[y] = FALSE; break; case COD_SEG: /*Segmento*/ if (sbSeg[y]!=sBCodIntDosArg[bPosI+x][ CI2A_POS_EB1+y]) swRes[y] = FALSE; break; case COD_IMM08: case COD_IMM16: case COD_NUMH16: /*Hace la comparacion s olo a 8 bits*/ if (sdNum[y]!=sBCodIntDosArg[bPosI+x][ CI2A_POS_EB1+y]) swRes[y] = FALSE; break; default: swRes[y] = FALSE; if ((swRes[0])&&(swRes[1])) /*Con esto aceptar a codigo de 32 bits*/ /*Genera el codigo y sale*/ /*Verifica que el codigo corresponda con el proc*/ if (sBCodIntDosArg[bPosI+x][CI2A_POS_PROC]>B Procesador) return (ERR_INR); for (y=0; y<sBCodIntDosArg[bPosI+x][CI2A_POS _LEN]; y++, wRet++) *(pbCod+wRet) = sBCodIntDosArg[bPosI+x][CI 2A_POS_COD+y]; /*El codigo*/ /*Viene el ModR/M y/o los operandos*/ switch (swCMP[0]) /*Primer operando*/ case COD_REG32: /*Para registros de 32 bit s*/ break; case COD_IMM08: /*En teoria solo para OUT y ESC*/ for (y=0; y<2; y++) if (TSTBIT(swIdArg[y], IDARG_IM08|IDAR G_IM16|IDARG_IM32)) if ((!TSTBIT(sBCodIntDosArg[bPosI+x] [CI2A_POS_RM1], RM_N))&&(TSTBIT(sBCodIntDosArg[bPosI+x][CI2A_POS_RM 2], RM_N))) else *(pbCod+wRet) = LBYTE(sdNum[y]); wRet++; if (!TSTBIT(sBCodIntDosArg[bPosI+x ][CI2A_POS_RM1+y], RM_D)) if ((TSTBIT(swIdArg[y], IDARG_IM 16))||(swCMP[1]==COD_NUMH16)) *(pbCod+wRet) = HBYTE(sdNum[y] ); wRet++; else if (TSTBIT(swIdArg[y], IDARG_M08|IDA RG_M16)) /*ERR se asume ESC*/ wRet--; *(pbCod+wRet-1) = *(pbCod+wRet-1) | ((*(pbCod+wRet) & ESC_COD_H) >> ESC_COD_R); *(pbCod+wRet) = *(pbCod+wRet) & ES C_COD_L; *(pbCod+wRet) = *(pbCod+wRet) << E SC_COD_R; *(pbCod+wRet) = bObtenModoDir (swF lagDir[y]) | *(pbCod+wRet); wRet++; /*Hay numeros en direccionamiento* / if ((TSTBIT(swFlagDir[y], FDIR_N16 ))||(TSTBIT(swFlagDir[y], FDIR_N08))) /*Hace el complemento para el si gno*/ if (TSTBIT(swFlagDir[y], FDIR_SI G)) sdNum[y] = ~sdNum[y] + 1; *(pbCod+wRet) = LBYTE(sdNum[y]); wRet++; if (TSTBIT(swFlagDir[y], FDIR_N1 6)) *(pbCod+wRet) = HBYTE(sdNum[y] ); wRet++;

Page 306: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

301

break; case COD_NUMH16: /*Cuando son dos numeros , solo para enter*/ *(pbCod+wRet) = LBYTE(sdNum[y]); wRet++ ; *(pbCod+wRet) = HBYTE(sdNum[y]); wRet++ ; if (TSTBIT(swIdArg[1], IDARG_IM08)) *(pbCod+wRet) = LBYTE(sdNum[y]); wRet ++; break; case COD_REG16: case COD_REG08: case COD_MEMORIA: case COD_rm16: case COD_rm08: case COD_SEG: if ((!TSTBIT(sBCodIntDosArg[bPosI+x][CI2 A_POS_RM1], RM_N))||(!TSTBIT(sBCodIntDosArg[bPosI+x][CI2A_POS_R M2], RM_N))) /*(0 o 0)*/ if (TSTBIT(sBCodIntDosArg[bPosI+x][CI2 A_POS_RM1], RM_N)) /*(1 0) Construye Mod R/M*/ *(pbCod+wRet) = bByteRM (swIdArg, sw FlagDir, sbReg, sbSeg); else /*(0 0) y (0 1) Se define R/M*/ if (TSTBIT(swIdArg[0], IDARG_M08|IDA RG_M16|IDARG_M32)) *(pbCod+wRet) = bObtenModoDir (swF lagDir[0]) | (sBCodIntDosArg[bPosI+x][CI1A_POS_RM] & RM_F); else *(pbCod+wRet) = sBModosReg_1[sbReg [0]] | (sBCodIntDosArg[bPosI+x][CI1A_POS_RM] & RM_F); wRet++; /*(1 1) no hay byte R/M*/ for (y=0; y<2; y++) if (TSTBIT(sBCodIntDosArg[bPosI+x][CI2 A_POS_RM1+y], RM_S)) wRet--; *(pbCod+wRet) = *(pbCod+wRet) + sbRe g[y]; wRet++; for (y=0; y<2; y++) /*Numero de direccionamiento*/ if (TSTBIT(swIdArg[y], IDARG_M08|IDARG _M16|IDARG_M32)) /*Hay numeros en direccionamiento*/ if ((TSTBIT(swFlagDir[y], FDIR_N16)) ||(TSTBIT(swFlagDir[y], FDIR_N08))) /*Hace el complemento para el sign o*/ if (TSTBIT(swFlagDir[y], FDIR_SIG) ) sdNum[y] = ~sdNum[y] + 1; *(pbCod+wRet) = LBYTE(sdNum[y]); wRet++; if (TSTBIT(swFlagDir[y], FDIR_N16) ) *(pbCod+wRet) = HBYTE(sdNum[y]); wRet++; if (TSTBIT(swIdArg[y], IDARG_IM08|IDAR G_IM16|IDARG_IM32)) /*Numeros*/ if ((!TSTBIT(sBCodIntDosArg[bPosI+x] [CI2A_POS_RM1], RM_N))&&(TSTBIT(sBCodIntDosArg[bPosI+x][CI2A_POS_RM 2], RM_N))) else *(pbCod+wRet) = LBYTE(sdNum[y]); wRet++; if (!TSTBIT(sBCodIntDosArg[bPosI+x ][CI2A_POS_RM1+y], RM_D)) if ((TSTBIT(swIdArg[y], IDARG_IM 16))||(swCMP[1]==COD_NUMH16)) *(pbCod+wRet) = HBYTE(sdNum[y] ); wRet++; break; case COD_rm32: break; case COD_MEM08: /*Memoria*/ case COD_MEM16:

Page 307: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

302

*(pbCod+wRet) = LBYTE(sdNum[0]); wRet++ ; *(pbCod+wRet) = HBYTE(sdNum[0]); wRet++ ; break; default: return (CREAWORD(CERO, ERR_EEI)); break; if (x>=bOpcI) return (CREAWORD(0, ERR_EEI)); *(pbCod+LEN_COD) = LBYTE (--wRet); return (ERR_NE); word wChkCOMA (nodo **psnAux) if ((*psnAux)) if ((*psnAux)->bTipo!=ID_OPERADOR) return (CRE AWORD((*psnAux)->bPos, ERR_FA)); else if ((*psnAux)->bNumTipo!=CHAR_COMA) return ( CREAWORD((*psnAux)->bPos, ERR_SEC)); else *psnAux = (*psnAux)->psnSig; else return (CREAWORD((*psnAux)->bPos, ERR_FA)); return (ERR_NE); byte bByteRM (word *pwIdArg, word *pwFlagDir, byte *pbReg, byte *pbSeg) byte x, bRM=CERO, bFlag=FALSE; for (x=0; x<2; x++) if (TSTBIT(*(pwIdArg+x), IDARG_R08|IDARG_R16|I DARG_R32)) if (((x<=0)||(!bFlag))&&(!TSTBIT(*(pwIdArg+1 ), IDARG_SEG))) bRM = bRM | sBModosReg_2[*(pbReg+x)]; else bRM = bRM | sBModosReg_1[*(pbReg+x)]; bFlag = TRUE; if (TSTBIT(*(pwIdArg+x), IDARG_SEG)) bRM = bRM | sBModosSeg_2[*(pbSeg+x)]; bFlag = TRUE; if (TSTBIT(*(pwIdArg+x), IDARG_M08|IDARG_M16|I DARG_M32)) bRM = bRM | bObtenModoDir (*(pwFlagDir+x)); return (bRM); byte bChkSalto (nodo *psnAux) /*Confirma la existencia de instruccion de salto LOOPXX, JXXX, CALL, etc*/ if (psnAux->bTipo==ID_IUNARG) /*Solo hay saltos que aceptan un argumento*/ if (psnAux->bNumTipo<=ID_IUNARGJ) return (TRUE ); return (FALSE); byte bChkIOPort (byte bTipo, byte bNumTipo) /*Confirma la existencia de un salto*/ if (bTipo==ID_IDOSARG) /*Solo hay saltos que ace ptan un argumento*/ if (bNumTipo==ID_IDOSARGI) return (TRUE); return (FALSE); word wCodResWord (nodo *psnLista, byte *pbCod, cha r *pcText, word *pwRef, word wLin) /*Por lo pronto solo existe DB*/ word x, y=LEN_COD+1, z; nodo *psnAux; byte bAuxNum=CERO;

Page 308: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

303

psnAux = psnLista->psnSig; switch (psnLista->bNumTipo) case ID_RW_DB: /*DB*/ while (psnAux) switch (psnAux->bTipo) case ID_CADENA: /*Es una cadena*/ for (x=psnAux->bPos; x<(LWORD(psnAux-> dNumero)); x++, y++) *(pbCod+y) = *(pcText+x); break; case ID_NUMERO: /*Es un numero*/ *(pbCod+y) = LBYTE (psnAux->dNumero); bAuxNum = *(pbCod+y); y++; /*Se gua rda el numero para un array*/ break; case ID_OPERADOR: /*Es una COMA*/ switch (psnAux->bNumTipo) case CHAR_COMA: break; case CHAR_PLUS: /*Para una cadena*/ psnAux = psnAux->psnSig; if (psnAux->bTipo!=ID_NUMERO) retu rn (CREAWORD(psnAux->bPos, ERR_SEN)); y = LBYTE (psnAux->dNumero); if (y>LEN_ARRAY) return (CREAWORD( psnAux->bPos, ERR_AML)); for (x=LEN_COD; x<y; x++) *(pbCod+x+1) = bAuxNum; if (psnAux->psnSig) return (CREAWO RD(psnAux->bPos, ERR_ANV)); y++; break; default: return (CREAWORD(psnAux->bPos, ERR_E DO)); break; default: return (CREAWORD(psnAux->bPos, ERR_EEA)) ; psnAux = psnAux->psnSig; *(pbCod+LEN_COD) = LBYTE (y-1); break; case ID_RW_DW: /*DW*/ while (psnAux) switch (psnAux->bTipo) case ID_NUMERO: /*Es un numero*/ *(pbCod+y) = LBYTE (psnAux->dNumero); y++; *(pbCod+y) = HBYTE (psnAux->dNumero); y++; break; case ID_OPERADOR: /*Es una COMA*/ if (psnAux->bNumTipo!=CHAR_COMA) retur n (CREAWORD(psnAux->bPos, ERR_EDO)); break; default: return (CREAWORD(psnAux->bPos, ERR_EEA)) ; psnAux = psnAux->psnSig; *(pbCod+LEN_COD) = LBYTE (y-1); break; case ID_RW_SREF: /*SETREF*/ if (TSTBIT(WConstASM, CTEASM_NO1INST)) retur n (ERR_VPI); /*No valida en archivos*/ case ID_RW_ORG: /*ORG*/ if (psnAux->bTipo==ID_NUMERO) z = LWORD (psnAux->dNumero); /*Obtiene el numero*/ if ((*pwRef>z)&&(psnLista->bNumTipo==ID_RW _ORG)) return (CREAWORD(psnAux->bPos, ERR_EER)); if (*pwRef>z) return (CREAWORD(psnAux->bPos, ERR_ORG)) ;

Page 309: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

304

*pwRef = z; if (psnLista->bNumTipo==ID_RW_SREF) WConstASM = SETBIT (WConstASM, CTEASM_SE TREF); else /*El ORG Define las nuevas etiquetas */ WConstASM = CLSBIT (WConstASM, CTEASM_NO REF); else return (CREAWORD(psnAux->bPos, ERR_SEN) ); psnAux = psnAux->psnSig; if (psnAux) return (CREAWORD(psnAux->bPos, E RR_EEA)); break; case ID_RW_INC: /*INCLUDE*/ if (!TSTBIT(WConstASM, CTEASM_ARCHIVO)) retu rn (ERR_INP); /*No valida en archivos*/ if (TSTBIT(WConstASM, CTEASM_NESTFILE)) retu rn (ERR_HAE); if (!psnAux) return (ERR_EIE); if (psnAux->bTipo!=ID_CADENA) return (ERR_MU I); for (x=psnAux->bPos, y=CERO; x<(LWORD(psnAux ->dNumero)); x++, y++) *(pCInclude+y) = toupper (*(pcText+x)); *(pCInclude+y) = CERO; WConstASM = SETBIT (WConstASM, CTEASM_NESTFI LE); /*Archivo en espera*/ break; case ID_RW_DELA: /*DELALL borrar las constant es y etiquetas*/ if (TSTBIT(WConstASM, CTEASM_ARCHIVO)) retur n (ERR_INP); vBorraLBLCTE (); break; case ID_RW_ENDP: /*ENDP*/ if (!TSTBIT(WConstASM, CTEASM_ARCHIVO)) retu rn (ERR_INP); break; case ID_RW_88: case ID_RW_86: /*Tipo de procesador*/ if (psnAux) return (ERR_EIE); if (BProcesador==COD_NOPROC) BProcesador = C OD_P86; else if (BProcesador!=COD_P86) iAddMensaje (WAR _NAP, wLin); break; case ID_RW_188: case ID_RW_186: if (psnAux) return (ERR_EIE); if (BProcesador==COD_NOPROC) BProcesador = C OD_P186; else if (BProcesador!=COD_P186) iAddMensaje (WA R_NAP, wLin); break; case ID_RW_286: if (psnAux) return (ERR_EIE); if (BProcesador==COD_NOPROC) BProcesador = C OD_P286; else if (BProcesador!=COD_P286) iAddMensaje (WA R_NAP, wLin); break; case ID_RW_386: if (psnAux) return (ERR_EIE); if (BProcesador==COD_NOPROC) BProcesador = C OD_P386; else if (BProcesador!=COD_P386) iAddMensaje (WA R_NAP, wLin); break; default: return (ERR_MPR); return (ERR_NE); void vBorraLBLCTE () vLiberaMemLBL (); /*Libera la memoria*/ psLEtiqueta = CERO; /*Reinicia el apuntador*/

F.24 COMPILAE.CPP /*CONTIENE LAS FUNCIONES PARA COMPILAR ARCHIVOS*/ #define Uses_TApplication #define Uses_TMenuBar

Page 310: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

305

#define Uses_TRect #define Uses_TSubMenu #define Uses_TKeys #define Uses_TMenuItem #define Uses_TStatusLine #define Uses_TStatusItem #define Uses_TStatusDef #define Uses_TPoint #define Uses_TEditor #define Uses_MsgBox #define Uses_TFileDialog #define Uses_TDeskTop #define Uses_TStaticText #define Uses_TButton #define Uses_TDeskTop #define Uses_TRect #define Uses_TFileEditor #define Uses_TFileDialog #define Uses_TChDirDialog #include <tv.h> #include <conio.h> #include <lib.h> #include <string.h> #include <bios.h> #include "txtwin.h" #include "edit188.h" #include "asmmaq.h" #include "define.h" #include "mensaje.h" #include "color.h" #include "teditwnd.h" #include "fileedit.h" #define COL_NORM BGRIS|FIVERDE #define COL_RES BGRIS|FIBLANCO #define COL_SAL BGRIS|FICYAN void DUAMI188::vCompilaArchivo (char *pcFile, efil e *psefAux, byte bDisk) /*Compila un archivo*/ byte sbCod[MAX_LEN_CAD]; char scText[MAX_LEN_CAD+10]; //Maxima longitud de cadena + 10 char scFileOut[MAX_PATH]; char *pcInclude; //Ruta y nombre de salida word wErr, wPos, wAux, swLin[MAX_NESTFILE], wLin C=CERO, x, wLenCod, wLinT; byte bSalir, bInc, bCancelar; /*Lleva el conteo de archivos usando include*/ FILE *psfOut, *psfIn[MAX_NESTFILE]; /*Se piden 2 para archivos anidados*/ efile sefIn[MAX_NESTFILE]; EDITWINDOW *pstewAux; pstwMsgComp->select (); //Muestra la ventana de compilando pstwMsgComp->show (); //Muestra la ventana de c ompilando pstwMsgComp->vImprimeText (2, 2, "Compilando:", COL_NORM); pstwMsgComp->vImprimeText (2, 5, "Lineas analiza das:", COL_NORM); pstwMsgComp->vImprimeText (2, 6, "Lineas compila das:", COL_NORM); pstwMsgComp->vImprimeText (2, 7, "Memoria libre : 00000 bytes", COL_NORM); pstwMsgComp->vImprimeText (2, 9, "Estado:", COL_ NORM); pstwMsgComp->vImprimeText (10, 9, "PASO 1", COL_ RES); pstwMsgComp->vImprimeText (1, 11, " PRESIONE E SC PARA CANCELAR ", 0x1F); if ((!pcFile)&&(!psefAux)) return; if ((pcFile)&&(psefAux)) return; /*Cuando se trata de un achivo, el compilador re aliza dos pasos*/ for (bInc=0; bInc<MAX_NESTFILE; bInc++) //Las variables de archivo psfIn[bInc] = CERO; swLin[bInc] = CERO; bCreaEditFile (&sefIn[bInc], CERO); psfOut = CERO; bInc = CERO; scText[CERO] = CER O; strcpy (scFileOut, soOpciones.scPathEXE); //Cop ia el directorio destino if (pcFile) //Para obtener el nombre de archivo de salida

Page 311: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

306

vObtenNombreArch (scText, pcFile, FALSE, MAX_N FILE-1); /*Obtiene el .COM*/ psfIn[bInc] = fopen (pcFile, "rt"); /*Abre el archivo fuente*/ if (!psfIn[bInc]) iAddMensaje (ERR_EAA, CERO); pstwMsgComp->vImprimeNFile (2, 3, pcFile, COL_ RES); else vObtenNombreArch (scText, pcEditFile(psefAux), FALSE, MAX_NFILE); vAsignaEditFile (&sefIn[bInc], psefAux); pstwMsgComp->vImprimeNFile (2, 3, pcEditFile(p sefAux), COL_RES); strcat (scText, ".COM"); //Agrega el COM strcat (scFileOut, scText); //Tiene el nombre c ompleto de archivo vIniciaCompilacion (); bCancelar = FALSE; if ((psfIn[bInc])||(bEFValido(&sefIn[bInc]))) //ERR puede ocurrir un error si no ocurre el I F do if ((bEsSegundoPaso())&&(bDisk)) psfOut = fopen (scFileOut, "wb"); //Crea ejecutable if (!psfOut) iAddMensaje (ERR_ECA, CERO); else psfOut = CERO; /*Inicia en las varibles*/ wPos = CERO; wLenCod = CERO; pstwMsgComp->vImprimeText (21, 5, " ", COL_RES); pstwMsgComp->vImprimeText (21, 6, " ", COL_RES); pstwMsgComp->vImprimeText (21, 7, " ", COL_RES); for (bInc=0; bInc<MAX_NESTFILE; bInc++) swLi n[bInc] = CERO; /*Lineas de archivo*/ bInc = CERO; wLinC = CERO; wLinT = CERO; //Lineas compiladas vResetMensajes (); /*Limpia los mensajes*/ iAddMensaje (MSG_SINNUM(MSG_SGS), CERO); // Titulo de mensajes bSalir = FALSE; //clrscr (); while (!bSalir) /*Hasta el fin de compilaci on*/ if (bioskey(1)) //Para cancelar la compil acion if (bioskey(0)==kbEsc) iAddMensaje (ERR_TPU, CERO); bSalir = TRUE; bCancelar = TRUE; if ((bObtenLineaCod(scText, psfIn[bInc], & sefIn[bInc], &swLin[bInc]))&&(!bSalir)) wAux = wPos; /*Obtiene la linea de codi go*/ wErr = wASM2MAQ (scText, sbCod, &wPos, s wLin[bInc]); /*Obtiene el codigo maquina*/ if (wErr) iAddMensaje (wErr, swLin[bInc] ); pcInclude = pcEsArchivoINCLUDE (); if (pcInclude) bInc++; if (bInc>=MAX_NESTFILE) /*Con esto sol o se anida MAX_NESTFILE archivos*/ bInc--; iAddMensaje (ERR_TAI, swLin [bInc]); else /*Hay que ver si el archivo no esta en el editor*/ pstwMsgComp->vLimpiaRenglon (3); pstewAux = (EDITWINDOW *)pstvBuscaVe ntanaArch (pcInclude); /*Para saber si esta en el editor*/ if (!bCreaEditFile(&sefIn[bInc], pst ewAux)) psfIn[bInc] = fopen (pcInclude, "r t"); if (!psfIn[bInc]) iAddMensaje (ERR_EAI, swLin[bInc -1]); bInc--; else wAddINCLUDE (pcInclude, swLin[bI nc-1]);

Page 312: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

307

pstwMsgComp->vImprimeNFile (2, 3 , pcInclude, COL_RES); iAddMensaje (MSG_LBL, swLin[bInc -1]); swLin[bInc] = CERO; /*ERR Se asume que el archivo exis te en el editor*/ else wAddINCLUDE (pcEditFile(&sefIn[bIn c]), swLin[bInc-1]); pstwMsgComp->vImprimeNFile (2, 3, pcEditFile(&sefIn[bInc]), COL_RES); iAddMensaje (MSG_LBL, swLin[bInc-1 ]); swLin[bInc] = CERO; if (sbCod[LEN_COD]) if (bEsSegundoPaso()) if (bDisk) if (psfOut) fwrite ((sbCod+1), sbCod[LEN_COD ], 1, psfOut); wLenCod = wLenCod + sbCod[LEN_COD] ; else //Se revisa que el buffer del depu rador sea suficiente for (x=1; x<=sbCod[LEN_COD]; x++, wLenCod++) if (wLenCod<TAM_CODMAQ()) BUFF_C ODMAQ(wLenCod) = sbCod[x]; wPos = wPos + sbCod[LEN_COD]; wLinC++ ; /*Incrementa las lineas compiladas*/ else if ((bEsSegundoPaso())&&(wPos!=wAux)) if (!bEsSETREF()) /*Hubo un org*/ for (; wAux<wPos; wAux++, wLenCod+ +) if (bDisk) putc (CERO, psfOut); else BUFF_CODMAQ(wLenCod) = CERO ; else if (bInc>CERO) /*Cierra y continua*/ if (psfIn[bInc]) fclose (psfIn[bInc] ); psfIn[bInc] = CERO; iAddMensaje (MSG_SINNUM(MSG_SCA), CERO ); psfIn[bInc] = CERO; wLinT = wLinT + swLin[bInc]; bInc--; pstwMsgComp->vLimpiaRenglon (3); if (pcFile) pstwMsgComp->vImprimeNFile (2, 3, pcFile, COL_RES); else pstwMsgComp->vImprimeNFile (2, 3, pcEditFile(psefAux), COL_RES); else bSalir = TRUE; /*Ya termino de obte ner las lineas de codigo*/ pstwMsgComp->vImprimeNum (21, 5, 10, swLin [bInc], COL_RES); pstwMsgComp->vImprimeNum (21, 6, 10, wLinC , COL_RES); pstwMsgComp->vImprimeText (21, 7, " " , COL_RES); pstwMsgComp->vImprimeNum (21, 7, 10, (TAM_ LBLCTE()-USE_LBLCTE()), COL_RES); vResetPunteros (psfIn[CERO], &sefIn[CERO]); /*Regresa el archivo de entrada al inicio*/ clearerr(psfIn[CERO]); /*Procede al analisis del segundo paso*/ pstwMsgComp->vImprimeText (10, 9, "Analizand o referencias", COL_RES); //En realidad no regresa un error, es solo p ara seguir el estandar. if (!bEsSegundoPaso()) wErr = wResuelveRef ( ); pstwMsgComp->vImprimeText (10, 9, "PASO 2 ", COL_RES); while ((!bFinCompilacion())&&(!bCancelar)); if (psfIn[CERO]) fclose (psfIn[CERO]); if (bDisk) //Cierra el archivo if (psfOut)

Page 313: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

308

fclose (psfOut); if (NUMERO_ERR()) unlink (scFileOut); else if (!NUMERO_ERR()) iAddMensaje (MSG_NUMFIN(M SG_SGA), wLenCod); if (!bDisk) LEN_CODMAQ() = wLenCod; //Se fijan los byte cargados pstwMsgComp->vImprimeNum (21, 5, 10, wLinT+swLin [0], COL_RES); pstwMsgComp->vImprimeText (1, 11, " TERMINAN DO DE COMPILAR ", 0x1F); /*Mesaje de compilacion*/ pstwMsgComp->vImprimeText (10, 9, " ", CREA_COLOR(BGRIS, FIBLANCO)); pstwMsgComp->vImprimeText (2, 2, "Salida: ", COL_NORM); pstwMsgComp->vLimpiaRenglon (3); //bDisk se emplea ahora para generar el mapa de direcciones del programa. if ((!NUMERO_ERR())&&(!NUMERO_WAR())) pstwMsgComp->vImprimeText (10, 9, "COMPILADO C ORRECTAMENTE", CREA_COLOR(BGRIS, FIBLANCO)); iAddMensaje (MSG_SINNUM(MSG_ACE), CERO); if (bDisk) pstwMsgComp->vImprimeNFile (2, 3, s cFileOut, COL_SAL); else pstwMsgComp->vImprimeText (2, 3, "Cargado en MEMORIA", COL_SAL); bDisk = TRUE; //Se genera MAP else if (NUMERO_ERR()) pstwMsgComp->vImprimeText (10, 9, " HAY ERRO RRES ", CREA_COLOR(BROJO, FIBLANCO)); iAddMensaje (MSG_SINNUM(MSG_ANC), CERO); pstwMsgComp->vImprimeText (2, 3, "No se gene ro nada", COL_SAL); bDisk = FALSE; //No se genera MAP else iAddMensaje (MSG_SINNUM(MSG_ACO), CERO); pstwMsgComp->vImprimeText (10, 9, " HAY WARN INGS ", CREA_COLOR(BROJO, FIAMARILLO)); if (bDisk) pstwMsgComp->vImprimeNFile (2, 3, scFileOut, COL_RES); else pstwMsgComp->vImprimeText (2, 3, "Carga do en MEMORIA", COL_SAL); bDisk = TRUE; //Se genera MAP if ((bDisk)&&(soOpciones.usGeneral&FLAGGRAL_MAP) ) //Se va a generar el mapa de direcciones del p rograma scText[CERO] = CERO; vObtenNombreArch (scText, scFileOut, FALSE, MA X_NFILE-1); strcat (scText, ".MAP"); //Agrega el MAP strcpy (scFileOut, soOpciones.scPathEXE); strcat (scFileOut, scText); //Tiene el nombre completo de archivo bCreaMAP (scFileOut); //Genera el MAP pstwMsgComp->vImprimeText (1, 11, " PRESIONE CUALQUIER TECLA ", 0x1F); iAddMensaje (MSG_NUMFIN(MSG_NLE), wLinT+swLin[0] ); //Lineas analizadas iAddMensaje (MSG_NUMFIN(MSG_NLC), wLinC); //Lin eas compiladas iAddMensaje (MSG_NUMFIN(MSG_NER), NUMERO_ERR()); //N£mero de errores iAddMensaje (MSG_NUMFIN(MSG_NWA), NUMERO_WAR()); //Numero de warnings vEsperaEvento (); pstwMsgComp->hide (); if ((NUMERO_ERR())||(NUMERO_WAR())) psmMsg->vMos trar (); byte bObtenLineaCod (char *pcText, FILE *psfIn, ef ile *psefIn, word *pwLin) /*Obtiene linea a linea codigo, si retorna FALSE el archivo o editor llego al final*/ word y=CERO; char x, cSalir; *(pcText) = CERO; cSalir = FALSE; if (psfIn) /*Es una entrada por archivo*/ if (feof(psfIn)) return (FALSE); while (!cSalir) /*Esta seccion es para cargar la linea de co digo del archivo*/ x = getc (psfIn); if (ferror (psfIn))

Page 314: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

309

/*Error al leer el archivo*/ iAddMensaje (ERR_ELA, CERO); *(pcText) = CERO; return (FALSE); if ((x==0x0A)||(x==0x0D)||(feof(psfIn))) cSalir = TRUE; if (x==0x0A) (*pwLin)++; /*En archivos se salta la 0x0D*/ else if (y<MAX_LEN_CAD) //Solo se permite hasta la maxima longitud de cadena *(pcText+y) = x; y++; else /*Es una entrada por editor*/ if (befof(psefIn)) return (FALSE); while (!cSalir) x = cGetc (psefIn); if ((x==0x0A)||(x==0x0D)||(befof(psefIn))) cSalir = TRUE; if (x==0x0D) (*pwLin)++; /*En el editor n o se salta el 0x0D, y este es primero*/ else if (y<MAX_LEN_CAD) *(pcText+y) = x; y++; *(pcText+y) = CERO; return (TRUE); byte bCreaEditFile (efile *psefF, EDITWINDOW *pste wAux) psefF->pstewF = pstewAux; psefF->usCont = CERO; //Contador del buffer if (!pstewAux) psefF->pcFileName = CERO; return (FALSE); psefF->pcFileName = pstewAux->pfeFEditor->fileNa me; return (TRUE); void vAsignaEditFile (efile *psefF1, efile *psefF2 ) psefF1->pstewF = psefF2->pstewF; psefF1->usCont = psefF2->usCont; psefF1->pcFileName = psefF2->pcFileName; char *pcEditFile (efile *psefF) return (psefF->pcFileName); byte befof (efile *psefAux) if (!psefAux) return (TRUE); if (!(psefAux->pstewF)) return (TRUE); if (psefAux->pstewF->pfeFEditor->bufSize<psefAux ->usCont) return (TRUE); return (FALSE); byte bEFValido (efile *psefAux) if (!(psefAux->pstewF)) return (FALSE); return (TRUE);

Page 315: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

310

char cGetc (efile *psefAux) ushort x; char cC; if (!psefAux) return (CERO); if (!(psefAux->pstewF)) return (CERO); x = psefAux->usCont; if (x==psefAux->pstewF->pfeFEditor->curPtr) x = psefAux->pstewF->pfeFEditor->curPtr + psef Aux->pstewF->pfeFEditor->gapLen; cC = *(psefAux->pstewF->pfeFEditor->buffer+x); psefAux->usCont = x + 1; return (cC); void vResetPunteros (FILE *psfIn, efile *psefIn) /*Reinicia loa apuntadores de archivo y editor*/ if (psfIn) fseek (psfIn, CERO, SEEK_SET); //Por archivo else psefIn->usCont = CERO; //Por buffer de edi tor

F.25 DEBUG.CPP /*CONTIENE LAS FUNCIONES PARA LA DEPURACION DE PROGRAMAS*/ #include <stdlib.h> #include <iostream.h> #include <fstream.h> #include <stdio.h> #include <string.h> #include <ctype.h> #define Uses_TEventQueue #define Uses_TEvent #define Uses_TProgram #define Uses_TApplication #define Uses_TKeys #define Uses_TRect #define Uses_TMenuBar #define Uses_TSubMenu #define Uses_TMenuItem #define Uses_TStatusLine #define Uses_TStatusItem #define Uses_TStatusDef #define Uses_TDeskTop #define Uses_TView #define Uses_TWindow #define Uses_TFrame #define Uses_TScroller #define Uses_TScrollBar #define Uses_TDialog #define Uses_TButton #define Uses_TSItem #define Uses_TCheckBoxes #define Uses_TRadioButtons #define Uses_TLabel #define Uses_TInputLine #include <tv.h> #include <lib.h> #include "debug.h" #include "asmmaq.h" #include "color.h" #include <conio.h> const //Algunos colores USCOL_MAQNOR = CREA_COLOR (BCYAN, FIBLANCO), USCOL_MAQSEL = CREA_COLOR (BAZUL, FIBLANCO), USCOL_MAQSTP = CREA_COLOR (BCYAN, FROJO),

Page 316: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

311

USCOL_REGNOR = CREA_COLOR (BCYAN, FICYAN), USCOL_REGSEL = CREA_COLOR (BNEGRO, FIBLANCO), USCOL_MEMNOR = CREA_COLOR (BCYAN, FAZUL), USCOL_MEMSEL = CREA_COLOR (BGRIS, FAZUL), maxLineLength = 80; //80 caracteres son mas que suficientes para las ventanas //Codigo de la ventana de depuracion DEBUGWINDOW::DEBUGWINDOW (const TRect& pstrBounds, byte bTVolMem, byte *pbVolMem, word wLenMem, byte bTBlkMemVol, word wSeg, word wOffS, //Volcado de memoria byte *pbBuf, word wLenCod, //Para debug char *pcBuf, byte bLenR, byte bNumR ) : //A los registros TWindow (pstrBounds, "Depurador UAMI-188EB", wnNoN umber), TWindowInit (&DEBUGWINDOW::initFrame) //Se va a crear la ventana de Debug de la UAMI-1 88EB TRect strR, strR1; TScrollBar *pstsbVScrollBar, *pstsbHScrollBar; TRect strEBounds = getExtent(); uchar ucV, ucH; bTamVolMem = bTVolMem; palette = wpCyanWindow; options = options | ofTileable; //Se fija la ventana de registros strR = TRect (strEBounds.b.x-14, strEBounds.a.y, strEBounds.b.x, strEBounds.b.y-bTVolMem); ucV = gfGrowHiY | gfGrowLoX | gfGrowHiX; ucH = gfGrowLoX | gfGrowHiY | gfGrowLoY | gfGrow HiX; //Se van a colocar los Scroll strR1 = TRect (strR.b.x-1, strR.a.y+1, strR.b.x, strR.b.y-1); pstsbVScrollBar = new TScrollBar (strR1); pstsbVScrollBar->options |= ofPostProcess; pstsbVScrollBar->growMode = ucV; insert (pstsbVScrollBar); strR1 = TRect (strR.a.x+2, strR.b.y-1, strR.b.x- 2, strR.b.y); pstsbHScrollBar = new TScrollBar (strR1); pstsbHScrollBar->options |= ofPostProcess; pstsbHScrollBar->growMode = ucH; insert (pstsbHScrollBar); strR1 = strR; strR1.grow (-1, -1); psrwRW = new REGWINDOW (strR1, CERO, pstsbVScrol lBar, pcBuf, bLenR, bNumR); psrwRW->growMode = gfGrowHiY | gfGrowLoX | gfGro wHiX; insert (psrwRW); //Se fija la ventana de memoria strR = TRect (strEBounds.a.x, strEBounds.b.y-(bT VolMem+1), strEBounds.b.x, strEBounds.b.y); ucV = gfGrowHiY | gfGrowLoX | gfGrowHiX | gfGrow LoY; ucH = gfGrowHiX | gfGrowHiY | gfGrowLoY; //Se colocan los Scroll strR1 = TRect (strR.b.x-1, strR.a.y+1, strR.b.x, strR.b.y-1); pstsbVScrollBar = new TScrollBar (strR1); pstsbVScrollBar->options |= ofPostProcess; pstsbVScrollBar->growMode = ucV; insert (pstsbVScrollBar); strR1 = TRect (strR.a.x+2, strR.b.y-1, strR.b.x- 2, strR.b.y); pstsbHScrollBar = new TScrollBar (strR1); pstsbHScrollBar->options |= ofPostProcess; pstsbHScrollBar->growMode = ucH; insert (pstsbHScrollBar); strR1 = strR; strR1.grow (-1, -1); psmewMW = new MEMWINDOW (strR1, pstsbHScrollBar, pstsbVScrollBar, pbVolMem, wLenMem, bTBlkMemVol, wSeg, wOffS); psmewMW->growMode = gfGrowHiY | gfGrowHiX | gfGr owLoY; insert (psmewMW); //se fija la ventana para desensamblar strR = TRect (strEBounds.a.x, strEBounds.a.y, st rEBounds.b.x-13, strEBounds.b.y-bTVolMem); ucV = gfGrowHiY | gfGrowLoX | gfGrowHiX; ucH = gfGrowHiX | gfGrowHiY | gfGrowLoY; //Se colocan los scroll

Page 317: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

312

strR1 = TRect (strR.b.x-1, strR.a.y+1, strR.b.x, strR.b.y-1); pstsbVScrollBar = new TScrollBar (strR1); pstsbVScrollBar->options |= ofPostProcess; pstsbVScrollBar->growMode = ucV; insert (pstsbVScrollBar); strR1 = TRect (strR.a.x+2, strR.b.y-1, strR.b.x- 2, strR.b.y); pstsbHScrollBar = new TScrollBar (strR1); pstsbHScrollBar->options |= ofPostProcess; pstsbHScrollBar->growMode = ucH; insert (pstsbHScrollBar); strR1 = strR; strR1.grow (-1, -1); psmawMW = new MAQWINDOW (strR1, pstsbHScrollBar, pstsbVScrollBar, pbBuf, wLenCod); psmawMW->growMode = gfGrowHiX | gfGrowHiY; insert (psmawMW); void DEBUGWINDOW::sizeLimits (TPoint& pstpminP, TP oint& pstpmaxP) TWindow::sizeLimits (pstpminP, pstpmaxP); //Tama¤o minimo que puede tener la ventana de de puracion pstpminP.x = 40; pstpminP.y = bTamVolMem + 5; void DEBUGWINDOW::close () //Oculta la pantalla de mensaje, es sustituida hide (); void DEBUGWINDOW::vCerrar () //Cierra definitivamente la pantalla, sustituye a close TWindow::close (); void DEBUGWINDOW::vMostrar () //Muestra la ventana de mensaje select (); show (); psmawMW->draw (); psmewMW->draw (); psrwRW->draw (); void DEBUGWINDOW::vActualiza () psmawMW->draw (); psmewMW->draw (); psrwRW->draw (); void DEBUGWINDOW::vResetAll () psmawMW->vResetParams (); psmawMW->draw (); DEBUGWINDOW::~DEBUGWINDOW () word DEBUGWINDOW::wObtenPosInstruccion () return (psmawMW->wObtenPosicion()); word DEBUGWINDOW::wObtenRegistroSel () return (psrwRW->wRegistroSel());

Page 318: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

313

void DEBUGWINDOW::vFijaSegOffVolMem (word wSeg, wo rd wOff) psmewMW->vFijaSegmentoOffset (wSeg, wOff); void DEBUGWINDOW::vFijaPosEXE (word wPos) psmawMW->vFijaPosicionEXE (wPos); word DEBUGWINDOW::wObtenPosEXE () return (psmawMW->wObtenPosicionEXE()); MAQWINDOW::MAQWINDOW (const TRect& pstrBounds, TSc rollBar *pstsbHScrollBar, TScrollBar *pstsbVScrollBar, byte *pbBuf, word wLen): TScroller (pstrBounds, pstsbHScrollBar, pstsbVScro llBar) word x; options = options | ofFramed; iPosCur = CERO+1; //Se inician en 1, primer ren glon wPosExe = CERO; //Se inician en cero for (x=0; x<DBGMAQ_MAXREN; x++) wPosRen[x] = CER O; //Se inician los renglones pbBufCod = pbBuf; wLenBuf = wLen; wLenFirst = CERO + 1; //Al menos un byte setLimit (maxLineLength, wLen); void MAQWINDOW::draw() ushort usColor; char scAux[maxLineLength]; char scText[50], scNum[10]; TRect strR; int i; word wPos, x, y, iRen; TDrawBuffer stdbAux; strR = getBounds (); i = strR.b.y - strR.a.y; if (iPosCur>i) iPosCur = i; wPos = delta.y; wLenFirst = CERO; for (i=0, iRen=CERO+1; i<size.y; i++, iRen++) if (iRen==iPosCur) usColor = USCOL_MAQSEL; else usColor = USCOL_MAQNOR; wPosRen[i] = wPos; //ERR no se ha fijado un l imite stdbAux.moveChar (0, ' ', usColor, size.x); / /Llena de blancos x = wMAQ2ASM (scText, pbBufCod, wPos, DEPURA_R EF, wLenBuf); if (!wLenFirst) wLenFirst = x; //Longitud de la primera instruccion y = wPos + x; if ((wPosExe>=wPos)&&(wPosExe<y)) sprintf (scAux, " þ CS:%04X ", wPos); if (iRen!=iPosCur) usColor = USCOL_MAQSTP; else sprintf (scAux, " CS:%04X ", wPos); for (y=0; y<10; y++) if (y<x) sprintf (scNum, "%02X", *(pbBufCod+ wPos+y)); else sprintf (scNum, " "); strcat (scAux, scNum); wPos = wPos + x; if (wPos>=wLenBuf) //Se reinicia el scroll y su posicion wPos = CERO; vCambiaVScroll (1);

Page 319: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

314

strcat (scAux, scText); if (delta.x>strlen(scAux)) scAux[0] = EOS; else for (x=0; x<size.x; x++) scAux[x] = scAux[x+ delta.x]; scAux[x] = EOS; stdbAux.moveCStr (0, scAux, usColor); writeLine (0, i, size.x, 1, stdbAux); void MAQWINDOW::handleEvent(TEvent& psteEvent) int x; TRect strR; strR = getBounds (); x = strR.b.y - strR.a.y; if(TSTBIT(psteEvent.what, evKeyboard)) switch (psteEvent.keyDown.keyCode) //Intercepta teclas Arriba y Abajo case kbUp: //Arriba iPosCur--; if (iPosCur<1) iPosCur = 1; vCambiaVScroll (delta.y-1); draw (); break; case kbDown: //Abajo iPosCur++; if (iPosCur>x) iPosCur = x; vCambiaVScroll (delta.y+wLenFirst); draw (); break; case kbPgDn: //Pagina abajo vCambiaVScroll (wPosRen[size.y-1]); draw (); break; default: TScroller::handleEvent(psteEvent); return; clearEvent (psteEvent); return; if(TSTBIT(psteEvent.what, evMouseDown)) //Intercepta un click del raton TPoint stpMouse; stpMouse = makeLocal (psteEvent.mouse.where); iPosCur = stpMouse.y + 1; draw (); TScroller::handleEvent(psteEvent); inline void MAQWINDOW::vCambiaVScroll (int iPos) drawLock = True; vScrollBar->setValue(iPos); drawLock = False; void MAQWINDOW::vResetParams () iPosCur = CERO + 1;

Page 320: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

315

wPosExe = CERO; vScrollBar->setValue(0); word MAQWINDOW::wObtenPosicion () return (wPosRen[iPosCur-1]); //Menos 1 ya que i PosCur es por renglon void MAQWINDOW::vFijaPosicionEXE (word wPos) wPosExe = wPos; vScrollBar->setValue(wPos); iPosCur = CERO+1; draw (); word MAQWINDOW::wObtenPosicionEXE () return (wPosExe); byte MAQWINDOW::bBytesPosEXE () word x; for (x=0; x<DBGMAQ_MAXREN; x++) if (wPosRen[x]==wPosExe) return (wPosRen[x+1]-wPosRen[x]); return (CERO); MEMWINDOW::MEMWINDOW (const TRect& pstrBounds, TSc rollBar *pstsbHScrollBar, TScrollBar *pstsbVScrollBar, byte *pbBuf, word wLen, byte bTBl k, word wSeg, word wOffS): TScroller (pstrBounds, pstsbHScrollBar, pstsbVScro llBar) short sMaxLX, sMaxLY; pbBufMem = pbBuf; wLenBuf = wLen; bTamBlk = bTBlk; //Longitud de cada bloque de m emoria a presentar wSegMem = wSeg; wOffSet = wOffS; iPosCur = CERO; //Posicion del cursor options = options | ofFramed; //Margen + DIR + 1 Margen + Cod con Margen + Car acter + 1 Margen sMaxLX = 1 + 5 + (bTamBlk * 3) + bTamBlk + 1; sMaxLY = wLen / bTamBlk; setLimit (sMaxLX, sMaxLY); void MEMWINDOW::draw() //Coloca el volcado de memoria word wPos, x, y; ushort usColor; TDrawBuffer stdbBuff; char scAux[maxLineLength]; char scAux2[10]; for (int i=0; i<size.y; i++) if (i==iPosCur) usColor = USCOL_MEMSEL; else usColor = USCOL_MEMNOR; stdbBuff.moveChar (0, ' ', usColor, size.x); //Llena de blancos wPos = (delta.y + i) * bTamBlk; //Construye lo que se ve del volcado de memori a scAux[CERO] = CERO; //Primero la posicion sprintf (scAux, " %04X:%04X ", wSegMem, (wOff Set+wPos)); //Primero coloca los codigos for (x=0; x<bTamBlk; x++) sprintf (scAux2, "%02X ", *(pbBufMem+wPos+x) ); strcat (scAux, scAux2);

Page 321: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

316

//Ahora el caracter for (x=0; scAux[x]; x++); scAux[x] = 32; x++; for (y=0; y<bTamBlk; y++, wPos++) if ((*(pbBufMem+wPos)>0x20)&&(*(pbBufMem+wPo s)<0x7E)) scAux[x] = (char)(*(pbBufMem+wPos)); else scAux[x] = 46; x++; scAux[x] = CERO; //En x se queda la longitud if (delta.x>x) scAux[CERO] = CERO; else if (delta.x) for (x=0; x<size.x; x++) scAux[x] = scAux[ x+delta.x]; scAux[x] = CERO; stdbBuff.moveCStr (0, scAux, usColor); writeLine (0, i, size.x, 1, stdbBuff); void MEMWINDOW::vFijaSegmentoOffset (word wSeg, wo rd wOff) wSegMem = wSeg; wOffSet = wOff; draw (); void MEMWINDOW::handleEvent(TEvent& psteEvent) TRect strR; int x; strR = getBounds (); x = strR.b.y - strR.a.y; if(TSTBIT(psteEvent.what, evKeyboard)) switch (psteEvent.keyDown.keyCode) //Intercepta teclas Arriba y Abajo case kbUp: //Arriba iPosCur--; if (iPosCur<0) iPosCur = 0; if (limit.y>x) drawLock = True; vScrollBar->setValue(delta.y-1); drawLock = False; draw (); break; case kbDown: //Abajo iPosCur++; if (limit.y>x) if (iPosCur>=x) iPosCur = x - 1; drawLock = True; vScrollBar->setValue(delta.y+1); drawLock = False; draw (); break; default: TScroller::handleEvent(psteEvent);

Page 322: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

317

return; clearEvent (psteEvent); return; if(TSTBIT(psteEvent.what, evMouseDown)) //Intercepta un click del raton TPoint stpMouse; stpMouse = makeLocal (psteEvent.mouse.where); iPosCur = stpMouse.y; draw (); TScroller::handleEvent(psteEvent); REGWINDOW::REGWINDOW (const TRect& pstrBounds, TSc rollBar *pstsbHScrollBar, TScrollBar *pstsbVScrollBar, char *pcBuf, byte bLenR, byte bNu mR): TScroller (pstrBounds, pstsbHScrollBar, pstsbVScro llBar) pcBufReg = pcBuf; bNumReg = bNumR; bLenReg = bLenR; iPosCur = CERO; options = options | ofFramed; setLimit (bLenR, bNumR); //Los limites son fijo s void REGWINDOW::draw() //Coloca los registros ushort usColor; TRect strR; int j; char scAux[maxLineLength]; TDrawBuffer stdbBuff; strR = getBounds (); j = strR.b.y - strR.a.y; if (iPosCur>=j) iPosCur = j - 1; for (int i=0; i<size.y; i++) j = delta.y + i; if (i==iPosCur) usColor = USCOL_REGSEL; else usColor = USCOL_REGNOR; stdbBuff.moveChar (0, ' ', usColor, size.x); //Llena de blancos if (j<bNumReg) if (delta.x>bLenReg) scAux[0] = EOS; else strncpy (scAux, pcBufReg+(j*bLenReg)+delta .x, size.x); scAux[size.x] = EOS; stdbBuff.moveCStr (0, scAux, usColor); writeLine (0, i, size.x, 1, stdbBuff); void REGWINDOW::handleEvent(TEvent& psteEvent) TRect strR; int x; strR = getBounds (); x = strR.b.y - strR.a.y; if(TSTBIT(psteEvent.what, evKeyboard)) switch (psteEvent.keyDown.keyCode) //Intercepta teclas Arriba y Abajo case kbUp: //Arriba iPosCur--; if (iPosCur<0)

Page 323: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

318

iPosCur = 0; if (limit.y>x) vCambiaVScroll (delta.y-1 ); draw (); break; case kbDown: //Abajo iPosCur++; if (limit.y>x) if (iPosCur>=x) iPosCur = x - 1; vCambiaVScroll (delta.y+1); else if (iPosCur>=bNumReg) iPosCur = bNumReg - 1; draw (); break; default: TScroller::handleEvent(psteEvent); return; clearEvent (psteEvent); return; if(TSTBIT(psteEvent.what, evMouseDown)) //Intercepta un click del raton TPoint stpMouse; stpMouse = makeLocal (psteEvent.mouse.where); iPosCur = stpMouse.y; if (iPosCur>=bNumReg) iPosCur = bNumReg - 1; draw (); TScroller::handleEvent(psteEvent); inline void REGWINDOW::vCambiaVScroll (int iPos) drawLock = True; vScrollBar->setValue(iPos); drawLock = False; word REGWINDOW::wRegistroSel () //Regresa el registro seleccionado return (iPosCur);

F.26 DEC2ASM.CPP #include <stdio.h> #include <stdlib.h> #include <string.h> #include <conio.h> #include <alloc.h> #include <lib.h> #include <ctype.h> #include "define.h" #include "asmmaq.h" byte bIniciaMAQ (word wMemoriaMAQ) /*Inicia para convertir de maquina a ASM*/ pBCodMaq = CERO; WLenCod = CERO; WLenCodMaq = CERO; if (!wMemoriaMAQ) return (FALSE); pBCodMaq = (byte *)farmalloc (wMemoriaMAQ);

Page 324: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

319

if (!pBCodMaq) return (FALSE); WLenCodMaq = wMemoriaMAQ; vCargaDescriptores (); return (TRUE); void vTerminaMAQ () /*Termina MAQ*/ if (pBCodMaq) farfree (pBCodMaq); /*En este caso se retorna el numero de bytes de la instruccions; en */ /*caso de no conocer la instruccion se retorna un DB con el codigo. */ /*En pcTxt se almacena la instruccion, por lo que es necesario */ /*asignar suficiente espacio (unos 50 bytes minimo ). Esta funcion */ /*funciona instruccion por instruccion. */ /*Nota: Hay que tener cuidado con el tama¤o (wLen) de pbCod. wRef */ /*es la referencia y solo sirve en instrucciones c on salto. */ word wMAQ2ASM (char *pcTxt, char *pbCod, word wPos , word wRef, word wLen) word y; *pcTxt = CERO; /*Se fija la cadena de retorno*/ y = wDecodINoArg (pcTxt, pbCod, wPos, wLen); /*S in argumentos*/ if (y==wPos) y = wDecodIEsp (pcTxt, pbCod, wPos, wLen); /*Especiales*/ if (y==wPos) y = wDecodIUnArg (pcTxt, pbCod, wPos, wLen, wRef+wPos); /*Con un argumento*/ if (y==wPos) y = wDecodIDosArg (pcTxt, pbCod, wPos, wLe n); /*Con dos argumentos*/ if (y==wPos) /*No se pudo decodificar, se toma como D B*/ vFijaDB (pcTxt, *(pbCod+wPos)); y++; return (y-wPos); /*Bytes de la instruccion*/ word wDecodINoArg (char *pcTxt, char *pbCod, word wPos, word wLen) word x, y, z; byte bFlag; for (x=0; x<LEN_INOARG; x++) bFlag = TRUE; for (y=0; y<sBCodIntNoArgs[x][DESI_NCOD]; y++) z = y + wPos; if (sBCodIntNoArgs[x][DESI_COD+y]!=*(pbCod+z )) bFlag = FALSE; if ((bFlag)&&(z<=wLen)) /*Se ha encontrado el codigo*/ strcat (pcTxt, sCInstNoArgs[x]); return (z+1); return (wPos); void vFijaDB (char *pcTxt, byte bCod) *(pcTxt+CERO) = CERO; strcat (pcTxt, sCResWord[ID_RW_DB]); /*Coloca D B*/ vAgregaNum (pcTxt, bCod, COD_IMM08, CHAR_ESP); word wDecodIEsp (char *pcTxt, char *pbCod, word wP os, word wLen)

Page 325: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

320

word w=wPos, x=CERO, y, z; byte bFlag, bNoSalir=CERO+1; while (bNoSalir) for (; x<ID_IESP_B; x++) /*Con esto ya no rev isa otras que no son instrucciones*/ bFlag = TRUE; for (y=0; y<sBCodInstEspe[x][DESI_NCOD]; y++ ) /*Revisa el codigo(s) de la instruccion*/ z = y + wPos; if (sBCodInstEspe[x][DESI_COD+y]!=*(pbCod+ z)) bFlag = FALSE; if ((bFlag)&&(z<wLen)) /*Se ha encontrado el codigo*/ if (bNoSalir>CERO+1) strcat (pcTxt, " "); strcat (pcTxt, sCInstEspe[x]); if ((x<ID_IESP_C)&&(bNoSalir<=CERO+1)) /*C on esto se sabe si es REPXXX*/ /*Revisa la existencia de un CMPXX, SCAS XX, etc*/ bNoSalir++; wPos++; x = ID_IESP_C; w = z + 1; break; else return (z+1); if (x>=ID_IESP_B) return (w); return (wPos); void vAgregaNum (char *pcTxt, dword dNum, word wTi po, char cPlus) /*Aqui deberia existir el cambio si se desea imp rimir numeros en otras bases*/ char scNum[13], bPos=CERO; if (cPlus) scNum[0] = cPlus; bPos++; scNum[bPos] = 48; bPos++; switch (wTipo) case COD_IMM08: dNum = dNum & 0x000000FF; /*Lo hace de 8 bi ts*/ case COD_IMM16: case COD_NUMH16: if (wTipo!=COD_IMM08) /*Hace un reacomodo*/ if (dNum<0x10) scNum[bPos] = 48; bPos++ ; /*Lo hace de 16 bits*/ if (dNum<0x100) scNum[bPos] = 48; bPos+ +; /*Lo hace de 16 bits*/ itoa ((word)dNum, scNum+bPos, BASE_NUMP); break; case COD_IMM32: if (dNum<0x10000) /*Lo hace de 32 bits*/ scNum[bPos] = 48; bPos++; scNum[bPos] = 48; bPos++; scNum[bPos] = 48; bPos++; ltoa ((word)dNum, scNum+bPos, BASE_NUMP); break; for (wTipo=0; scNum[wTipo]; wTipo++) scNum[wTipo ] = toupper (scNum[wTipo]); strcat (pcTxt, scNum); strcat (pcTxt, "H"); byte bObtenArgumento (byte bArg, byte bTipo) /*regresa el argumento, por LEY existe nunca toc a CERO*/ byte x; if (bTipo==MODRM_MRM) for (x=0; x<LEN_REG16; x++) /*ERR Se usa REG1 6 ya que es el mismo numero que REG08*/ if (bArg==sBModosReg_1[x]) return (CMP_REG|x ); /*ERR no es posible usar BX+BP+SI+DI*/

Page 326: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

321

if (bTipo==MODRM_REG) for (x=0; x<LEN_REG16; x++) /*ERR Se usa REG1 6 ya que es el mismo numero que REG08*/ if (bArg==sBModosReg_2[x]) return (CMP_REG|x ); /*ERR no es posible usar BX+BP+SI+DI*/ for (x=0; x<LEN_RM_DIR; x++) if (bArg==sBModosDir[x][1]) return (sBModosDir [x][0]); return (CERO); /*Jamas pasa por este camino*/ byte bObtenArgumentoSeg (byte bArg) /*regresa el argumento, por LEY existe nunca toc a CERO*/ byte x; for (x=0; x<LEN_SEG; x++) if (bArg==sBModosSeg_1[x]) return (x); for (x=0; x<LEN_SEG; x++) /*ERR Se usa REG16 ya que es el mismo numero que REG08*/ if (bArg==sBModosSeg_2[x]) return (x); return (CERO); /*Jamas pasa por este camino*/ word wDecodIUnArg (char *pcTxt, byte *pbCod, word wPos, word wLen, word wRef) word x, wCod, wLenI; /*x lleva el conteo de ins trucciones, wCod apunta al sig byte*/ word wCMP; /*El comparador y como el que retorna el valor del sig codigo*/ int iCod; byte bFlag, bAux, bSalir=FALSE; wLenI = wNumOpcDescriptor (DESCRIP_UN); for (x=0; (x<wLenI)&&(!bSalir); x++) bFlag = FALSE; *(pcTxt+CERO) = CERO; wCMP = CREAWORD (sBCodIntUnArg[x][CI1A_POS_CMP H], sBCodIntUnArg[x][CI1A_POS_CMPL]); if (!TSTBIT(sBCodIntUnArg[x][CI1A_POS_RM], RM_ S)) /*Solo si no es suma, entra a este codigo*/ wCod = wChkCodigo (pbCod, sBCodIntUnArg[x], wPos); /*Verifica el codigo*/ if (wCod==wPos) wCMP = COD_NOOPER; /*No hac e nada*/ iCod = iObtenPosDescriptor (DESCRIP_UN, x); / *Pos del texto de instruccion*/ if (iCod>=CERO) strcat (pcTxt, sCInst1Args[iCo d]); else wCMP = COD_NOOPER; bSalir = FALSE; /*Si es TRUE, se encontro*/ switch (wCMP) case COD_NOOPER: break; /*Para no hacer na da, ya que no es codigo*/ case COD_FAR: strcat (pcTxt, " "); strcat (pcTxt, sCInstEspe[ID_IESP_F]); case COD_REG08: case COD_REG16: case COD_REG32: if (TSTBIT(sBCodIntUnArg[x][CI1A_POS_RM], RM_S)) /*Es suma de registros*/ /*ERR Si son dos codigos se debe tomar e n cuenta, pero es raro*/ for (bAux=0; bAux<TOT_REG; bAux++) if (sBCodIntUnArg[x][CI1A_POS_COD]==(* (pbCod+wPos)-bAux)) wCod = wAgregaArg (pcTxt, pbCod, wCo d+1, wCMP, bAux, PTR_NO, FALSE); bAux = TOT_REG; bSalir = TRUE; break; /*Si no es suma, hay que decodificar el byte MOD R/M*/ case COD_rm08: case COD_rm16: case COD_rm32: case COD_MEM08: case COD_MEM16: case COD_MEM32: case COD_MEMORIA: if (!TSTBIT(sBCodIntUnArg[x][CI1A_POS_RM], RM_N)) /*Hay byte RM, pero se asigna*/ if ((sBCodIntUnArg[x][CI1A_POS_RM]&RM_F) ==(*(pbCod+wCod)&RM_F)) bAux = *(pbCod+wCod) & RM_C; wCod++; bSalir = TRUE; bAux = bObtenArgumento (bAux, MODRM_MR M); /*Obtenemos el argumento*/ if ((bAux&CMP_REG)==CMP_REG) /*Es un r egistro*/

Page 327: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

322

bAux = bAux & ~CMP_REG; wCod = wAgregaArg (pcTxt, pbCod, wCo d, wCMP&COD_REG, bAux, PTR_NO, FALSE); if (wCMP==COD_FAR) /*Instruccion no valida*/ wCod = wPos; break; else /*Es memoria. Construye el argume nto que esta en bAux*/ wCod = wAgregaArg (pcTxt, pbCod, wCo d, wCMP&COD_MEM, bAux, PTR_BYTE, FALSE); if (TSTBIT(sBCodIntUnArg[x][CI1A_POS_RM], RM_B)) /*Se coloca algo en especifico*/ wCod = wAgregaArg (pcTxt, pbCod, wCod, w CMP, sBCodIntUnArg[x][CI1A_POS_EB], PTR_NO, FALSE); bSalir = TRUE; break; case COD_NUMH16: case COD_IMM32: case COD_IMM16: case COD_IMM08: if (TSTBIT(sBCodIntUnArg[x][CI1A_POS_RM], RM_D)) if (wCMP==COD_IMM08) /*Un byte por instruccion*/ x = CREAWORD (CERO, *(pbCod+wCod)) + ( (wCod-wPos)+1); if (x>0x81) /*ERR se asume se conoce e l num de byts de codigo*/ x = wRef - (((~x) + 1) & 0x00FF); else x = x + wRef; wCod++; /*Resto instruccion*/ else /*Dos bytes por instruccion*/ x = CREAWORD (*(pbCod+wCod+1), *(pbCod +wCod)) + ((wCod-wPos)+2); if (x>0x8002) /*ERR se asume se conoce el num de byts de codigo*/ x = wRef - ((~x) + 1); else x = x + wRef; bFlag++; wCod++; wCod++; vAgregaNum (pcTxt, x, COD_IMM16, CHAR_ES P); else wCod = wAgregaArg (pcTxt, pbCod, wCod, w CMP, CERO, PTR_NO, FALSE); bSalir = TRUE; break; case COD_SEG: /*Los registros de segmento so n mas especificos*/ if (TSTBIT(sBCodIntUnArg[x][CI1A_POS_RM], RM_S)) /*Es suma de registros*/ /*ERR Si son dos codigos se debe tomar e n cuenta*/ for (bAux=0; bAux<TOT_SEG; bAux++) if (sBCodIntUnArg[x][CI1A_POS_COD]==(* (pbCod+wPos)-sBSegPref[bAux])) bFlag = TRUE; wCod = wPos + 1; bre ak; if (TSTBIT(sBCodIntUnArg[x][CI1A_POS_RM], RM_B)) bFlag = TRUE; bAux = sBCodIntUnArg[x][CI1A_POS_EB]; if (bFlag) bFlag = wAgregaArg (pcTxt, pbCod, wCod, wCMP, bAux, PTR_NO, FALSE); bSalir = TRUE; break; case COD_PUNTERO: if (TSTBIT(sBCodIntUnArg[x][CI1A_POS_RM], RM_N|RM_D))

Page 328: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

323

wCod = wAgregaArg (pcTxt, pbCod, wCod, w CMP, CERO, PTR_NO, FALSE); bSalir = TRUE; break; /*No se decodifico nada*/ if ((wCod>wLen)||(!bSalir)) return (wPos); return (wCod); word wChkCodigo (byte *pbCod, byte *pbCodArgs, wor d wPos) /*retorna hasta donde son iguales + 1 o wPos en caso de error*/ word y, z; for (y=0; y<*(pbCodArgs+CI1A_POS_LEN); y++) /*ERR Se asume que CI1A_POS_LEN=CI2A_POS_LEN y CI1A_POS_COD=CI2A_POS_COD*/ z = y + wPos; if (*(pbCodArgs+CI1A_POS_COD+y)!=*(pbCod+z)) r eturn (wPos); /*Retorna wPos*/ return (z+1); /*Si es igual termina en wPos+num bytes de codigo*/ word wAgregaArg (char *pcTxt, byte *pbCod, word wC od, word wCMP, byte bArg, byte bPTR, byte bCOMA) /*Agrega un argumento*/ word x; byte bFlag=FALSE; if ((wCMP&COD_MEM08)&&(bPTR==PTR_BYTE)) /*BYTE PTR*/ strcat (pcTxt, " "); strcat (pcTxt, sCInstEspe[ID_IESP_B]); strcat (pcTxt, " "); strcat (pcTxt, sCInstEspe[ID_IESP_P]); if ((wCMP&COD_MEM16)&&(bPTR==PTR_WORD)) /*BYTE PTR*/ strcat (pcTxt, " "); strcat (pcTxt, sCInstEspe[ID_IESP_W]); strcat (pcTxt, " "); strcat (pcTxt, sCInstEspe[ID_IESP_P]); strcat (pcTxt, " "); switch (wCMP) case COD_REG08: strcat (pcTxt, sCRegistro08[bArg]); break; case COD_REG16: strcat (pcTxt, sCRegistro16[bArg]); break; case COD_REG32: break; case COD_MEM08: case COD_MEM16: case COD_MEM32: case COD_MEMORIA: strcat (pcTxt, "["); if (TSTBIT(bArg, FDIR_BX)) if (bFlag) strcat (pcTxt, "+"); strcat (pcTxt, sCRegistro16[ID_REGDIR0]); bFlag = TRUE; if (TSTBIT(bArg, FDIR_BP)) if (bFlag) strcat (pcTxt, "+"); strcat (pcTxt, sCRegistro16[ID_REGDIR1]); bFlag = TRUE; if (TSTBIT(bArg, FDIR_SI)) if (bFlag) strcat (pcTxt, "+"); strcat (pcTxt, sCRegistro16[ID_REGDIR2]); bFlag = TRUE;

Page 329: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

324

if (TSTBIT(bArg, FDIR_DI)) if (bFlag) strcat (pcTxt, "+"); strcat (pcTxt, sCRegistro16[ID_REGDIR3]); bFlag = TRUE; /*Ahora, si exite un numero, lo agrega*/ if (TSTBIT(bArg, FDIR_N16|FDIR_N08)) if (bFlag) bFlag = '+'; if (TSTBIT(bArg, FDIR_N16)) x = CREAWORD (*(pbCod+wCod+1), *(pbCod+w Cod)); if (bFlag) /*Revisa signos*/ /*ERR Con bFlag se sabe si es solo [DI SP16]*/ if (x>=0x8000) x = ~x + 1; if (bFlag) bFlag = '-'; vAgregaNum (pcTxt, x, COD_IMM16, bFlag); wCod++; else x = CREAWORD (CERO, *(pbCod+wCod)); if (x>=0x80) x = ~x + 1; if (bFlag) bFlag = '-'; vAgregaNum (pcTxt, x, COD_IMM08, bFlag); wCod++; strcat (pcTxt, "]"); break; case COD_IMM08: x = CREAWORD (CERO, *(pbCod+wCod)); wCod++; vAgregaNum (pcTxt, x, wCMP, CERO); break; case COD_NUMH16: case COD_IMM16: case COD_IMM32: x = CREAWORD (*(pbCod+wCod+1), *(pbCod+wCod) ); wCod++; wCod++; vAgregaNum (pcTxt, x, wCMP, CERO); break; case COD_SEG: strcat (pcTxt, sCSegmento[bArg]); break; case COD_PUNTERO: x = CREAWORD (*(pbCod+wCod+3), *(pbCod+wCod+ 2)); vAgregaNum (pcTxt, x, COD_IMM16, CERO); x = CREAWORD (*(pbCod+wCod+1), *(pbCod+wCod) ); vAgregaNum (pcTxt, x, COD_IMM16, CHAR_2PUN); wCod = wCod + 4; break; case COD_FAR: break; default: /*!ERR se asume ESC*/ x = (*(pbCod) & ESC_COD_L) << ESC_COD_R; x = x | ((*(pbCod+1) & ESC_COD_H) >> ESC_COD _R); vAgregaNum (pcTxt, x, COD_IMM08, CERO); break; if (bCOMA) strcat (pcTxt, ","); return (wCod); word wDecodIDosArg (char *pcTxt, char *pbCod, word wPos, word wLen)

Page 330: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

325

word x, wCod, wLenI; /*x lleva el conteo de ins trucciones, wCod apunta al sig byte**/ word wCMP[2]; /*El comparador y como el que reto rna el valor del sig codigo*/ int iCod; byte bAux[2], bSalir=FALSE, bArg1; wLenI = wNumOpcDescriptor (DESCRIP_DOS); for (x=0; (x<wLenI)&&(!bSalir); x++) *(pcTxt+CERO) = CERO; wCMP[0] = CREAWORD (sBCodIntDosArg[x][CI2A_POS _CMPH1], sBCodIntDosArg[x][CI2A_POS_CMPL1]); wCMP[1] = CREAWORD (sBCodIntDosArg[x][CI2A_POS _CMPH2], sBCodIntDosArg[x][CI2A_POS_CMPL2]); if ((!TSTBIT(sBCodIntDosArg[x][CI2A_POS_RM1], RM_S))&&(!TSTBIT(sBCodIntDosArg[x][CI2A_POS_RM2], R M_S))) /*Solo si no es suma, entra a este codigo*/ wCod = wChkCodigo (pbCod, sBCodIntDosArg[x], wPos); /*Verifica el codigo*/ if (wCod==wPos) wCMP[0] = COD_NOOPER; /*No hace nada*/ iCod = iObtenPosDescriptor (DESCRIP_DOS, x); /*Pos del texto de instruccion*/ if (iCod>=CERO) strcat (pcTxt, sCInst2Args[iCo d]); else wCMP[0] = COD_NOOPER; bArg1 = TRUE; /*Controla los argumentos, prim er argumento*/ switch (wCMP[0]) case COD_NOOPER: break; /*Para no hacer na da, ya que no es codigo valido*/ case COD_REG08: case COD_REG16: case COD_REG32: if ((TSTBIT(sBCodIntDosArg[x][CI2A_POS_RM1 ], RM_S))||(TSTBIT(sBCodIntDosArg[x][CI2A_POS_RM2], RM _S))) /*Codigo se forma de suma*/ if (TSTBIT(sBCodIntDosArg[x][CI2A_POS_RM 1], RM_S)) /*Es suma de registros*/ /*ERR Si son dos codigos se debe tomar en cuenta*/ for (bAux[0]=0; bAux[0]<TOT_REG; bAux[ 0]++) /*Para REG16 y REG08*/ if (sBCodIntDosArg[x][CI2A_POS_COD]= =(byte)(*(pbCod+wPos)-bAux[0])) /*Es suma del primer registro*/ wCod = wAgregaArg (pcTxt, pbCod, w Cod+1, wCMP[0], bAux[0], PTR_NO, TRUE); /*El segundo debe ser un EXTRA BYT E o un numero*/ if (TSTBIT(sBCodIntDosArg[x][CI2A_ POS_RM2], RM_B)) /*Es extra byte*/ wCod = wAgregaArg (pcTxt, pbCod, wCod, wCMP[1], sBCodIntDosArg[x][CI2A_POS_EB2], PTR_NO, FALSE); else /*Tiene que ser un numero*/ wCod = wAgregaArg (pcTxt, pbCod, wCod, wCMP[1], CERO, PTR_NO, FALSE); bSalir = TRUE; bAux[0] = TOT_REG; if (bSalir) break; /*Si no es suma, hay que decodificar e l byte MOD R/M*/ else /*Suma de segundo registro*/ /*ERR Si son dos codigos se debe tomar en cuenta*/ for (bAux[0]=0; bAux[0]<TOT_REG; bAux[ 0]++) /*Para REG16 y REG08*/ if (sBCodIntDosArg[x][CI2A_POS_COD]= =(byte)(*(pbCod+wPos)-bAux[0])) /*Es suma del segundo registro*/ if (TSTBIT(sBCodIntDosArg[x][CI2A_ POS_RM1], RM_B)) /*Es extra byte*/ wCod = wAgregaArg (pcTxt, pbCod, wCod+1, wCMP[1], sBCodIntDosArg[x][CI2A_POS_EB1], PTR_NO, TRUE); else /*Tiene que ser un numero*/ wCod = wAgregaArg (pcTxt, pbCod, wCod+1, wCMP[1], CERO, PTR_NO, TRUE); wCod = wAgregaArg (pcTxt, pbCod, w Cod, wCMP[0], bAux[0], PTR_NO, FALSE); /*El segundo debe ser un EXTRA BYT E o un numero*/ bSalir = TRUE; bAux[0] = TOT_REG; if (bSalir) break; break; /*No es suma, siguiente codigo*/ case COD_rm08: case COD_rm16: case COD_rm32: case COD_MEM08: case COD_MEM16:

Page 331: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

326

case COD_MEM32: case COD_MEMORIA: if ((TSTBIT(sBCodIntDosArg[x][CI2A_POS_RM1 ], RM_N))&&(TSTBIT(sBCodIntDosArg[x][CI2A_POS_RM2], RM _N))) /*No hay byte, no se creo R/M (1 1)*/ if (TSTBIT(sBCodIntDosArg[x][CI2A_POS_RM 1], RM_B)) wCod = wAgregaArg (pcTxt, pbCod, wCod, wCMP[0], sBCodIntDosArg[x][CI2A_POS_EB1], PTR_NO, TRUE); bArg1 = FALSE; /*Para colocar la COMA */ if ((TSTBIT(sBCodIntDosArg[x][CI2A_POS_R M2], RM_B))&&(!bArg1)) wCod = wAgregaArg (pcTxt, pbCod, wCod, wCMP[1], sBCodIntDosArg[x][CI2A_POS_EB2], PTR_NO, FALSE); else if ((wCMP[0]&COD_NUMH16)&&(!bArg1)) wCod = wAgregaArg (pcTxt, pbCod, wCo d, wCMP[0], CERO, PTR_NO, FALSE); else if ((wCMP[1]&COD_NUMH16)&&(!bArg1)) wCod = wAgregaArg (pcTxt, pbCod, w Cod, wCMP[1], CERO, PTR_NO, FALSE); else wCod = wPos; break; /*No se enco ntro o hay error*/ bSalir = TRUE; if ((TSTBIT(sBCodIntDosArg[x][CI2A_POS_RM1 ], RM_N))&&(!TSTBIT(sBCodIntDosArg[x][CI2A_POS_RM2], R M_N))) /*Se decodifica byte R/M (1 0)*/ if (wCMP[1]==COD_SEG) /*Segmento*/ bAux[1] = bObtenArgumentoSeg (BYTE_REG (*(pbCod+wCod))); bAux[0] = bObtenArgumento (BYTE_MOD_RM (*(pbCod+wCod)), MODRM_MRM); wCod++; if ((bAux[0]&CMP_REG)==CMP_REG) /*Es u n registro*/ bAux[0] = bAux[0] & ~(CMP_REG); wCod = wAgregaArg (pcTxt, pbCod, wCo d, wCMP[0]&COD_REG, bAux[0], PTR_NO, TRUE); else /*Es memoria*/ wCod = wAgregaArg (pcTxt, pbCod, wCo d, wCMP[0]&COD_MEM, bAux[0], PTR_NO, TRUE); /*No es necesario comprobar los argume ntos, ya que simpre quedan los dos*/ wCod = wAgregaArg (pcTxt, pbCod, wCod, wCMP[1], bAux[1], PTR_NO, FALSE); else if (wCMP[0]&COD_MEM) /*ERR Se basa en el hecho de que no existe dos memorias como argumento*/ bAux[1] = bObtenArgumento (BYTE_REG( *(pbCod+wCod)), MODRM_REG); bAux[0] = bObtenArgumento (BYTE_MOD_ RM(*(pbCod+wCod)), MODRM_MRM); wCod++; if (wCMP[1]&COD_MEM) /*ERR Se basa en el hecho de que no existe dos memorias como argumento*/ bAux[0] = bObtenArgumento (BYTE_REG( *(pbCod+wCod)), MODRM_REG); bAux[1] = bObtenArgumento (BYTE_MOD_ RM(*(pbCod+wCod)), MODRM_MRM); wCod++; if ((bAux[0]&CMP_REG)==CMP_REG) /*Es u n registro*/ bAux[0] = bAux[0] & ~(CMP_REG); wCod = wAgregaArg (pcTxt, pbCod, wCo d, wCMP[0]&COD_REG, bAux[0], PTR_NO, TRUE); else /*Es memoria*/ wCod = wAgregaArg (pcTxt, pbCod, wCo d, wCMP[0]&COD_MEM, bAux[0], PTR_NO, TRUE); /*No es necesario comprobar los argume ntos, ya que simpre quedan los dos*/ if ((bAux[1]&CMP_REG)==CMP_REG) /*Es u n registro*/ bAux[1] = bAux[1] & (~CMP_REG); wCod = wAgregaArg (pcTxt, pbCod, wCo d, wCMP[1]&COD_REG, bAux[1], PTR_NO, FALSE); else /*Es memoria*/

Page 332: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

327

wCod = wAgregaArg (pcTxt, pbCod, wCo d, wCMP[1]&COD_MEM, bAux[1], PTR_NO, FALSE); bSalir = TRUE; if ((!TSTBIT(sBCodIntDosArg[x][CI2A_POS_RM 1], RM_N))&&(!TSTBIT(sBCodIntDosArg[x][CI2A_POS_RM2], R M_N))) /*Se define el byte RM (0 0)*/ if (BYTE_REG(sBCodIntDosArg[x][CI2A_POS_ RM1])==BYTE_REG(*(pbCod+wCod))) bAux[0] = bObtenArgumento (BYTE_MOD_RM (*(pbCod+wCod)), MODRM_MRM); bAux[1] = PTR_NO; wCod++; /*Sevira para definir el PTR*/ if (wCMP[1]==COD_IMM08) if ((wCMP[0]&COD_REG16)||(wCMP[0]&CO D_MEM16)) bAux[1] = PTR_WORD; else bAux[1] = PTR_BYTE; else bAux[1] = PTR_WORD; if ((bAux[0]&CMP_REG)==CMP_REG) /*Es u n registro*/ bAux[0] = bAux[0] & ~(CMP_REG); bAr g1 = FALSE; wCod = wAgregaArg (pcTxt, pbCod, wCo d, wCMP[0]&COD_REG, bAux[0], bAux[1], TRUE); else /*Es memoria*/ wCod = wAgregaArg (pcTxt, pbCod, wCo d, wCMP[0]&COD_MEM, bAux[0], bAux[1], TRUE); if ((TSTBIT(sBCodIntDosArg[x][CI2A_POS _RM1], RM_B))||(TSTBIT(sBCodIntDosArg[x][CI2A_POS_RM2], RM _B))) /*Solo agrega numero de extra byte*/ if (TSTBIT(sBCodIntDosArg[x][CI2A_PO S_RM1], RM_B)) wCod = wAgregaArg (pcTxt, pbCod, w Cod, wCMP[0], sBCodIntDosArg[x][CI2A_POS_EB1], PTR_NO, FALSE); else wCod = wAgregaArg (pcTxt, pbCod, w Cod, wCMP[1], sBCodIntDosArg[x][CI2A_POS_EB2], PTR_NO, FALSE); else wCod = wAgregaArg (pcTxt, pbCod, wCo d, wCMP[1], CERO, PTR_NO, FALSE); bSalir = TRUE; if ((!TSTBIT(sBCodIntDosArg[x][CI2A_POS_RM 1], RM_N))&&(TSTBIT(sBCodIntDosArg[x][CI2A_POS_RM2], RM _N))) /*No hay numero despues (0 1)*/ if (BYTE_REG(sBCodIntDosArg[x][CI2A_POS_ RM1])==BYTE_REG(*(pbCod+wCod))) bAux[0] = bObtenArgumento (BYTE_MOD_RM (*(pbCod+wCod)), MODRM_MRM); bAux[1] = PTR_NO; wCod++; /*Sevira para definir el PTR*/ if ((wCMP[0]&COD_REG16)||(wCMP[0]&COD_ MEM16)) bAux[1] = PTR_WORD; else bAux[1] = PTR_BYTE; if ((bAux[0]&CMP_REG)==CMP_REG) /*Es u n registro*/ bAux[0] = bAux[0] & ~(CMP_REG); wCod = wAgregaArg (pcTxt, pbCod, wCo d, wCMP[0]&COD_REG, bAux[0], bAux[1], TRUE); else /*Es memoria*/ wCod = wAgregaArg (pcTxt, pbCod, wCo d, wCMP[0]&COD_MEM, bAux[0], bAux[1], TRUE); if (TSTBIT(sBCodIntDosArg[x][CI2A_POS_ RM1], RM_B)) /*Solo agrega numero de extra byte*/ vAgregaNum (pcTxt, sBCodIntDosArg[x] [CI2A_POS_EB1], COD_IMM08, CHAR_ESP); else if (TSTBIT(sBCodIntDosArg[x][CI2A_PO S_RM2], RM_B)) /*Solo agrega numero de extra byte*/ vAgregaNum (pcTxt, sBCodIntDosArg[ x][CI2A_POS_EB2], COD_IMM08, CHAR_ESP); else wCod = wPos; break; /*Erro r no se encontro codigo*/ bSalir = TRUE; break; case COD_NUMH16: case COD_IMM32: case COD_IMM16: case COD_IMM08: /*En teoria solo para OUT y ESC*/ if ((TSTBIT(sBCodIntDosArg[x][CI2A_POS_RM1 ], RM_N))&&(TSTBIT(sBCodIntDosArg[x][CI2A_POS_RM2], RM _N)))

Page 333: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

328

/*(1 1)*/ if (TSTBIT(sBCodIntDosArg[x][CI2A_POS_RM 1], RM_B)) wCod = wAgregaArg (pcTxt, pbCod, wCod, wCMP[1], sBCodIntDosArg[x][CI2A_POS_EB2], PTR_NO, TRUE); else wCod = wAgregaArg (pcTxt, pbCod, wCod, wCMP[0], CERO, PTR_NO, TRUE); /*No es necesario comprobar los argument os, ya que simpre quedan los dos*/ if (TSTBIT(sBCodIntDosArg[x][CI2A_POS_RM 2], RM_B)) wCod = wAgregaArg (pcTxt, pbCod, wCod, wCMP[1], sBCodIntDosArg[x][CI2A_POS_EB2], PTR_NO, FALSE); else if (wCMP[1]&COD_MEM) bAux[1] = bObtenArgumento (BYTE_REG( *(pbCod+wCod)), MODRM_REG); bAux[0] = bObtenArgumento (BYTE_MOD_ RM(*(pbCod+wCod)), MODRM_MRM); wCod++; wCod = wAgregaArg (pcTxt, pbCod, wCo d, wCMP[1]&COD_MEM, bAux[0], bAux[1], FALSE); else wCod = wAgregaArg (pcTxt, pbCod, wCo d, wCMP[1], CERO, PTR_NO, FALSE); bSalir = TRUE; break; case COD_SEG: /*Los registros de segmento so n mas especificos*/ if ((TSTBIT(sBCodIntDosArg[x][CI2A_POS_RM1 ], RM_N))&&(!TSTBIT(sBCodIntDosArg[x][CI2A_POS_RM2], R M_N))) /*ERR Por lo general registros de segmen to llevan RM_B, pero aqui no se aplica asi, ya que es el mismo codigo*/ bAux[1] = bObtenArgumentoSeg (BYTE_REG(* (pbCod+wCod))); bAux[0] = bObtenArgumento (BYTE_MOD_RM(* (pbCod+wCod)), MODRM_MRM); wCod++; wCod = wAgregaArg (pcTxt, pbCod, wCod, w CMP[0], bAux[1], PTR_NO, TRUE); /*No es necesario comprobar los argument os, ya que simpre quedan los dos*/ if ((bAux[0]&CMP_REG)==CMP_REG) /*Es un registro*/ bAux[0] = bAux[0] & ~(CMP_REG); wCod = wAgregaArg (pcTxt, pbCod, wCod, wCMP[1]&COD_REG, bAux[0], PTR_NO, FALSE); else /*Es memoria*/ wCod = wAgregaArg (pcTxt, pbCod, wCod, wCMP[1]&COD_MEM, bAux[0], PTR_NO, FALSE); bSalir = TRUE; break; /*No se decodifico nada*/ if ((wCod>wLen)||(!bSalir)) return (wPos); return (wCod);

F.27 DEPURA.CPP #include <stdio.h> #include <stdlib.h> #include <string.h> #include <conio.h> #include <malloc.h> #include <lib.h> #include "asmmaq.h" #include "define.h" /*CONTIENE ALGUNAS FUNCIONES EMPLEADAS EN LA DEPURACION DEL PROGRAMA*/ void vPrintFlag (word w, byte b) char scBit[20], c, x; printf ("***wIdArg:***************************** **\n"); printf (" | PTR|AXAL|IM32| M32| R32| PRE| FAR | SEG| P |IM16|IM08| M16| M08| R16| R8 |"); itoa (w, scBit, 2);

Page 334: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

329

c = strlen (scBit); for (x=0; x<(16-c); x++) printf (" 0 |"); for (x=0; x<c; x++) printf (" %c |", scBit[x]); printf ("***bFlagDir:*************************** **"); printf ("\n BX | BP | SI | DI | N8 | N16| SIG| ? ? |\n"); itoa (b, scBit, 2); c = strlen (scBit); for (x=0; x<(8-c); x++) printf (" 0 |"); for (x=0; x<c; x++) printf (" %c |", scBit[x]); printf ("\n"); void vPrintInst () inst *psiAux; if (!psIInstruccion) return; psiAux = psIInstruccion; printf ("Instrucciones sin compilar\n"); while (psiAux) printf ("Inst: %s | #Cod: %02X | Ref: %04X\n", psiAux->pcInst, psiAux->bNumCod, psiAux->wRef); /*Instruccion*/ psiAux = psiAux->psiSig; void vPrintLbl () label *pslAux; if (!psLEtiqueta) return; pslAux = psLEtiqueta; clrscr (); while (pslAux) if (pslAux->bTipo==ID_ETIQUETA) printf ("Etiqueta: "); if (pslAux->bNumTipo==ID_LBL_NDF) printf ("N O DEFINIDA\n"); else printf ("DEFINIDA\n"); printf ("Nombre: %s Referencia: %8X\n", pslA ux->pcLabel, pslAux->dRefVal); pslAux = pslAux->pslSig; void vPrintCte () label *pslAux; if (!psLEtiqueta) return; pslAux = psLEtiqueta; clrscr (); while (pslAux) if (pslAux->bTipo==ID_CONSTANTE) printf ("Constante:\n"); printf ("%s = %8X(%d)\n", pslAux->pcLabel, p slAux->dRefVal, pslAux->bTipo); pslAux = pslAux->pslSig;

F.28 DESENSA.CPP /*CONTIENE ALGUNAS FUNCIONES PARA DESENSAMBLAR*/ #include <stdio.h>

Page 335: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

330

#include <stdlib.h> #include <string.h> #include <conio.h> #include <malloc.h> #include <ctype.h> #include <io.h> #include <lib.h> #include "define.h" #include "asmmaq.h" dword dCargaCODIGO (char *pcFile) /*Carga el archivo en memoria, en caso de error retorna FALSE*/ FILE *psfIn; dword dLen; psfIn = fopen (pcFile, "rb"); if (!psfIn) return (FALSE); /*Carga el codigo a analizar*/ dLen = filelength (fileno(psfIn)); if (dLen>WLenCodMaq) return (FALSE); for (WLenCod=CERO; WLenCod<dLen; WLenCod++) *(pBCodMaq+WLenCod) = getc (psfIn); fclose (psfIn); if (!dLen) return (FALSE); return (dLen); void vColocaCODIGO (byte *pbCod, word wPos, byte b Insert) /*Agrega o inserta codigo segun el valor de bIns ert.*/ /*pbCod respeta la estructura de wASM2MAQ */ byte bLenCod; word x, y; bLenCod = *(pbCod+LEN_COD); if (bInsert) /*Hay que insertar el codigo*/ y = WLenCodMaq - 1; x = y - bLenCod; for (; x>wPos; x--) *(pBCodMaq+y) = *(pBCodMaq +x); for (x=1; x<=bLenCod; x++, wPos++) *(pBCodMaq+wP os) = *(pbCod+x); WLenCod = WLenCod + bLenCod; /*Agrega los bytes de codigo*/

F.29 DIALOGOS.CPP /*CONTIENE EL CODIGO NECESARIO PARA EL MANEJO DE DI ALOGOS*/ #include <stdlib.h> #include <stdio.h> #include <string.h> #include <ctype.h> #define Uses_TEventQueue #define Uses_TEvent #define Uses_TProgram #define Uses_TApplication #define Uses_TKeys #define Uses_TRect #define Uses_TMenuBar #define Uses_TSubMenu #define Uses_TMenuItem #define Uses_TStatusLine #define Uses_TStatusItem #define Uses_TStatusDef #define Uses_TDeskTop #define Uses_TView #define Uses_TWindow #define Uses_TFrame #define Uses_TScroller #define Uses_TScrollBar #define Uses_TDialog

Page 336: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

331

#define Uses_TButton #define Uses_TSItem #define Uses_TCheckBoxes #define Uses_TRadioButtons #define Uses_TLabel #define Uses_TInputLine #define Uses_TDeskTop #define Uses_TRect #define Uses_TEditor #define Uses_TFileEditor #define Uses_TFileDialog #define Uses_MsgBox #define Uses_TChDirDialog #include <tv.h> #include <lib.h> #include "define.h" #include "edit188.h" #include "asmmaq.h" #include "debug.h" #include "inputnum.h" #include "pserie.h" #include "teditwnd.h" #include "fileedit.h" #include "command.h" //Algunas estructuras son fijas, con el objeto de que el usuario //encuentre sus mismos valores en una operacion po sterior. void DUAMI188::vOpcionesDialog () byte bActualiza=FALSE; TDialog *pstdAux = new TDialog (TRect(9, 0, 70, 24), "Opciones"); if (pstdAux) TLabel *pstlAux; TView *pstvAux; //Seleccion de puerto pstvAux = new TRadioButtons(TRect(21, 3, 37, 6 ), new TSItem("COM ~1~", new TSItem("COM ~2~", new TSItem("COM ~3~", 0)))); pstdAux->insert(pstvAux); pstdAux->insert( new TLabel(TRect(20, 2, 28, 3 ), "~P~uerto", pstvAux)); //Velocidad del puerto pstvAux = new TRadioButtons(TRect(39, 3, 58, 8 ), new TSItem(" ~4~ - 1200", new TSItem(" ~5~ - 2400", new TSItem(" ~6~ - 4800", new TSItem(" ~7~ - 9600", new TSItem(" ~8~ - 19200", 0)))))); pstdAux->insert(pstvAux); pstdAux->insert( new TLabel(TRect(38, 2, 58, 3 ), "~V~elocidad de Puerto", pstvAux)); //Path del ejecutable pstvAux = new TInputLine(TRect(3, 8, 37, 9), M AXPATH); pstdAux->insert (pstvAux); pstdAux->insert (new TLabel(TRect(2, 7, 31, 8) , "~D~irectorio destino del .COM:", pstvAux)); //Administracion de memoria pstdAux->insert (new TStaticText(TRect(3, 10, 37, 11), "Manejo de memoria (debe reiniciar)")); //Memoria para compilar pstvAux = new INPUTNUM(TRect(29, 11, 37, 12), CHARNUM_DEC16, INPUTNUM_DEC); pstdAux->insert (pstvAux); pstdAux->insert (new TLabel(TRect(2, 11, 27, 1 2), "~N~o. bytes para compilar:", pstvAux)); //Memoria para variables pstvAux = new INPUTNUM(TRect(29, 12, 37, 13), CHARNUM_DEC16, INPUTNUM_DEC); pstdAux->insert (pstvAux); pstdAux->insert (new TLabel(TRect(2, 12, 28, 1 3), "No. ~b~ytes para variables:", pstvAux)); //Memoria para depurar

Page 337: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

332

pstvAux = new INPUTNUM(TRect(29, 13, 37, 14), CHARNUM_DEC16, INPUTNUM_DEC); pstdAux->insert (pstvAux); pstdAux->insert (new TLabel(TRect(2, 13, 27, 1 4), "No. bytes ~p~ara depurar:", pstvAux)); //Memoria para el volcado pstvAux = new INPUTNUM(TRect(29, 14, 37, 15), CHARNUM_DEC16, INPUTNUM_DEC); pstdAux->insert (pstvAux); pstdAux->insert (new TLabel(TRect(2, 14, 27, 1 5), "No. bytes para vo~l~cado:", pstvAux)); //Mumero de mensajes pstvAux = new INPUTNUM(TRect(29, 15, 37, 16), CHARNUM_DEC16, INPUTNUM_DEC); pstdAux->insert (pstvAux); pstdAux->insert (new TLabel(TRect(2, 15, 27, 1 6), "N~o~. m ximo de mensajes:", pstvAux)); //Segundos de espera pstvAux = new INPUTNUM(TRect(52, 9, 58, 10), C HARNUM_DEC16, INPUTNUM_DEC); pstdAux->insert (pstvAux); pstdAux->insert (new TLabel(TRect(38, 9, 51, 1 0), "~S~eg. espera:", pstvAux)); //Video pstvAux = new TRadioButtons(TRect(39, 13, 58, 16), new TSItem ("B/N 80x25", new TSItem ("Col 80x25", new TSItem ("Col 80x43|50", 0)))); pstdAux->insert (pstvAux); pstlAux = new TLabel(TRect(38, 11, 44, 12), "V ~i~deo", pstvAux); pstdAux->insert (pstlAux); pstdAux->insert (new TStaticText(TRect(39, 12, 56, 13), "(debe reiniciar)")); //Generales pstvAux = new TCheckBoxes(TRect(2, 18, 58, 20) , new TSItem ("C~r~ear archivo .MAP de referencias", new TSItem ("Verificar conexi¢n con la ~U~AMI188EB al inicio", 0))); pstdAux->insert (pstvAux); pstlAux = new TLabel(TRect(2, 17, 15, 18), "~G ~eneral", pstvAux); pstdAux->insert (pstlAux); //Los botones de la ventana pstdAux->insert (new TButton (TRect(9, 21, 21, 23), "~O~K", cmOK, bfDefault)); pstdAux->insert (new TButton (TRect(38, 21, 50 , 23), "~C~ancelar", cmCancel, bfNormal)); //Opciones del editor pstvAux = new TCheckBoxes(TRect(3, 3, 19, 6), new TSItem ("~M~argen", new TSItem ("M~A~Y/min", new TSItem ("~R~esaltar", 0)))); pstdAux->insert (pstvAux); pstlAux = new TLabel(TRect(2, 2, 9, 3), "~E~di tor", pstvAux); pstdAux->insert (pstlAux); //Colocamos los datos que se mostraran pstdAux->setData (&soOpciones); ushort usControl = deskTop->execView (pstdAux) ; //Los obtenemos los datos de la ventana de dia logo if (usControl!=cmCancel) pstdAux->getData (&soOpciones); //Guarda las opciones FILE *psfIn = fopen (scDirFuenteOPT, "wb"); if (!psfIn) messageBox("Ha ocurrido un error al modifi car archivo de configuraci¢n.", mfError | mfOKButton ); else for (int x=CERO; soOpciones.scPathEXE[x]; x++); if (x) /*Verifica que se termine en \*/ if (soOpciones.scPathEXE[x-1]!=92) soOpciones.scPathEXE[x] = 92; soOpciones.scPathEXE[x+1] = CERO; putc (85, psfIn); fwrite (&soOpciones, sizeof(opt), 1, psfIn ); fclose (psfIn); bActualiza = TRUE; destroy (pstdAux);

Page 338: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

333

if (bActualiza==TRUE) vActualizaEditores (); //A ctualiza los cambios a las ventanas void DUAMI188::vActualizaEditores () /*Se encarga de actualizar todos los editores co n los cambios de las opciones*/ EDITWINDOW *psewAux1, *psewAux; psewAux1 = pstewObtenTopEditor (); psewAux = psewAux1; USFlagEditores = soOpciones.usFlagEditor; //Act ualiza banderas globales if (psewAux==0) return; do message (deskTop, evCommand, cmActualizaEditor , CERO); message (deskTop, evCommand, cmNext, CERO); psewAux1 = pstewObtenTopEditor (); while (psewAux!=psewAux1); wEsperaPuerto = (word)dConvierteCadNum (soOpcion es.scSegundos, INPUTNUM_DEC); vTerminaPuertoSerie (); //Termina el puerto ser ie y lo reinicia vIniciaPuertoSerie (soOpciones.usPuerto, COM_8_B ITS, COM_STOPBIT, COM_PARIDADPAR, soOpciones.usVelocidad); void DUAMI188::vAgregaInstruccionDialog () addi saInst; word x, wRef; byte sbCod[15]; //Se fija por defaul saInst.usOpt = CERO; wRef = psdwDWin->wObtenPosInstruccion (); x = wMAQ2ASM (saInst.scInst, PTR_CODMAQ(), wRef, DEPURA_REF, TAM_CODMAQ()); TDialog *pstdAux = new TDialog (TRect(20, 2, 60, 15), "Instruccion"); if (pstdAux) TView *pstvAux; pstdAux->insert (new TStaticText(TRect(3, 2, 3 8, 3), "Esta acci¢n, obliga cargar de")); pstdAux->insert (new TStaticText(TRect(3, 3, 3 8, 4), "nuevo el programa a la UAMI188EB.")); //El ChkBox de insertar pstvAux = new TCheckBoxes(TRect(3, 8, 37, 9), new TSItem ("~I~nsertar instruccion" , 0)); pstdAux->insert (pstvAux); //Los botones de la ventana pstdAux->insert (new TButton (TRect( 6, 10, 17 , 12), "~O~K", cmOK, bfDefault)); pstdAux->insert (new TButton (TRect(21, 10, 33 , 12), "~C~ancelar", cmCancel, bfNormal)); //La instruccion pstvAux = new TInputLine(TRect(3, 6, 37, 7), M AX_LEN_CAD); pstdAux->insert (pstvAux); pstdAux->insert (new TLabel(TRect(2, 5, 30, 6) , "Instrucci¢n en ~e~nsamblador:", pstvAux)); //Colocamos los datos que se mostraran pstdAux->setData (&saInst); ushort usControl = deskTop->execView (pstdAux) ; //Los obtenemos los datos de la ventana de dia logo if (usControl!=cmCancel) pstdAux->getData (&saInst); WConstASM = CERO; //No hay opciones vIniciaCompilacion (); x = wASM2MAQ (saInst.scInst, sbCod, &wRef, 0 ); if (LBYTE(x)!=ERR_NE) messageBox(MENSAJE(LBYTE(x)), mfError | mf OKButton ); else vColocaCODIGO (sbCod, wRef, saInst.usOpt); wDUAMI188Flag = SETBIT (wDUAMI188Flag, FLA G188_CHINS); psdwDWin->vActualiza (); destroy (pstdAux); void DUAMI188::vCambiaRegistroDialog ()

Page 339: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

334

chkr scrR; int x, iRef; word wNum; iRef = psdwDWin->wObtenRegistroSel (); //Regist ro seleccionado //POR LO PRONTO SE PERMITE CAMBIAR CUALQUIER REG ISTRO if (iRef==DBGREG_CS) //CS no se permite cambiar messageBox("No es posible cambiar este registr o.", mfError | mfOKButton ); return; for (x=0; x<DBGREG_NUMDIG; x++) //Se copian los numeros tal cual. scrR.scReg[x] = sCRegWindow[(iRef*DBGREG_LENRE G)+DBGREG_POSVAL+x]; scrR.scReg[x] = CERO; TDialog *pstdAux = new TDialog (TRect(20, 2, 51, 9), "Cambia registro"); if (pstdAux) TView *pstvAux; //Los botones de la ventana pstdAux->insert (new TButton (TRect( 3, 4, 14, 6), "~O~K", cmOK, bfDefault)); pstdAux->insert (new TButton (TRect(15, 4, 27, 6), "~C~ancelar", cmCancel, bfNormal)); //El registro pstvAux = new INPUTNUM(TRect(21, 2, 28, 3), CH ARNUM_HEX16, INPUTNUM_HEX); pstdAux->insert (pstvAux); pstdAux->insert (new TLabel(TRect(2, 2, 19, 3) , "~N~uevo valor (H):", pstvAux)); //Colocamos los datos que se mostraran pstdAux->setData (&scrR); ushort usControl = deskTop->execView (pstdAux) ; //Los obtenemos los datos de la ventana de dia logo if (usControl!=cmCancel) pstdAux->getData (&scrR); wNum = (word)dConvierteCadNum (scrR.scReg, I NPUTNUM_HEX); sprintf (scrR.scReg, "%04X", wNum); for (x=0; x<DBGREG_NUMDIG; x++) sCRegWindow[(iRef*DBGREG_LENREG)+DBGREG_PO SVAL+x] = scrR.scReg[x]; psdwDWin->vActualiza (); vCargaRegistro (iRef); //Cambiamos el regis tro destroy (pstdAux); void DUAMI188::vLeerMemoriaUAMI188Dialog () word wSeg, wOffSet, wNBytes; TDialog *pstdAux = new TDialog (TRect(20, 2, 55, 14), "Leer memoria de UAMI188"); if (pstdAux) TView *pstvAux; //Offset pstvAux = new INPUTNUM(TRect(24, 4, 32, 5), CH ARNUM_HEX16, INPUTNUM_HEX); pstdAux->insert (pstvAux); pstdAux->insert (new TLabel(TRect(2, 4, 16, 5) , "~O~ffSet (H):", pstvAux)); //Numero de bytes pstvAux = new INPUTNUM(TRect(24, 6, 32, 7), CH ARNUM_DEC16, INPUTNUM_DEC); pstdAux->insert (pstvAux); pstdAux->insert (new TLabel(TRect(2, 6, 19, 7) , "~N~umero de bytes:", pstvAux)); //Los botones de la ventana pstdAux->insert (new TButton (TRect( 4, 8, 15, 10), "~O~K", cmOK, bfDefault)); pstdAux->insert (new TButton (TRect(18, 8, 30, 10), "~C~ancelar", cmCancel, bfNormal)); //Segmento pstvAux = new INPUTNUM(TRect(24, 2, 32, 3), CH ARNUM_HEX16, INPUTNUM_HEX); pstdAux->insert (pstvAux); pstdAux->insert (new TLabel(TRect(2, 2, 16, 3) , "~S~egmento (H):", pstvAux)); //Colocamos los datos que se mostraran pstdAux->setData (&slmuLMU); ushort usControl = deskTop->execView (pstdAux) ; //Los obtenemos los datos de la ventana de dia logo if (usControl!=cmCancel) pstdAux->getData (&slmuLMU);

Page 340: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

335

wSeg = (word)dConvierteCadNum (slmuLMU.scSeg mento, INPUTNUM_HEX); wOffSet = (word)dConvierteCadNum (slmuLMU.sc OffSet, INPUTNUM_HEX); wNBytes = (word)dConvierteCadNum (slmuLMU.sc NumBytes, INPUTNUM_DEC); //Solo hay que verificar el numero de bytes if (wNBytes>wTamVolMem) messageBox("Demasiados bytes para el volca do de memoria.", mfError | mfOKButton ); else vLeerMemoriaUAMI188 (wSeg, wOffSet, wNByte s, pbBuffVolMem); //Lee la memoria de la UAMI psdwDWin->vFijaSegOffVolMem (wSeg, wOffSet ); //Actualiza la ventana destroy (pstdAux); void DUAMI188::vLeerProgramaUAMI188Dialog () word wSeg, wOffSet, wNBytes; TDialog *pstdAux = new TDialog (TRect(20, 2, 55, 14), "Leer programa de UAMI188"); if (pstdAux) TView *pstvAux; //Offset pstvAux = new INPUTNUM(TRect(24, 4, 32, 5), CH ARNUM_HEX16, INPUTNUM_HEX); pstdAux->insert (pstvAux); pstdAux->insert (new TLabel(TRect(2, 4, 16, 5) , "~O~ffSet (H):", pstvAux)); //Numero de bytes pstvAux = new INPUTNUM(TRect(24, 6, 32, 7), CH ARNUM_DEC16, INPUTNUM_DEC); pstdAux->insert (pstvAux); pstdAux->insert (new TLabel(TRect(2, 6, 19, 7) , "~N~umero de bytes:", pstvAux)); //Los botones de la ventana pstdAux->insert (new TButton (TRect( 4, 8, 15, 10), "~O~K", cmOK, bfDefault)); pstdAux->insert (new TButton (TRect(18, 8, 30, 10), "~C~ancelar", cmCancel, bfNormal)); //Segmento pstvAux = new INPUTNUM(TRect(24, 2, 32, 3), CH ARNUM_HEX16, INPUTNUM_HEX); pstdAux->insert (pstvAux); pstdAux->insert (new TLabel(TRect(2, 2, 16, 3) , "~S~egmento (H):", pstvAux)); //Colocamos los datos que se mostraran pstdAux->setData (&slmuLPU); ushort usControl = deskTop->execView (pstdAux) ; //Los obtenemos los datos de la ventana de dia logo if (usControl!=cmCancel) pstdAux->getData (&slmuLPU); wSeg = (word)dConvierteCadNum (slmuLPU.scSeg mento, INPUTNUM_HEX); wOffSet = (word)dConvierteCadNum (slmuLPU.sc OffSet, INPUTNUM_HEX); wNBytes = (word)dConvierteCadNum (slmuLPU.sc NumBytes, INPUTNUM_DEC); //Solo hay que verificar el numero de bytes if (wNBytes>TAM_CODMAQ()) messageBox("Demasiados bytes para buffer d el depurador.", mfError | mfOKButton ); else vLeerMemoriaUAMI188 (wSeg, wOffSet, wNByte s, PTR_CODMAQ()); //Lee la memoria de la UAMI wDUAMI188Flag = SETBIT (wDUAMI188Flag, FLA G188_CARGA); psdwDWin->vMostrar (); //Ahora los registros vCambiaRegistro (DBGREG_CS, wSeg); vCambiaRegistro (DBGREG_IP, wOffSet); vCargaRegistro (DBGREG_CS); vCargaRegistro (DBGREG_IP); vLeerRegistrosUAMI188 (); //Lee los regis tros de la UAMI188 destroy (pstdAux); bChkConexion (); void DUAMI188::vMoverMemoriaUAMI188Dialog ()

Page 341: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

336

TDialog *pstdAux = new TDialog (TRect(20, 2, 56, 18), "Mover memoria de UAMI188"); if (pstdAux) TView *pstvAux; //Inicio Offset pstvAux = new INPUTNUM(TRect(25, 4, 33, 5), CH ARNUM_HEX16, INPUTNUM_HEX); pstdAux->insert (pstvAux); pstdAux->insert (new TLabel(TRect(2, 4, 21, 5) , "Origen O~f~fSet (H):", pstvAux)); //Fin Segmento pstvAux = new INPUTNUM(TRect(25, 6, 33, 7), CH ARNUM_HEX16, INPUTNUM_HEX); pstdAux->insert (pstvAux); pstdAux->insert (new TLabel(TRect(2, 6, 24, 7) , "~D~estino Segmento (H):", pstvAux)); //Fin Offset pstvAux = new INPUTNUM(TRect(25, 8, 33, 9), CH ARNUM_HEX16, INPUTNUM_HEX); pstdAux->insert (pstvAux); pstdAux->insert (new TLabel(TRect(2, 8, 22, 9) , "D~e~stino OffSet (H):", pstvAux)); //Numero de bytes pstvAux = new INPUTNUM(TRect(25, 10, 33, 11), CHARNUM_DEC16, INPUTNUM_DEC); pstdAux->insert (pstvAux); pstdAux->insert (new TLabel(TRect(2, 10, 19, 1 1), "~N~umero de bytes:", pstvAux)); //Los botones de la ventana pstdAux->insert (new TButton (TRect( 4, 12, 15 , 14), "~O~K", cmOK, bfDefault)); pstdAux->insert (new TButton (TRect(18, 12, 30 , 14), "~C~ancelar", cmCancel, bfNormal)); //Inicio Segmento pstvAux = new INPUTNUM(TRect(25, 2, 33, 3), CH ARNUM_HEX16, INPUTNUM_HEX); pstdAux->insert (pstvAux); pstdAux->insert (new TLabel(TRect(2, 2, 23, 3) , "~O~rigen Segmento (H):", pstvAux)); //Colocamos los datos que se mostraran pstdAux->setData (&smmuMMU); ushort usControl = deskTop->execView (pstdAux) ; //Los obtenemos los datos de la ventana de dia logo if (usControl!=cmCancel) word wISeg, wFSeg, wIOffSet, wFOffSet, wNByt es; pstdAux->getData (&smmuMMU); //No se realiza ninguna verificacion es RESP ONSABILIDAD del programador wISeg = (word)dConvierteCadNum (smmuMMU.scIS egmento, INPUTNUM_HEX); wIOffSet = (word)dConvierteCadNum (smmuMMU.s cIOffSet, INPUTNUM_HEX); wFSeg = (word)dConvierteCadNum (smmuMMU.scFS egmento, INPUTNUM_HEX); wFOffSet = (word)dConvierteCadNum (smmuMMU.s cFOffSet, INPUTNUM_HEX); wNBytes = (word)dConvierteCadNum (smmuMMU.sc NumBytes, INPUTNUM_DEC); vMoverMemoriaUAMI188 (wISeg, wFSeg, wIOffSet , wFOffSet, wNBytes); destroy (pstdAux); void DUAMI188::vCargaMemoriaUAMIDialog () ushort usControl; word wInicio, wFinal; TDialog *pstdAux = new TDialog (TRect(20, 2, 60, 11), "Carga programa del depurador"); if (pstdAux) TView *pstvAux; sprintf (scmuCMU.scFin, "%04X", LEN_CODMAQ()); //Fija un valor //Localidad final pstvAux = new INPUTNUM(TRect(24, 4, 32, 5), CH ARNUM_HEX16, INPUTNUM_HEX); pstdAux->insert (pstvAux); pstdAux->insert (new TLabel(TRect(2, 4, 20, 5) , "OffSet ~f~inal (H):", pstvAux)); //Los botones de la ventana pstdAux->insert (new TButton (TRect( 6, 6, 17, 8), "~O~K", cmOK, bfDefault)); pstdAux->insert (new TButton (TRect(21, 6, 33, 8), "~C~ancelar", cmCancel, bfNormal)); //Localidad de inicio pstvAux = new INPUTNUM(TRect(24, 2, 32, 3), CH ARNUM_HEX16, INPUTNUM_HEX); pstdAux->insert (pstvAux); pstdAux->insert (new TLabel(TRect(2, 2, 22, 3) , "OffSet ~i~nicial (H):", pstvAux)); //Colocamos los datos que se mostraran pstdAux->setData (&scmuCMU); usControl = deskTop->execView (pstdAux);

Page 342: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

337

//Los obtenemos los datos de la ventana de dia logo if (usControl!=cmCancel) pstdAux->getData (&scmuCMU); wInicio = (word)dConvierteCadNum (scmuCMU.sc Inicio, INPUTNUM_HEX); wFinal = (word)dConvierteCadNum (scmuCMU.scF in, INPUTNUM_HEX); usControl = TRUE; else usControl = FALSE; destroy (pstdAux); if (usControl) vCargaProgramaUAMI (wInicio, wFin al); void DUAMI188::vSetLeerMemoriaDialog () word wNBytes; TDialog *pstdAux = new TDialog (TRect(20, 2, 55, 18), "Leer memoria de UAMI188"); if (pstdAux) TView *pstvAux; pstdAux->insert (new TStaticText(TRect(3, 2, 2 6, 3), "Se recomienda un valor")); pstdAux->insert (new TStaticText(TRect(3, 3, 2 9, 4), "peque¤o para el No. bytes")); //Offset pstvAux = new INPUTNUM(TRect(24, 7, 32, 8), CH ARNUM_HEX16, INPUTNUM_HEX); pstdAux->insert (pstvAux); pstdAux->insert (new TLabel(TRect(2, 7, 16, 8) , "~O~ffSet (H):", pstvAux)); //Numero de bytes pstvAux = new INPUTNUM(TRect(24, 9, 32, 10), C HARNUM_DEC16, INPUTNUM_DEC); pstdAux->insert (pstvAux); pstdAux->insert (new TLabel(TRect(2, 9, 19, 10 ), "~N~umero de bytes:", pstvAux)); //El ChkBox de activar pstvAux = new TCheckBoxes(TRect(3, 11, 33, 12) , new TSItem ("~A~ctivar lectura", 0)) ; pstdAux->insert (pstvAux); //Los botones de la ventana pstdAux->insert (new TButton (TRect( 4, 13, 15 , 15), "~O~K", cmOK, bfDefault)); pstdAux->insert (new TButton (TRect(18, 13, 30 , 15), "~C~ancelar", cmCancel, bfNormal)); //Segmento pstvAux = new INPUTNUM(TRect(24, 5, 32, 6), CH ARNUM_HEX16, INPUTNUM_HEX); pstdAux->insert (pstvAux); pstdAux->insert (new TLabel(TRect(2, 5, 16, 6) , "~S~egmento (H):", pstvAux)); //Colocamos los datos que se mostraran pstdAux->setData (&slmuSLMU); ushort usControl = deskTop->execView (pstdAux) ; //Los obtenemos los datos de la ventana de dia logo if (usControl!=cmCancel) //Solo es informativo , no realiza ninguna accion pstdAux->getData (&slmuSLMU); wNBytes = (word)dConvierteCadNum (slmuSLMU.s cNumBytes, INPUTNUM_DEC); //Solo hay que verificar el numero de bytes if (wNBytes>wTamVolMem) messageBox("Demasiados bytes para el volca do de memoria.", mfError | mfOKButton ); strcpy (slmuSLMU.scNumBytes, "100"); //Fi ja el default destroy (pstdAux); void DUAMI188::vCambiaMemoriaDialog () chkm scmM; byte bAux; word wSeg, wOffSet, wLen, x, y; strcpy (scmM.scSegmento, "0070"); strcpy (scmM.scOffSet, "0000"); scmM.scValor[0] = CERO; TDialog *pstdAux = new TDialog (TRect(15, 2, 65, 14), "Cambiar memoria de UAMI188"); if (pstdAux)

Page 343: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

338

TView *pstvAux; pstdAux->insert (new TStaticText(TRect(3, 2, 4 5, 3), "Es necesario leer la memoria de la UAMI188")); pstdAux->insert (new TStaticText(TRect(3, 3, 4 5, 4), "para ver los cambios en el depurador.")); //Offset pstvAux = new INPUTNUM(TRect(40, 5, 47, 6), CH ARNUM_HEX16, INPUTNUM_HEX); pstdAux->insert (pstvAux); pstdAux->insert (new TLabel(TRect(26, 5, 40, 6 ), "~O~ffSet (H):", pstvAux)); //Valores de memoria pstvAux = new INPUTNUM(TRect(11, 7, 47, 8), MA X_LEN_CAD, INPUTNUM_HEX); pstdAux->insert (pstvAux); pstdAux->insert (new TLabel(TRect(2, 7, 9, 8), "~V~alor:", pstvAux)); //Los botones de la ventana pstdAux->insert (new TButton (TRect( 9, 9, 20, 11), "~O~K", cmOK, bfDefault)); pstdAux->insert (new TButton (TRect(26, 9, 38, 11), "~C~ancelar", cmCancel, bfNormal)); //Segmento pstvAux = new INPUTNUM(TRect(18, 5, 25, 6), CH ARNUM_HEX16, INPUTNUM_HEX); pstdAux->insert (pstvAux); pstdAux->insert (new TLabel(TRect(2, 5, 16, 6) , "~S~egmento (H):", pstvAux)); //Colocamos los datos que se mostraran pstdAux->setData (&scmM); ushort usControl = deskTop->execView (pstdAux) ; //Los obtenemos los datos de la ventana de dia logo if (usControl!=cmCancel) pstdAux->getData (&scmM); wSeg = (word)dConvierteCadNum (scmM.scSegmen to, INPUTNUM_HEX); wOffSet = (word)dConvierteCadNum (scmM.scOff Set, INPUTNUM_HEX); wLen = strlen (scmM.scValor); for (x=0; x<wLen; x++) if (scmM.scValor[x]>57) scmM.scValor[x] = scmM.scValor[x] - 55; else scmM.scValor[x] = scmM.scValor[x] - 4 8; for (x=0, y=0; x<wLen; x++, y++) bAux = CREABYTE (scmM.scValor[x], scmM.scV alor[x+1]); scmM.scValor[y] = bAux; x++; wLen = y; vCargaMemoria (wSeg, wOffSet, wLen, (byte *) scmM.scValor); destroy (pstdAux);

F.30 EDITOR.CPP //BASICAMENTE CONTIENE EL CODIGO PARA COLOREAR EL E DITOR. //LO QUE SE HACE UNICAMENTE ES CAMBIAR EL COLOR DE LETRAS, EL DE //FONDO NO SE MUEVE PARA NADA. #define Uses_TFrame #define Uses_TWindow #define Uses_TRect #define Uses_TIndicator #define Uses_TMemo #define Uses_TEvent #define Uses_TScrollBar #define Uses_opstream #define Uses_ipstream #define Uses_TKeys #include <tv.h> #include "editor.h" #include "color.h" #include "define.h" #include "asmmaq.h" #include <dos.h>

Page 344: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

339

const ECOLOR_NORM = CREA_COLOR (BAZUL, FIAMARILLO), ECOLOR_SEL = CREA_COLOR (BNARANJA, FIAMARILLO), DEL_COLORF = 0xF0FF, ECOLOR_COMEN = (ushort)(FGRIS<<8), ECOLOR_OPER = (ushort)(FIBLANCO<<8), ECOLOR_CAD = (ushort)(FCYAN<<8), ECOLOR_INST = (ushort)(FIVERDE<<8), ECOLOR_NUM = (ushort)(FICYAN<<8), ECOLOR_KW = (ushort)(FIAZUL<<8), ECOLOR_REG = (ushort)(FICYAN<<8), ECOLOR_SEG = (ushort)(FIBLANCO<<8), MAX_KEYWORD = 0x1A; //Longitud maxima posible d e una palabra EDITOR::EDITOR (const TRect& bounds, TScrollBar *a HScrollBar, TScrollBar *aVScrollBar, TIndicator *anIndicator, ushort usBufferSize): TEditor (bounds, aHScrollBar, aVScrollBar, anIndic ator, usBufferSize) bTextColor = FALSE; //Sin color void EDITOR::draw () if (drawLine!=delta.y) drawPtr = lineMove (drawPtr, delta.y - drawLin e); drawLine = delta.y; if (bTextColor) drawLines (0, size.y, drawPtr); else TEditor::drawLines (0, size.y, drawPtr); void EDITOR::drawLines (int y, int iCount, ushort usLinePtr) ushort usColor; int iMaxLen, w, x, z; ushort u; dword dNada; byte bAux; char scText[MAX_KEYWORD], cFlag; ushort usBuffer[maxLineLength]; iMaxLen = delta.x + size.x; //Solo imprime el t ama¤o de la ventana while (iCount-->0) formatLine (usBuffer, usLinePtr, iMaxLen, CREA WORD(ECOLOR_SEL, ECOLOR_NORM)); //Coloreamos la pantalla!!! cFlag = FALSE; for (x=0, z=0, w=0, u=usLinePtr; x<iMaxLen; x+ +, z++, u++) bAux = LBYTE(usBuffer[x]); switch (bAux) case CHAR_IGUAL: //No forma parte del len guaje case CHAR_MENOR: //NO forma parte del len guaje case CHAR_PLUS: case CHAR_COMA: case CHAR_MENOS: case CHAR_PIZQ: case CHAR_PDER: case CHAR_2PUN: usBuffer[x] = (usBuffer[x] & DEL_COLORF) | ECOLOR_OPER; cFlag = TRUE; break; case CHAR_COMLL: usBuffer[x] = (usBuffer[x] & DEL_COLORF) | ECOLOR_CAD; do x++;

Page 345: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

340

usBuffer[x] = (usBuffer[x] & DEL_COLOR F) | ECOLOR_CAD; while ((x<iMaxLen)&&(LBYTE(usBuffer[x] )!=CHAR_COMLL)); cFlag = TRUE; break; case CHAR_PCOMA: do usBuffer[x] = usBuffer[x] = (usBuffer[ x] & DEL_COLORF) | ECOLOR_COMEN; x++; while (x<iMaxLen); cFlag = FALSE; z = CERO - 1; w = x + 1 ; break; case CHAR_ESP: cFlag = TRUE; break; default: scText[z] = bAux; break; if (z>=MAX_KEYWORD) z = CERO - 1; w = x + 1; cFlag = FALSE; if (cFlag) if (z) scText[z] = CERO; usColor = LBYTE(wAnalizaCadena(scText, 0 , z, &dNada)); //La identifica switch (usColor) case ID_REG16: case ID_REGDIR: case ID_REG08: case ID_REG32: usColor = ECOLOR_REG; break; case ID_SEG: usColor = ECOLOR_SEG; break; case ID_INOARG: case ID_IUNARG: case ID_IDOSARG: case ID_IESP: usColor = ECOLOR_INST; break; case ID_NUMERO: usColor = ECOLOR_NUM; break; case ID_RESWORD: usColor = ECOLOR_KW; break; default: usColor = CERO; break; if (usColor) for (; z; w++, z--) usBuffer[w] = usBuffer[w] = (usBuffe r[w] & DEL_COLORF) | usColor; z = CERO - 1; w = x + 1; cFlag = FALSE; writeBuf(0, y, size.x, 1, &usBuffer[delta.x]); usLinePtr = nextChar (lineEnd(usLinePtr)); y++;

Page 346: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

341

void EDITOR::handleEvent (TEvent& psteEvent) //Aqui va colocado lo del cambio de mayusculas a minusculas. if ((psteEvent.keyDown.keyCode==kbUp)||(psteEven t.keyDown.keyCode==kbDown)) drawLines (drawLine-delta.y, 1, drawPtr); if (psteEvent.what==evMouseDown) drawLines (drawLine-delta.y, 1, drawPtr); TEditor::handleEvent (psteEvent); return;

F.31 EDIT188A.CPP #define Uses_TApplication #define Uses_TDeskTop #define Uses_TRect #define Uses_TEditor #define Uses_TFileEditor #define Uses_TFileDialog #define Uses_MsgBox #define Uses_TChDirDialog #include <tv.h> #include <lib.h> #define MAIN_EDITD188 #include "teditwnd.h" #include "edit188.h" #include "reloj.h" #include "indica.h" #include "define.h" #define MAIN_ASMMAQ #include "asmmaq.h" #include "mensaje.h" #include "debug.h" #include "command.h" #include "txtwin.h" #include "pserie.h" #include "maximo.h" #include "timer.h" #include "inputnum.h" #include "cm_seria.h" #include "fileedit.h" #include <stdlib.h> #include <stdarg.h> #include <strstrea.h> #include <iomanip.h> #include <dos.h> #include <stdio.h> #include <conio.h> const smBW80 = 0x0002, smCO80 = 0x0003, smMono = 0x0007, smFont8x8 = 0x0100; DUAMI188::DUAMI188(int iArg, char *pscArg[]): TProgInit (DUAMI188::initStatusLine, DUAMI188::ini tMenuBar, DUAMI188::initDeskTop), TApplication () //Este es el constructor e inicia las variables para este objeto word x; byte bVolMem, bDefault; //Inicia unas cuantas variables scArchPrimario[CERO] = CERO; //No hay archivo p rincipal abierto scArchUAMI[CERO] = CERO; //No hay archivo que s e carge en UAMI wDUAMI188Flag = CERO; //Todas las banderas desa ctivadas bDefault = FALSE; //No opciones por default //Ruta del ejecutable

Page 347: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

342

vObtenNombreDir (scDirFuenteOPT, pscArg[CERO]); strcat (scDirFuenteOPT, ARCHIVO_OPTS); //Los argumentos for (x=CERO+1; x<iArg; x++) if (*(pscArg[x])=='/') switch (*(pscArg[x]+1)) case 'd': case 'D': //Carga las opciones por defaul t bDefault = TRUE; break; //Carga las opciones del D188 x = CERO; FILE *psfIn = fopen (scDirFuenteOPT, "rb"); if (psfIn) /*Carga las opciones*/ x = getc (psfIn); if (x==85) fread (&soOpciones, sizeof(opt), 1, psfIn); fclose (psfIn); if (((!psfIn)&&(x!=85))||(bDefault)) //Verifica con U, y no se necesita wTVol //No existe el archivo o no es, carga las DEFA ULT soOpciones.usFlagEditor = FLAGEDIT_RE|FLAGEDIT _Mm|FLAGEDIT_AI; //Se activan todas las banderas soOpciones.usPuerto = CERO+1; //Se usa COM 2 soOpciones.usVelocidad = COMVEL_19200; //Velo cidad de 19200 bps soOpciones.scPathEXE[CERO] = CERO; //No hay p ath strcpy (soOpciones.scBytesCom, "512"); //Memo ria para compilar cada linea de codigo strcpy (soOpciones.scBytesVar, "17408"); //Me moria que se emplea durante la compilacion strcpy (soOpciones.scBytesDep, "17408"); //Me moria para depuracion strcpy (soOpciones.scBytesVol, "8192"); //Mem oria de volcado strcpy (soOpciones.scNumMsg, "60"); //Por def ault son 60 mensajes strcpy (soOpciones.scSegundos, "2"); //2 segu ndos por default soOpciones.usVideo = VIDEO_CO; //Por default video de 80x25 soOpciones.usGeneral = CERO; //No se genera M APA y no se verifica UAMI //Fija la opcion de video switch (soOpciones.usVideo) case VIDEO_BN: //Blanco y negro setScreenMode (smBW80); break; case VIDEO_CO: //Color setScreenMode (smCO80); break; case VIDEO_COE: //Color extendido default: setScreenMode (smCO80|smFont8x8); break; //Espera del puerto wEsperaPuerto = (word)dConvierteCadNum (soOpcion es.scSegundos, INPUTNUM_DEC); //Carga banderas globales USFlagEditores = soOpciones.usFlagEditor; //Leer memoria de la UAMI188 strcpy (slmuLMU.scOffSet, "0000"); strcpy (slmuLMU.scNumBytes, soOpciones.scBytesVo l); strcpy (slmuLMU.scSegmento, "0000"); //Leer programa de la UAMI188 strcpy (slmuLPU.scOffSet, "0000"); strcpy (slmuLPU.scNumBytes, soOpciones.scBytesDe p); strcpy (slmuLPU.scSegmento, "0000"); //Mover memoria de la UAMI188 strcpy (smmuMMU.scIOffSet, "0000"); strcpy (smmuMMU.scFSegmento, "0070"); strcpy (smmuMMU.scFOffSet, "0000"); strcpy (smmuMMU.scNumBytes, "0"); strcpy (smmuMMU.scISegmento, "0070"); //Cargar programa desde memoria a la UAMI

Page 348: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

343

strcpy (scmuCMU.scInicio, "0000"); strcpy (scmuCMU.scFin, "0600"); //Valores de lectura a memoria de la UAMI (depur acion) strcpy (slmuSLMU.scOffSet, "0000"); strcpy (slmuSLMU.scNumBytes, "20"); strcpy (slmuSLMU.scSegmento, "0070"); slmuSLMU.usActivo = CERO; //Carga las opciones del compilador if (!bIniciaASMMAQ()) //Debe de ir lo antes pos ible vTerminaMAQ (); //Termina el depurador vTerminaASM (); //Termina el ensamblador clrscr (); printf ("No hay memoria suficiente. Use D188 / D.\nPresione cualquier tecla."); getch (); exit (1); //Para el volcado de memoria wTamVolMem = atoi (soOpciones.scBytesVol); //MAXIMO DE MEMORIA PERMITIDO if (wTamVolMem>MAX_BYTES_VOLM) wTamVolMem = MAX_ BYTES_VOLM; pbBuffVolMem = (byte *)malloc (wTamVolMem); if (!pbBuffVolMem) vTerminaMAQ (); //Termina el depurador vTerminaASM (); //Termina el ensamblador clrscr (); printf ("No hay memoria suficiente. Use D188 / D.\nPresione cualquier tecla."); getch (); exit (1); //Inicia el puerto serie, sin activar interrupc ion vIniciaPuertoSerie (soOpciones.usPuerto, COM_8_B ITS, COM_STOPBIT, COM_PARIDADPAR, soOpciones.usVelocidad); //Esta variable ya no se debe mover, una vez fij ada WConstASM = SETBIT (WConstASM, CTEASM_LBL|CTEASM _CTE|CTEASM_ARCHIVO); //Se definen algunas opciones //Crea el reloj en pantalla TRect strR = getExtent(); strR.a.x = strR.b.x - 9; //9 Caracteres de dere cha a izquierda strR.a.y = strR.b.y - 1; //1 caracter menos que el ultimo en eje Y. psReloj = new RELOJ (strR); insert (psReloj); //Indicador de conexion strR = getExtent(); strR.a.x = strR.b.x - 6; //6 Caracteres de dere cha a izquierda strR.b.y = strR.a.y + 1; //1 caracter mas que e l primero en eje Y. psIndica = new INDICADOR (strR); insert (psIndica); //Mensajes de conexion de la UAMI strR = TRect (25, 9, 55, 15); pstwMsgUAMI = new TXTWINDOW (strR, "UAMI188", wp GrayWindow); pstwMsgUAMI->hide (); //La oculta deskTop->insert(pstwMsgUAMI); //Mensajes al momento de compilar strR = TRect (20, 5, 55, 18); pstwMsgComp = new TXTWINDOW (strR, "Compilado", wpGrayWindow); pstwMsgComp->hide (); //La oculta deskTop->insert(pstwMsgComp); /*Mensajes*/ //Para activar y desactivar los comandos del men u stcArchivo.enableCmd (cmSave); stcArchivo.enableCmd (cmSaveAs); stcArchivo.enableCmd (cmGuardarTodo); stcArchivo.enableCmd (cmCut); stcArchivo.enableCmd (cmCopy); stcArchivo.enableCmd (cmPaste); stcArchivo.enableCmd (cmClear); stcArchivo.enableCmd (cmUndo); stcArchivo.enableCmd (cmFind); stcArchivo.enableCmd (cmReplace); stcArchivo.enableCmd (cmSearchAgain);

Page 349: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

344

stcWindow.enableCmd (cmCascade); stcWindow.enableCmd (cmCloseAll); stcWindow.enableCmd (cmTile); stcCompilar.enableCmd (cmCompilarD); stcCompilar.enableCmd (cmCompilarM); stcDebug.enableCmd (cmAddIns); stcCarga.enableCmd (cmCargaSelPrg); stcCarga.enableCmd (cmCargaMemPrg); stcMemoria.enableCmd (cmMoveMem); stcMemoria.enableCmd (cmReadRegs); stcMemoria.enableCmd (cmReadMem); stcMemoria.enableCmd (cmReadPrg); stcMemoria.enableCmd (cmChgValMem); stcEjecutar.enableCmd (cmEjecutar); stcEjecutar.enableCmd (cmPasoAPaso); disableCommands (stcDebug); disableCommands (stcArchivo); disableCommands (stcWindow); disableCommands (stcCompilar); disableCommands (stcCarga); disableCommands (stcMemoria); disableCommands (stcEjecutar); disableCommand (cmClosePrima); //Desactiva cerr ar primario disableCommand (cmCargaSelPrg); //Desactiva car ga a UAMI seleccionado disableCommand (cmMoveMem); //Desactiva mover m emoria disableCommand (cmEjecutar); //Desactiva ejecut ar disableCommand (cmPasoAPaso); //Desactiva ejecu tar paso a paso //Carga el porta papeles TEditor::editorDialog = usDialogosEdicion; psTEWClipWindow = pstewAbrirEditor (0, False); if(psTEWClipWindow!=0) TEditor::clipboard = psTEWClipWindow->pfeFEdit or; TEditor::clipboard->canUndo = False; //La ventana de mensajes TRect strR2 = getExtent(); if (strR2.b.y>25) //Display de 50x80 o 43x80 bVolMem = 14; //Volcado de memoria si es mayo r a 25 lineas strR2.a.y = strR2.b.y - 15; else //Display de 25x80 bVolMem = 7; //Volcado de memoria si es de 25 lineas strR2.a.y = strR2.b.y - 8; strR2.b.y = strR2.b.y - 2; psmMsg = new MENSAJES (strR2); psmMsg->close (); //La oculta, no la borra deskTop->insert(psmMsg); //Coloca la venatana en el desktop //La ventana de depuracion strR2 = getExtent(); if (strR2.b.y>25) strR2 = TRect (0, 0, 80, 41); else strR2 = TRect (0, 0, 80, 23); psdwDWin = new DEBUGWINDOW (strR2, bVolMem, pbBu ffVolMem, wTamVolMem, 16, 0, 0, PTR_CODMAQ(), TAM_CO DMAQ(), sCRegWindow, DBGREG_ LENREG, DBGREG_NUMREG); psdwDWin->close (); //La oculta, no la elimina deskTop->insert(psdwDWin); //Coloca la ventana //Carga los archivos especificados en la linea d e comandos for (x=CERO+1; x<iArg; x++) if (*(pscArg[x])!='/') pstewAbrirEditor (pscAr g[x], True); //Inicia el temporizador

Page 350: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

345

vIniciaTemporizador (); //Verifica el estado if (soOpciones.usGeneral&FLAGGRAL_UAM) bDefault = bChkConexion (); if (bDefault!=INDICA_DSC) vFijaHoraUAMI188EB ( ); //Coloca la hora if ((bDefault==INDICA_STP)||(bDefault==INDICA_ DBG)) //Verifica la conexion con la UAMI188EB //Es necesario cargar el programa messageBox ("Debido al estado en la UAMI188E B, es necesario cargar el programa de la UAMI188EB en el depurador para un correcto funciona miento.", mfInformation|mfOKButton); //Inicia los registros vIniciaRegistros (); wBufferCS = wObtenRegistro (DBGREG_CS); //Finalmente activa la interrupcion del puerto s erie vInterrupcionPtoSerie (TRUE); EDITWINDOW *DUAMI188::pstewAbrirEditor (const char *pcFileName, Boolean boVisible) EDITWINDOW *pstewAux; TRect r = deskTop->getExtent (); pstewAux = new EDITWINDOW (r, pcFileName, wnNoNu mber); pstewAux->pfeFEditor->editorFlags = efPromptOnRe place; pstewAux->pfeFEditor->autoIndent = (Boolean)(soO pciones.usFlagEditor & FLAGEDIT_AI); pstewAux->pfeFEditor->bTextColor = soOpciones.us FlagEditor & FLAGEDIT_RE; TView *p = validView(pstewAux); if (!boVisible) p->hide(); deskTop->insert (p); return ((EDITWINDOW *)p); void DUAMI188::vAbrirArchivo () //Abre el archivo y le asigna un apuntador char scFileName[MAXPATH], x; strcpy(scFileName, "*.ASM" ); if(usEjecutarDialogo(new TFileDialog("*.ASM", "A brir archivo", "~N~ombre", fdOpenButton, 100), sc FileName)!=cmCancel) pstewAbrirEditor (scFileName, True); void DUAMI188::vNuevoArchivo () pstewAbrirEditor (0, True); void DUAMI188::vCambiarDir () char D[MAXPATH]; usEjecutarDialogo(new TChDirDialog(cdNormal, 0), D); void DUAMI188::vDOSShell () suspend (); system("cls"); cout << "Teclear EXIT para regresar..."; system (getenv("COMSPEC")); resume (); redraw (); void DUAMI188::vMostrarClip () psTEWClipWindow->select(); psTEWClipWindow->show();

Page 351: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

346

void DUAMI188::vMosaico () deskTop->tile(deskTop->getExtent()); void DUAMI188::vCascada () deskTop->cascade(deskTop->getExtent()); void DUAMI188::handleEvent(TEvent& psteEvent) ushort usMsg; byte bDato; word wAux; byte far *pbFlagKey=(byte far *)MK_FP(CERO, 0x04 17); //Acceso a las banderas teclado if ((TSTBIT(psteEvent.what, evKeyDown))&&(TSTBIT (soOpciones.usFlagEditor, FLAGEDIT_Mm))) switch (psteEvent.keyDown.keyCode) case kbPtoComa: case kbDbComilla: *pbFlagKey = CLSBIT (*pbFlagKey, FLAG_KEY_ Mm); break; case kbEnter: case kbDown: case kbUp: case kbPgUp: case kbPgDn: *pbFlagKey = SETBIT (*pbFlagKey, FLAG_KEY_ Mm); break; default: break; TProgram::handleEvent(psteEvent); if (bObtenDatoCola(&bDato)) //Informacion de la UAMI188 por la COLA switch (bDato) case cmsOK: //La UAMI188 envia el estado de OK, no se hace nada. if (psIndica->bObtenIndicador()==INDICA_DS C) psIndica->vIndicador (INDICA_UKN); //Se desconoce el estado break; case cmsDesconect: //Se desconecto la UAMI1 88EB psIndica->vIndicador (INDICA_DSC); messageBox ("La UAMI188EB se ha desconecta do.", mfInformation|mfOKButton); break; case cmsConectar: //Se ha conectado la UAMI 188EB psIndica->vIndicador (INDICA_UKN); //No s abemos el estado break; case cmsEnd: //Termino un programa vLeerRetorno (); psIndica->vIndicador (INDICA_STP); break; case cmsError: //Ocurrio un error en la UAM I vLeerError (); break; case cmsPaso: //Para el trazado del program a psdwDWin->vMostrar (); psIndica->vIndicador (INDICA_DBG); vLeerRegistrosUAMI188 (); /*Pide registros */ psdwDWin->vFijaPosEXE (wObtenRegistro(DBGR EG_IP)); wAux = wObtenRegistro (DBGREG_CS); if (slmuSLMU.usActivo) //Obtiene la memori a word wSeg, wOff, wNBytes; wSeg = (word)dConvierteCadNum (slmuSLMU. scSegmento, INPUTNUM_HEX); wOff = (word)dConvierteCadNum (slmuLMU.s cOffSet, INPUTNUM_HEX); wNBytes = (word)dConvierteCadNum (slmuLM U.scNumBytes, INPUTNUM_DEC); vLeerMemoriaUAMI188 (wSeg, wOff, wNBytes , pbBuffVolMem); //Lee la memoria de la UAMI psdwDWin->vFijaSegOffVolMem (wSeg, wOff) ; //Actualiza la ventana

Page 352: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

347

if (wBufferCS!=wAux) messageBox ("El registro CS cambio, es p osible que el codigo que esta en el depurador no corresponda a lo que hay en la UAMI188EB, selecc ione Leer Programa.", mfInformation|mfOKButton); break; case cmsDetener: messageBox ("Programa detenido.", mfInform ation|mfOKButton); psIndica->vIndicador (INDICA_STP); break; case cmsResidente: messageBox ("El c¢digo ha quedado en memem oria.", mfInformation|mfOKButton); bChkConexion (); break; default: //No hace nada break; if(psteEvent.what!=evCommand) return; else switch(psteEvent.message.command) case cmAbrir: //Abre archivo existente vAbrirArchivo (); break; case cmNuevo: //Crea un nuevo arhivo vNuevoArchivo (); break; case cmCambiarDir: //Cambia de directorio vCambiarDir (); break; case cmDosShell: //Sale al MS-DOS vDOSShell(); break; case cmShowClip: //Muestra el porta papeles vMostrarClip(); break; case cmOpciones: //Opcione del editor vOpcionesDialog (); break; case cmTile: //Editores en mosaico vMosaico (); break; case cmCascade: //Editores en cascada vCascada(); break; case cmAcercade: //Acerca de... vAcercaDe (); break; case cmCompilarD: //Compila a disco vCompilar (TRUE); break; case cmCompilarM: //Compila a memoria vCompilar (FALSE); break; case cmAbrirPrima: //Selecciona el archivo primario if (iSetArchivoPrimario()) wDUAMI188Flag = SETBIT (wDUAMI188Flag, F LAG188_ACTAP); enableCommand (cmClosePrima); disableCommand (cmAbrirPrima); break; case cmClosePrima: //Cierra el archivo prim ario wDUAMI188Flag = CLSBIT (wDUAMI188Flag, FLA G188_ACTAP); scArchPrimario[CERO] = CERO; enableCommand (cmAbrirPrima); disableCommand (cmClosePrima); break; case cmGuardarTodo: //Guarda todo vGuardarTodo (); break;

Page 353: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

348

case cmCloseAll: //Cierra todo vCerrarTodo (); break; case cmMensajes: //Muestra ventana de mensa jes psmMsg->vMostrar (); break; case cmDebug: //Muestra ventana de depuraci on psdwDWin->vMostrar (); break; case cmChkConexion: //Verifica la conexcion y retona el estado bChkConexion (); break; case cmReset: //Reinicia la UAMI188 usMsg = messageBox ("¨Reiniciar la UAMI188 EB?", mfYesButton|mfNoButton|mfInformation); if (usMsg==12) vReiniciaUAMI (); //Se rei nicia break; case cmReadPrg: //Lee un programa de la UAM I vLeerProgramaUAMI188Dialog (); break; case cmSelPrg: //Selecciona el archivo para carga vSelecCargaUAMI (); break; case cmReadMem: //Lee una zona de memoria d e la UAMI188 vLeerMemoriaUAMI188Dialog (); break; case cmReadRegs: //Lee los registros de la UAMI vLeerRegistrosUAMI188 (); break; case cmMoveMem: //Mueve un bloque de memori a en la UAMI188 vMoverMemoriaUAMI188Dialog (); break; case cmCargaSelPrg: //Carga el programa sel eccionado a la UAMI188 vCargaProgramaArchivoUAMI (); break; case cmCargaMemPrg: //Carga desde memoria d el depurador a la UAMI188 vCargaMemoriaUAMIDialog (); break; case cmCargaPrg: //Carga un programa al dep urador vCargaFileDebug (); break; case cmDefReadMem: //Define la memoria que leera en cada ejecucion vSetLeerMemoriaDialog (); break; case cmEjecutar: //Ejecuta el programa en l a UAMI188 vEjecutar (); break; case cmPasoAPaso: //Ejecuta paso a paso vEjecutaPasoPaso (); break; case cmAddIns: //Agrega o inserta una nuev a instruccion vAgregaInstruccionDialog (); break; case cmDetener: usMsg = messageBox ("¨Detener ejecuci¢n en la UAMI188EB?", mfYesButton|mfNoButton|mfInformation); if (usMsg==12) vDetenerEjecucion (); break; case cmChgReg: //Cambia algun registro vCambiaRegistroDialog (); break; case cmChgValMem: //Cambia localidades en m emoria vCambiaMemoriaDialog (); break; case cmReiniciaSerie: //Reinicia el puerto serie vInterrupcionPtoSerie (FALSE); vTerminaPuertoSerie (); vIniciaPuertoSerie (soOpciones.usPuerto, C OM_8_BITS, COM_STOPBIT, COM_PARIDADPAR, soOpciones.usVelocidad); bLimpiaCola (); vInterrupcionPtoSerie (TRUE); break;

Page 354: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

349

case cmAbrirMAP: vAbrirMAP (); break; case cmPrueba: vFijaHoraUAMI188EB (); break; default: return; clearEvent(psteEvent); static Boolean isTileable(TView *p, void *) if (((p->options&ofTileable)!=0)&&((p->state&sfV isible)!=0)) return True; else return False; void DUAMI188::idle() TView *pstvAux; word wIp; TProgram::idle(); psReloj->update(); //Actualiza el reloj pstvAux = deskTop->firstThat (isTileable, 0); / /La ventana de arriba switch (psIndica->bObtenIndicador()) //Obtiene el estado case INDICA_OK: enableCommand (cmReset); enableCommands (stcMemoria); if (pstvAux==(TView *)psdwDWin) enableComman d (cmChgReg); else disableCommand (cmChgReg); enableCommand (cmCargaMemPrg); if (!TSTBIT(wDUAMI188Flag, FLAG188_SELEC)) d isableCommand (cmCargaSelPrg); //Solo si hay seleccion else enableCommand (cmCargaSelPrg); disableCommands (stcEjecutar); disableCommand (cmDetener); break; case INDICA_STP: enableCommand (cmReset); enableCommands (stcMemoria); if (pstvAux==(TView *)psdwDWin) enableComman d (cmChgReg); else disableCommand (cmChgReg); enableCommand (cmEjecutar); if (pstvAux==(TView *)psdwDWin) enableComman d (cmPasoAPaso); else disableCommand (cmPasoAPaso); enableCommand (cmCargaMemPrg); if (!TSTBIT(wDUAMI188Flag, FLAG188_SELEC)) d isableCommand (cmCargaSelPrg); //Solo si hay seleccion else enableCommand (cmCargaSelPrg); disableCommand (cmDetener); break; case INDICA_DBG: enableCommand (cmReset); enableCommands (stcMemoria); if (pstvAux==(TView *)psdwDWin) enableComman d (cmChgReg); else disableCommand (cmChgReg); disableCommands (stcCarga); enableCommand (cmEjecutar); if (pstvAux==(TView *)psdwDWin) enableComman d (cmPasoAPaso); else disableCommand (cmPasoAPaso); enableCommand (cmDetener); break; case INDICA_RUN: enableCommand (cmReset); disableCommands (stcMemoria); disableCommand (cmChgReg); disableCommands (stcCarga); disableCommands (stcEjecutar); disableCommand (cmReadMem);

Page 355: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

350

enableCommand (cmDetener); break; case INDICA_DSC: case INDICA_UKN: default: disableCommand (cmReset); disableCommands (stcMemoria); disableCommand (cmChgReg); disableCommands (stcCarga); disableCommands (stcEjecutar); disableCommand (cmDetener); break; if (!pstvAux) //Editor enableCommand (cmMensajes); enableCommand (cmDebug); disableCommands (stcWindow); disableCommands (stcArchivo); disableCommands (stcDebug); if (TSTBIT(wDUAMI188Flag, FLAG188_ACTAP)) enab leCommands (stcCompilar); else disableCommands (stcCompilar); return; if (pstvAux==(TView *)psmMsg) //Ventana de mensajes disableCommand (cmMensajes); enableCommand (cmDebug); disableCommands (stcArchivo); disableCommands (stcDebug); if (TSTBIT(wDUAMI188Flag, FLAG188_ACTAP)) enab leCommands (stcCompilar); else disableCommands (stcCompilar); return; if (pstvAux==(TView *)psdwDWin) //Depurador enableCommand (cmMensajes); enableCommands (stcDebug); disableCommand (cmDebug); disableCommands (stcArchivo); if (TSTBIT(wDUAMI188Flag, FLAG188_ACTAP)) enab leCommands (stcCompilar); else disableCommands (stcCompilar); return; disableCommands (stcDebug); enableCommands (stcArchivo); enableCommands (stcWindow); if (((EDITWINDOW *)pstvAux)->pfeFEditor->bEsArch ivoASM()) enableCommands (stcCompilar); else disableCommands (stcCompilar); enableCommand (cmDebug); enableCommand (cmMensajes); DUAMI188::~DUAMI188 () //Restaura el teclado a minusculas. byte far *pbFlagKey=(byte far *)MK_FP(CERO, 0x04 17); //Acceso a las banderas teclado *pbFlagKey = CLSBIT (*pbFlagKey, FLAG_KEY_Mm); vTerminaTemporizador (); vTerminaPuertoSerie (); destroy (pstwMsgComp); destroy (pstwMsgUAMI); psmMsg->vCerrar (); psdwDWin->vCerrar (); destroy (psIndica); destroy (psReloj); free (pbBuffVolMem); vTerminaMAQ (); //Termina el depurador vTerminaASM (); //Termina el ensamblador

Page 356: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

351

int main (int iArg, char *pscArg[]) /*Entrada pri ncipal*/ DUAMI188 sduam188 (iArg, pscArg); sduam188.run(); return (0);

F.32 EDIT188B.CPP #define Uses_TDialog #define Uses_TDeskTop #define Uses_TProgram #define Uses_TApplication #define Uses_TObject #define Uses_TInputLine #define Uses_TLabel #define Uses_THistory #define Uses_TRect #define Uses_TCheckBoxes #define Uses_TButton #define Uses_TButton #define Uses_MsgBox #define Uses_TSItem #define Uses_TEditor #include <tv.h> #include "edit188.h" #include <stdlib.h> #include <stdarg.h> #include <strstrea.h> #include <iomanip.h> ushort usEjecutarDialogo (TDialog *pstdD, void *pv Data) TView *pstvP = TProgram::application->validView (pstdD); if(pstvP==0) return (cmCancel); else if (pvData!=0) pstvP->setData (pvData); ushort usResult = TProgram::deskTop->execView (pstvP); if ((usResult!=cmCancel)&&(pvData!=0)) pstvP->getData (pvData); TObject::destroy (pstvP); return (usResult); TDialog *pstdBuscarDialogo () TDialog *pstdD = new TDialog(TRect(0, 0, 38, 12) , "Buscar"); pstdD->options |= ofCentered; TInputLine *pstilControl = new TInputLine(TRect( 3, 3, 32, 4), 80); pstdD->insert(pstilControl); TLabel *pstlLbl = new TLabel(TRect(2, 2, 17, 3), "~T~exto a buscar", pstilControl); pstdD->insert(pstlLbl); THistory *psthH = new THistory(TRect(32, 3, 35, 4), pstilControl, 10) ; pstdD->insert(psthH); TCheckBoxes *pstcbChkBox = new TCheckBoxes(TRec t(3, 5, 35, 7), new TSItem("~M~ay£sc ulas/Min£sculas ", new TSItem("~S~olo p alabra completa", 0))); pstdD->insert (pstcbChkBox); TButton *pstbB = new TButton(TRect(7, 9, 17, 11) , "O~K~", cmOK, bfDefault); pstdD->insert (pstbB); pstbB = new TButton(TRect(19, 9, 31, 11), "Cance lar", cmCancel, bfNormal); pstdD->insert (pstbB); pstdD->selectNext (False); return (pstdD); TDialog *pstdReplazarDialogo ()

Page 357: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

352

TDialog *pstdD = new TDialog(TRect(0, 0, 40, 16) , "Remplazar"); pstdD->options |= ofCentered; TInputLine *pstilControl = new TInputLine(TRect( 3, 3, 34, 4), 80); pstdD->insert (pstilControl); TLabel *pstlLbl = new TLabel(TRect(2, 2, 17, 3), "~T~exto a buscar", pstilControl); pstdD->insert (pstlLbl); THistory *psthH = new THistory(TRect(34, 3, 37, 4), pstilControl, 10); pstdD->insert (psthH); pstilControl = new TInputLine(TRect(3, 6, 34, 7 ), 80); pstdD->insert (pstilControl); pstlLbl = new TLabel(TRect(2, 5, 14, 6), "~N~uev o texto", pstilControl); pstdD->insert (pstlLbl); psthH = new THistory(TRect(34, 6, 37, 7), pstilC ontrol, 11); pstdD->insert (psthH); TCheckBoxes *pstcbChkBox = new TCheckBoxes(TRect (3, 8, 37, 12), new TSItem("~M~ay£scu las/Min£sculas", new TSItem("~S~olo pa labra completa", new TSItem("~P~regunt ar al remplazar", new TSItem("~R~emplaz ar todo", 0))))); pstdD->insert (pstcbChkBox); TButton *pstbB = new TButton(TRect(8, 13, 18, 15 ), "O~K~", cmOK, bfDefault); pstdD->insert (pstbB); pstbB = new TButton(TRect(20, 13, 32, 15), "Canc elar", cmCancel, bfNormal); pstdD->insert (pstbB); pstdD->selectNext (False); return (pstdD);

F.33 EDIT188C.CPP #define Uses_TApplication #define Uses_TMenuBar #define Uses_TRect #define Uses_TSubMenu #define Uses_TKeys #define Uses_TMenuItem #define Uses_TStatusLine #define Uses_TStatusItem #define Uses_TStatusDef #define Uses_TPoint #define Uses_TEditor #define Uses_MsgBox #define Uses_TFileDialog #define Uses_TDeskTop #define Uses_TStaticText #define Uses_TButton #include <tv.h> #include "edit188.h" #include "command.h" #include "indica.h" #include "pserie.h" #include "cm_seria.h" #include <stdarg.h> #include <strstrea.h> TMenuBar *DUAMI188::initMenuBar(TRect r) TSubMenu& sub1 = *new TSubMenu("~A~rchivo", kbAl tA) + *new TMenuItem("~A~brir", cmAbrir, kbF 3, hcNoContext, "F3") + *new TMenuItem("~N~uevo", cmNuevo, kbN oKey) + *new TMenuItem("~G~uardar", cmSave, kb F2, hcNoContext, "F2") + *new TMenuItem( "G~u~ardar como...", c mSaveAs, kbNoKey) + *new TMenuItem( "Guardar ~t~odo", cmGu ardarTodo, kbNoKey) + newLine() + *new TMenuItem("~C~errar", cmClose, kb AltF3, hcNoContext, "Alt+F3") + newLine() +

Page 358: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

353

*new TMenuItem("~C~ambio de directorio ...", cmCambiarDir, kbNoKey) + *new TMenuItem("~D~OS shell", cmDosShe ll, kbNoKey) + *new TMenuItem("~S~alir", cmQuit, kbAl tX, hcNoContext, "Alt+X"); TSubMenu& sub2 = *new TSubMenu("~E~dici¢n", kbAl tE) + *new TMenuItem("~D~eshacer", cmUndo, k bCtrlBack, hcNoContext, "Ctrl+Back") + newLine() + *new TMenuItem("Co~r~tar", cmCut, kbSh iftDel, hcNoContext, "Shitf+Del") + *new TMenuItem("~C~opiar", cmCopy, kbC trlIns, hcNoContext, "Ctrl+Ins" ) + *new TMenuItem("~P~egar", cmPaste, kbS hiftIns, hcNoContext, "Shift+Ins") + newLine() + *new TMenuItem("~M~ostrar portapapeles ", cmShowClip, kbNoKey ) + newLine() + *new TMenuItem("~O~pciones", cmOpcione s, kbNoKey); TSubMenu& sub3 = *new TSubMenu( "~B~usqueda", kb AltB) + *new TMenuItem("~B~uscar...", cmFind, kbNoKey) + *new TMenuItem("~R~emplazar...", cmRep lace, kbNoKey) + *new TMenuItem("Buscar de ~n~uevo", cm SearchAgain, nkbCtrlL, hcNoContext, "Ctrl+L"); TSubMenu& sub4 = *new TSubMenu("~C~ompilar", kbA ltC) + *new TMenuItem("~C~ompilar a disco", c mCompilarD, kbCtrlF9, hcNoContext, "Ctrl+F9") + *new TMenuItem("Compilar a ~m~emoria", cmCompilarM, kbCtrlF8, hcNoContext, "Ctrl+F8") + newLine() + *new TMenuItem("~A~rchivo primario", c mAbrirPrima, kbNoKey) + *new TMenuItem("Cerrar ~p~rimario", cm ClosePrima, kbNoKey); TSubMenu& sub5 = *new TSubMenu("~U~AMI188EB", kb AltU) + *new TMenuItem("~V~erificar conexion", cmChkConexion, nkbCtrlV, hcNoContext, "Ctrl+V") + *new TMenuItem("~R~einiciar UAMI188", cmReset, kbNoKey) + *new TMenuItem("~S~eleccionar programa a cargar", cmSelPrg, kbCtrlF1, hcNoContext, "Ctrl+F1") + *new TMenuItem("V~o~lcado de memoria", cmReadMem, kbNoKey) + *new TMenuItem("~M~over memoria", cmMo veMem, kbNoKey) + *new TMenuItem("L~e~er registros", cmR eadRegs, kbNoKey) + *new TMenuItem("Leer ~p~rograma", cmRe adPrg, kbNoKey) + newLine() + *new TMenuItem("~C~argar programa sele ccionado", cmCargaSelPrg, nkbCtrlP, hcNoContext, "Ctrl+S") + *new TMenuItem("C~a~rgar programa del depurador", cmCargaMemPrg, nkbCtrlM, hcNoContext, "Ctrl+M") + //La siguiente linea solo es para depu racion del D188.EXE //*new TMenuItem("~Solo pruebas~", cmP rueba, kbNoKey, hcNoContext) + newLine() + *new TMenuItem("Re~i~niciar puerto ser ie", cmReiniciaSerie, kbNoKey); TSubMenu& sub6 = *new TSubMenu("~D~epuraci¢n", k bAltD) + *new TMenuItem("~C~argar programa al d epurador", cmCargaPrg, kbNoKey) + *new TMenuItem("~D~efine lectura de me moria", cmDefReadMem, kbNoKey) + newLine() + *new TMenuItem("~E~jecutar", cmEjecuta r, kbF4, hcNoContext, "F4") + *new TMenuItem("Ejecutar ~p~aso a paso ", cmPasoAPaso, kbF7, hcNoContext, "F7") + *new TMenuItem("D~e~tener ejecuci¢n", cmDetener, nkbCtrlP, hcNoContext, "Ctrl+P") + newLine() + *new TMenuItem("~A~gregar instruccion" , cmAddIns, nkbCtrlI, hcNoContext, "Ctrl+I") + *new TMenuItem("Cambiar ~r~egistro", c mChgReg, nkbCtrlR, hcNoContext, "Ctrl+R") + *new TMenuItem("Cambiar ~v~alor en mem oria", cmChgValMem, kbNoKey) + newLine() + *new TMenuItem("Abrir ~m~apa de refere ncias", cmAbrirMAP, kbNoKey); TSubMenu& sub7 = *new TSubMenu("~V~entanas", kbA ltW) + *new TMenuItem("~T~ama¤o/mover", cmRes ize, kbCtrlF5, hcNoContext, "Ctrl+F5") + *new TMenuItem("~Z~oom", cmZoom, kbF5, hcNoContext, "F5") + *new TMenuItem("M~o~saico", cmTile, kb NoKey ) + *new TMenuItem("C~a~scada", cmCascade, kbNoKey) + *new TMenuItem("~S~iguiente", cmNext, kbF6, hcNoContext, "F6") + *new TMenuItem("~A~nterior", cmPrev, k bShiftF6, hcNoContext, "Shift+F6") + *new TMenuItem("~C~errar todo", cmClos eAll, kbNoKey) + newLine() + *new TMenuItem("~M~ensajes", cmMensaje s, kbNoKey) + *new TMenuItem("~D~epuraci¢n", cmDebug , nkbCtrlD, hcNoContext, "Ctrl+D") +

Page 359: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

354

newLine() + *new TMenuItem("Ace~r~ca de ...", cmAc ercade, kbNoKey); r.b.y = r.a.y+1; return new TMenuBar( r, sub1 + sub2 + sub3 + sub 4 + sub5 + sub6 +sub7); TStatusLine *DUAMI188::initStatusLine(TRect r) r.a.y = r.b.y-1; TStatusLine *stlLine; stlLine = new TStatusLine(r, *new TStatusDef(CERO, 0xFFFF ) + *new TStatusItem("~F2~ Guardar", kbF2, cmSave) + *new TStatusItem("~F3~ Abrir", kbF3, c mAbrir) + *new TStatusItem("~Alt-F3~ Cerrar", kb AltF3, cmClose) + *new TStatusItem("~Ctrl-F9~ Compilar", kbCtrlF9, cmCompilarD) + *new TStatusItem("~F10~ Menu", kbF10, cmMenu) + *new TStatusItem(CERO, kbF5, cmZoom) + *new TStatusItem(CERO, kbF6, cmNext) + *new TStatusItem(CERO, kbCtrlF5, cmRes ize)); return (stlLine); void DUAMI188::outOfMemory() messageBox("No hay memoria suficiente para esta operaci¢n.", mfError | mfOKButton ); void DUAMI188::vAcercaDe() byte bDato; bDato = bChkConexion (); if ((bDato!=INDICA_STP)&&(bDato!=INDICA_OK)) vInterrupcionPtoSerie (FALSE); while (!bEnviaDato(cmsAcercaDe)); vInterrupcionPtoSerie (TRUE); TDialog *pstdAcercade = new TDialog(TRect(0, 0, 39, 16), "Acerca de"); pstdAcercade->insert(new TStaticText(TRect(4, 2, 36, 11), "\003Ensamblador y depurador de la UAMI-188E B\n\003\n" "\003Versi¢n 1.0.1\n\003\n" "\003USO LIBRE\n\003\n" "\003Universidad Aut¢noma Metropolitana (Izt apalapa 2005)\n\003\n")); pstdAcercade->insert(new TButton(TRect(14, 12, 2 4, 14), "OK", cmOK, bfDefault)); pstdAcercade->options |= ofCentered; deskTop->execView(pstdAcercade); destroy(pstdAcercade); typedef char *_charPtr; typedef TPoint *PPoint; #pragma warn -rvl ushort usDialogosEdicion (int dialog, ...) va_list arg; char buf[80]; ostrstream os(buf, sizeof(buf)); switch(dialog) case edOutOfMemory: return messageBox("No hay memoria suficiente para esta operaci¢n.", mfError | mfOKButton ); case edReadError: va_start(arg, dialog); os << "Error al leer archivo " << va_arg(arg , _charPtr) << "." << ends; va_end(arg); return messageBox(buf, mfError | mfOKButton) ;

Page 360: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

355

case edWriteError: va_start(arg, dialog); os << "Error al escribir archivo " << va_arg (arg,_charPtr) << "." << ends; va_end(arg); return messageBox(buf, mfError | mfOKButton) ; case edCreateError: va_start(arg, dialog); os << "Error al crear archivo " << va_arg(ar g, _charPtr) << "." << ends; va_end(arg); return messageBox(buf, mfError | mfOKButton) ; case edSaveModify: va_start( arg, dialog ); os << va_arg(arg, _charPtr) << " ha sido mod ificado. Guardar?" << ends; va_end(arg); return messageBox(buf, mfInformation | mfYes NoCancel); case edSaveUntitled: return messageBox("Guardar nuevo archivo?", mfInformation | mfYesNoCancel); case edSaveAs: va_start(arg, dialog); return usEjecutarDialogo(new TFileDialog("*. ASM", "Guardar a rchivo como", "~N~ombre" , fdOKButton , 101), va_a rg(arg, _charPtr)); case edFind: va_start(arg, dialog); return usEjecutarDialogo(pstdBuscarDialogo() , va_arg(arg, _charPtr)); case edSearchFailed: return messageBox("Cadena no encontrada.", m fError | mfOKButton); case edReplace: va_start(arg, dialog); return usEjecutarDialogo(pstdReplazarDialogo (), va_arg(arg, _charPtr)); case edReplacePrompt: // Avoid placing the dialog on the same lin e as the cursor TRect r(0, 1, 40, 8); r.move((TProgram::deskTop->size.x-r.b.x)/2, 0); TPoint t = TProgram::deskTop->makeGlobal(r.b ); t.y++; va_start(arg, dialog); TPoint *pt = va_arg(arg, PPoint); if (pt->y<=t.y) r.move(0, TProgram::deskTop->size.y - r.b. y - 2); va_end(arg); return messageBoxRect(r, "Remplazar esta cad ena?", mfYesNoCancel | mfInformation); #pragma warn .rvl

F.34 ERROR.CPP /************************************************** *****/ /* MANEJA LOS MENSAJES DE ERROR, SOLO VERSION DE PR UEBA*/ /************************************************** *****/ #include <stdio.h> #include <stdlib.h>

Page 361: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

356

#include <string.h> #include <conio.h> #include <malloc.h> #include <lib.h> #include "asmmaq.h" #include "define.h" int iAddMensaje (word wMsg, word wLin) /*LBYTE(wMsg) = error, HBYTE(wMsg) = col, wLin = linea*/ if (LBYTE(wMsg)==ERR_NE) return (ERR_NE); if (BNumMensajes>=BTotalMensajes) if (BNumMensajes==BTotalMensajes) wMsg = MSG_SINNUM(MSG_DMM); wLin = CERO; else return (ERR_NE); if (LBYTE(wMsg)<=ERR_LSTERR) BNumErrores++; else if (LBYTE(wMsg)<=ERR_LSTWAR) BNumWarnings++; *(pWMensajes+BNumMensajes) = wMsg; *(pWLineas+BNumMensajes) = wLin; BNumMensajes++; return (ERR_NE); void vResetMensajes () BNumMensajes = CERO; BNumErrores = CERO; BNumWarnings = CERO; void vImprimeMensajes () /*Imprime mensajes de error o warnings*/ byte x; include *psincAux; psincAux = psINCInclude; if (BNumMensajes<=CERO) return; for (x=0; x<BNumMensajes; x++) if (LBYTE(*(pWMensajes+x))<=ERR_LSTWAR) /*Err ores y Warnings*/ if (LBYTE(*(pWMensajes+x))<=ERR_LSTERR) prin tf ("Error "); else printf ("Warning "); if (*(pWLineas+x)) printf ("L[%d] ", *(pWLin eas+x)); if (HBYTE(*(pWMensajes+x))) printf ("C[%d] " , HBYTE(*(pWMensajes+x))); printf (": %s\n", sCError[LBYTE(*(pWMensajes +x))]); else /*Mensajes o INCLUDE*/ if (LBYTE(*(pWMensajes+x))==MSG_LBL) /*Para incluir el archivo de la instruccio n INCLUDE*/ strcpy (sCError[MSG_LBL], "Archivo: "); strcat (sCError[MSG_LBL], psincAux->scFile ); psincAux = psincAux->psincSig; switch (HBYTE(*(pWMensajes+x))) case 0: printf ("L[%d] : %s\n", *(pWLineas+x), s CError[LBYTE(*(pWMensajes+x))]); break; case 2: printf ("%d ", *(pWLineas+x)); case 1: printf ("%s\n", sCError[LBYTE(*(pWMensaj es+x))]); break; case 3: printf ("%s %d\n", sCError[LBYTE(*(pWMen sajes+x))], *(pWLineas+x)); break;

Page 362: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

357

F.35 FILEEDIT.CPP #define Uses_TGroup #define Uses_TEditor #define Uses_TEvent #define Uses_opstream #define Uses_ipstream #define Uses_TApplication #include <tv.h> #include <lib.h> #include "fileedit.h" #include "command.h" #include "edit188.h" #include <string.h> #include <fstream.h> #include <io.h> #include <stdio.h> inline ushort min( ushort u1, ushort u2 ) return u1 < u2 ? u1 : u2; FILEEDITOR::FILEEDITOR(const TRect& pstrR, TScroll Bar *pstsbHScrollBar, TScrollBar *pstsbVScrollBar , TIndicator *pstiIndicator, const char *pcFileName): EDITOR (pstrR, pstsbHScrollBar, pstsbV ScrollBar, pstiIndicator, 0) word x; bEsASM = TRUE; //Por lo pronto es en ASM if (pcFileName==0) fileName[0] = EOS; else strcpy (fileName, pcFileName); fexpand (fileName); for (x=0; *(fileName+x); x++); if (strcmp(fileName+x-3, "ASM")) bEsASM = FALS E; if (isValid) isValid = loadFile (); byte FILEEDITOR::bEsArchivoASM () return (bEsASM); void FILEEDITOR::doneBuffer() delete buffer; void FILEEDITOR::handleEvent (TEvent& event) EDITOR::handleEvent(event); switch (event.what) case evCommand: switch (event.message.command) case cmActualizaEditor:

Page 363: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

358

autoIndent = (Boolean)(USFlagEditores & FLAGEDIT_AI); bTextColor = USFlagEditores & FLAGEDIT_R E; EDITOR::draw (); break; case cmSave: save(); break; case cmSaveAs: saveAs(); break; default: return; break; default: return; clearEvent(event); void FILEEDITOR::initBuffer() buffer = new char[bufSize]; Boolean FILEEDITOR::loadFile() ifstream f (fileName, ios::in | ios::binary); if (!f) setBufLen( 0 ); return True; else long fSize = filelength (f.rdbuf()->fd()); if ((fSize>0xFFE0L)||(setBufSize(ushort(fSize) ))==False) editorDialog( edOutOfMemory ); return False; else if (fSize>INT_MAX) f.read (&buffer[bufSize-ushort(fSize)], IN T_MAX); f.read (&buffer[bufSize-ushort(fSize)+INT_ MAX], ushort(fSize-INT_MAX)); else f.read (&buffer[bufSize-ushort(fSize)], usho rt(fSize)); if (!f) editorDialog( edReadError, fileName ); return False; else setBufLen(ushort(fSize)); return True; Boolean FILEEDITOR::save() if (*fileName==EOS) return saveAs (); else return saveFile ();

Page 364: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

359

Boolean FILEEDITOR::saveAs() Boolean res = False; if (editorDialog(edSaveAs, fileName)!=cmCancel) fexpand (fileName); message( owner, evBroadcast, cmUpdateTitle, 0 ); res = saveFile(); if (isClipboard()==True) *fileName = EOS; return res; static void writeBlock (ofstream& f, char *buf, un signed len) while (len>0) int l = len < INT_MAX ? len : INT_MAX; f.write (buf, l); buf+= l; len-= l; Boolean FILEEDITOR::saveFile () char drive[MAXDRIVE]; char dir[MAXDIR]; char file[MAXFILE]; char ext[MAXEXT]; if ((editorFlags&efBackupFiles)!=0) fnsplit (fileName, drive, dir, file, ext); char backupName[MAXPATH]; fnmerge (backupName, drive, dir, file, backupE xt); unlink (backupName); rename (fileName, backupName); ofstream f (fileName, ios::out|ios::binary); if (!f) editorDialog (edCreateError, fileName); return False; else writeBlock (f, buffer, curPtr); writeBlock (f, buffer+curPtr+gapLen, bufLen-cu rPtr); if (!f) editorDialog (edWriteError, fileName); return False; else modified = False; update (ufUpdate); return True; Boolean FILEEDITOR::setBufSize( ushort newSize ) if( newSize > 0xF000 ) newSize = 0xFFE0; else newSize = (newSize + 0x0FFF) & 0xF000; if( newSize != bufSize ) char *temp = buffer;

Page 365: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

360

if( (buffer = new char[newSize]) == 0 ) delete temp; return False; ushort n = bufLen - curPtr + delCount; memcpy( buffer, temp, min( newSize, bufSize ) ); memmove( &buffer[newSize - n], &temp[bufSiz e - n], n ); delete temp; bufSize = newSize; gapLen = bufSize - bufLen; return True; void FILEEDITOR::shutDown () setCmdState (cmSave, False); setCmdState (cmSaveAs, False); TEditor::shutDown(); void FILEEDITOR::updateCommands() TEditor::updateCommands(); setCmdState(cmSave, True); setCmdState(cmSaveAs, True); Boolean FILEEDITOR::valid( ushort command ) if (command==cmValid) return isValid; else if (modified==True) int d; if (*fileName==EOS) d = edSaveUntitled; else d = edSaveModify; switch (editorDialog(d, fileName)) case cmYes: return save(); case cmNo: modified = False; return True; case cmCancel: return False; return True;

F.36 FUNCION.CPP /*CONTIENE LAS FUNCIONES PARA EL MANEJO DEL COMPILA DOR*/ #define Uses_TApplication #define Uses_TMenuBar #define Uses_TRect #define Uses_TSubMenu #define Uses_TKeys #define Uses_TMenuItem #define Uses_TStatusLine #define Uses_TStatusItem #define Uses_TStatusDef #define Uses_TPoint #define Uses_TEditor #define Uses_MsgBox #define Uses_TFileDialog

Page 366: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

361

#define Uses_TDeskTop #define Uses_TStaticText #define Uses_TButton #define Uses_TDeskTop #define Uses_TRect #define Uses_TFileEditor #define Uses_TFileDialog #define Uses_TChDirDialog #include <tv.h> #include "edit188.h" #include "define.h" #include "asmmaq.h" #include "mensaje.h" #include "debug.h" #include "command.h" #include "maximo.h" #include "teditwnd.h" #include "fileedit.h" #include "pserie.h" #include <stdlib.h> #include <stdio.h> static Boolean isTileable(TView *p, void *) if (((p->options&ofTileable)!=0)&&((p->state&sfV isible)!=0)) return True; else return False; byte DUAMI188::bIniciaASMMAQ () /*Inicia el ensamblador y el desensamblador, FAL SE si no se inicia*/ word wMem1, wMem2, wMsg, wRet; wMem1 = atoi (soOpciones.scBytesCom); //Tama¤o de memoria para compilar wMem2 = atoi (soOpciones.scBytesVar); //Tama¤o de memoria para etiquetas, ctes, etc. wMsg = atoi (soOpciones.scNumMsg); //Numero de mensajes //MAXIMO DE MEMORIA PERMITIDO if (wMem1>MAX_BYTES_COMP) wMem1 = MAX_BYTES_COMP ; if (wMem2>MAX_BYTES_VAR) wMem2 = MAX_BYTES_VAR; if (wMsg>MAX_NUM_MENSAJES) wMsg = MAX_NUM_MENSAJ ES; wRet = iIniciaASM (wMem1, wMem2, wMsg); wMem1 = atoi (soOpciones.scBytesDep); //MAXIMO DE MEMORIA PERMITIDO if (wMem1>MAX_BYTES_DEBUG) wMem1 = MAX_BYTES_DEB UG; wRet = wRet + bIniciaMAQ (wMem1); if (wRet<2) return (FALSE); return (TRUE); TView *DUAMI188::pstvPrimeraVentana (Boolean (*bFu n)(TView *, void *), void *pvArgs) /*Regresa el puntero de la ventana que esta en l a parte superior de la pantalla*/ TView *pstvAux = deskTop->last; if (pstvAux==0) return 0; do pstvAux = pstvAux->next; if (bFun(pstvAux, pvArgs)==True) return pstvAu x; while (pstvAux!=deskTop->last); return 0; TView *DUAMI188::pstvBuscaVentanaArch (char *pcArc h) /*Regresa el puntero de la ventana segun el nomb re de archivo, no revisa ruta*/ TView *pstvAux = deskTop->last; EDITWINDOW *pstewAux; char scFile[MAX_NFILE]; if (pstvAux==0) return 0; do pstvAux = pstvAux->next; pstewAux = (EDITWINDOW *)pstvAux; vObtenNombreArch (scFile, pstewAux->pfeFEditor ->fileName, TRUE, MAX_NFILE-1); if (!strcmp(pcArch, scFile)) return (pstvAux); /*Si son iguales retorna el TView*/ while (pstvAux!=deskTop->last);

Page 367: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

362

return 0; EDITWINDOW *DUAMI188::pstewObtenTopEditor () TView * tvAux; EDITWINDOW *pstewAux; tvAux = deskTop->firstThat(isTileable, 0); return ((EDITWINDOW *)tvAux); void DUAMI188::vCompilar (byte bDisk) char scFile[MAX_NFILE+1]; EDITWINDOW *pstewAux; TEditor *psteAux; efile sefEdit; vInterrupcionPtoSerie (FALSE); //Se compila archivo, permite ctes y etiquetas WConstASM = CTEASM_LBL | CTEASM_CTE | CTEASM_ARC HIVO; if (TSTBIT(wDUAMI188Flag, FLAG188_ACTAP)) vObtenNombreArch (scFile, scArchPrimario, TRUE , MAX_NFILE); pstewAux = (EDITWINDOW *)pstvBuscaVentanaArch (scFile); //Para saber si esta en el editor if (pstewAux) bCreaEditFile (&sefEdit, pstewAux); vCompilaArchivo (CERO, &sefEdit, bDisk); else vCompilaArchivo (scArchPrimario, CERO, bDisk ); else pstewAux = (EDITWINDOW *)pstvPrimeraVentana (i sTileable, 0); if (!*(pstewAux->pfeFEditor->fileName)) //No tiene nombre de archivo pstewAux->pfeFEditor->saveAs (); if (!*(pstewAux->pfeFEditor->fileName)) messageBox("Debe guardar el archivo primer o.", mfError | mfOKButton ); return; bCreaEditFile (&sefEdit, pstewAux); vCompilaArchivo (CERO, &sefEdit, bDisk); vInterrupcionPtoSerie (TRUE); psdwDWin->vResetAll (); int DUAMI188::iSetArchivoPrimario () //Selecciona el archivo principal que se va a co mpilar char scFileName[MAXPATH], x; strcpy(scFileName, "*.ASM" ); if(usEjecutarDialogo(new TFileDialog("*.ASM", "A rchivo Primario", "~N~ombre", fdOpenButton, 100), scFileName)!=cmCancel) strcpy (scArchPrimario, scFileName); return (TRUE); return (FALSE); void DUAMI188::vCerrarTodo () EDITWINDOW *psewAux; psewAux = pstewObtenTopEditor (); if (psewAux==0) return; do //Cierra cada una de las ventanas

Page 368: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

363

message (deskTop, evCommand, cmClose, CERO); psewAux = pstewObtenTopEditor (); while (psewAux); /*FUNCIONES DE USO GENERAL*/ void vEsperaEvento () TEvent steAux; byte bSalir=FALSE; do steAux.getKeyEvent (); if (steAux.what&evKeyboard) bSalir = TRUE; steAux.getMouseEvent (); if (steAux.what&evMouseUp) bSalir = TRUE; while (!bSalir); //Hasta presionar una tecla o raton void DUAMI188::vGuardarTodo () EDITWINDOW *psewAux1, *psewAux; psewAux1 = pstewObtenTopEditor (); psewAux = psewAux1; if (psewAux==0) return; do message (deskTop, evCommand, cmSave, CERO); message (deskTop, evCommand, cmNext, CERO); psewAux1 = pstewObtenTopEditor (); while (psewAux!=psewAux1);

F.37 FUNDEBUG.CPP //FUNCIONES DEL DEPURADOR #define Uses_TApplication #define Uses_TMenuBar #define Uses_TRect #define Uses_TSubMenu #define Uses_TKeys #define Uses_TMenuItem #define Uses_TStatusLine #define Uses_TStatusItem #define Uses_TStatusDef #define Uses_TPoint #define Uses_TEditor #define Uses_MsgBox #define Uses_TFileDialog #define Uses_TDeskTop #define Uses_TStaticText #define Uses_TButton #define Uses_TDeskTop #define Uses_TRect #define Uses_TFileEditor #define Uses_TFileDialog #define Uses_TChDirDialog #include <tv.h> #include "edit188.h" #include "define.h" #include "asmmaq.h" #include "debug.h" #include "cm_seria.h" void DUAMI188::vCargaFileDebug () //Carga un ejecutable al depurador char scFileName[MAXPATH], x; strcpy(scFileName, "*.COM" ); if (usEjecutarDialogo(new TFileDialog("*.COM", " Archivo ejecutable", "~N~ombre", fdOpenButton, 100), scFileName)!=cmCancel)

Page 369: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

364

if (!dCargaCODIGO(scFileName)) messageBox("Error al cargar programa o archi vo muy grande.", mfError | mfOKButton ); else psdwDWin->vMostrar (); psdwDWin->vResetAll (); void DUAMI188::vAbrirMAP () //Abre el archivo y le asigna un apuntador char scFileName[MAXPATH], x; strcpy(scFileName, "*.MAP" ); if(usEjecutarDialogo(new TFileDialog("*.MAP", "A brir mapa", "~N~ombre", fdOpenButton, 100), sc FileName)!=cmCancel) pstewAbrirEditor (scFileName, True);

F.38 GRAL_AM.CPP #include <stdio.h> #include <stdlib.h> #include <string.h> #include <conio.h> #include <malloc.h> #include <ctype.h> #include <lib.h> #include "define.h" #include "asmmaq.h" void vCargaDescriptores () /*Carga los descriptores*/ register int x, y; /*printf ("Cargando descriptores....");*/ for (x=0, y=0; x<LEN_IUNARG; x++) sBDesIntUnArg[x][DESIA_POS] = y; y = y + sBDesIntUnArg[x][DESIA_OPC]; for (x=0, y=0; x<LEN_IDOSARG; x++) sBDesIntDosArg[x][DESIA_POS] = y; y = y + sBDesIntDosArg[x][DESIA_OPC]; /*printf (" Terminado.\n\n");*/ word wNumOpcDescriptor (byte bDesc) /*Numero de opciones en los descriptores de inst rucciones de un y dos arg*/ word x, y, z; if (bDesc==DESCRIP_UN) z = LEN_IUNARG; else z = LEN_IDOSARG; for (x=0, y=0; x<z; x++) if (bDesc==DESCRIP_UN) y = y + sBDesIntUnArg[x][DESIA_OPC]; else y = y + sBDesIntDosArg[x][DESIA_OPC]; return (y); int iObtenPosDescriptor (byte bDesc, word wPos) /*Obtiene la posicion dentro de un descriptor (- 1 = error)*/ word x, y, z; if (bDesc==DESCRIP_UN) z = LEN_IUNARG; else z = LEN_IDOSARG; for (x=0, y=0; x<z; x++)

Page 370: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

365

if (bDesc==DESCRIP_UN) y = y + sBDesIntUnArg[x][DESIA_OPC]; else y = y + sBDesIntDosArg[x][DESIA_OPC]; if (y>wPos) return (x); return (CERO-1); dword dObtenNumero (char *pcText, word wLen, byte bTipo) /*Obtiene el numero*/ dword dNum=0, dCont=1; int x, iMul; for (x=0; x<wLen; x++); /*Para iniciar de atras hacia adelante*/ switch (bTipo) case NUM_TIPO_HEX: iMul = 16; x--; break; case NUM_TIPO_DEC: iMul = 10; break; case NUM_TIPO_BIN: iMul = 02; x--; break; default: iMul = 16; break; for (x--; x>=0; x--) bTipo = toupper (*(pcText+x)); /*Ya no se usa bTipo, por lo que la usamos*/ if (bTipo>64) dNum = dNum + ((bTipo - 55) * dC ont); else dNum = dNum + ((bTipo - 48) * dCont); dCont = dCont * iMul; return (dNum);

F.39 INDICA.CPP //RELOJ EN PANTALLA #define Uses_TRect #define Uses_TView #define Uses_TDrawBuffer #include <tv.h> #include <stdio.h> #include <lib.h> #include "indica.h" #include "color.h" INDICADOR::INDICADOR (TRect& pstrR): TView(pstrR) bEstado = INDICA_DSC; void INDICADOR::draw() TDrawBuffer stdbBuf; char scNum[7]; ushort usColor=getColor(2); switch (bEstado) case INDICA_OK: stdbBuf.moveStr(0, " OK", BVERDE|FIVERDE); break; case INDICA_STP: stdbBuf.moveStr(0, "STP", BROJO|FIBLANCO); break; case INDICA_RUN: stdbBuf.moveStr(0, "RUN", usColor|FIVERDE); break; case INDICA_DBG:

Page 371: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

366

stdbBuf.moveStr(0, "DBG", usColor|FIAMARILLO ); break; case INDICA_DSC: stdbBuf.moveStr(0, "DSC", BNEGRO|FIROJO); break; case INDICA_UKN: stdbBuf.moveStr(0, "???", BINEGRO|FIVERDE); break; default: sprintf (scNum, "%30d", bEstado); stdbBuf.moveStr(0, scNum, BIVERDE|FIBLANCO); break; writeLine(0, 0, 3, 1, stdbBuf); void INDICADOR::vIndicador (byte bInc) bEstado = bInc; draw (); byte INDICADOR::bObtenIndicador () return (bEstado);

F.40 INPUTNUM.CPP /*CONTIENE LAS FUNCIONES QUE SE EMPLEAN EN LA VENTA NA DE MENSAJES*/ #include <stdlib.h> #include <iostream.h> #include <fstream.h> #include <stdio.h> #include <string.h> #include <ctype.h> #define Uses_TEventQueue #define Uses_TEvent #define Uses_TInputLine #define Uses_TKeys #include <tv.h> #include "inputnum.h" INPUTNUM::INPUTNUM (const TRect& pstrR, int iMaxLe n, char cTipo): TInputLine (pstrR, iMaxLen) cTipoNum = cTipo; void INPUTNUM::handleEvent(TEvent& psteEvent) //Solo acepta numeros if (TSTBIT(psteEvent.what, evKeyDown)) switch (ctrlToArrow(psteEvent.keyDown.keyCode) ) case kbLeft: case kbRight: case kbHome: case kbEnd: case kbBack: case kbDel: case kbIns: break; default: if (psteEvent.keyDown.charScan.charCode>96 ) //A mayusculas psteEvent.keyDown.charScan.charCode = ps teEvent.keyDown.charScan.charCode - 32; if (psteEvent.keyDown.charScan.charCode<32 ) break;

Page 372: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

367

switch (cTipoNum) case INPUTNUM_BIN: if ((psteEvent.keyDown.charScan.charCode<48)||(psteEve nt.keyDown.charScan.charCode>49)) clearEvent(psteEvent); return; break; case INPUTNUM_HEX: if ((psteEvent.keyDown.charScan.charCode<48)||(psteEve nt.keyDown.charScan.charCode>70)) clearEvent(psteEvent); return; if ((psteEvent.keyDown.charScan.charCode<65)&&(psteEve nt.keyDown.charScan.charCode>57)) clearEvent(psteEvent); return; break; case INPUTNUM_DEC: default: if ((psteEvent.keyDown.charScan.charCode<48)||(psteEve nt.keyDown.charScan.charCode>57)) clearEvent(psteEvent); return; break; break; TInputLine::handleEvent(psteEvent); //Esta funcion debe ser UNICAMENTE empleada por la s cadenas que son //manipuladas por la clase INPUTNUM. dword dConvierteCadNum (char *pcCad, char cTipo) //Convierte un cadena a numero, no revisa. dword dRet=CERO, dMul=CERO+1; word x, wMul=CERO; byte bChar; for (x=0; *(pcCad+x); x++); //Fin de la cadena switch (cTipo) case INPUTNUM_BIN: wMul = 02; break; case INPUTNUM_HEX: wMul = 16; break; case INPUTNUM_DEC: wMul = 10; break; do x--; bChar = *(pcCad+x); if (bChar>57) bChar = bChar - 55; else bChar = bChar - 48; dRet = dRet + (bChar * dMul); dMul = dMul * wMul; while (x); return (dRet);

F.41 LABEL.CPP /*CONTIENE EL CODIGO PARA EL MANEJO DE ETIQUETAS*/ #include <stdio.h> #include <stdlib.h>

Page 373: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

368

#include <string.h> #include <malloc.h> #include <lib.h> #include "define.h" #include "asmmaq.h" word wAddEtiqueta (char *pcText, word wPos, word w Len, byte bTipo, byte bNumTipo, word wRefVal) /*Define una etiqueta*/ label *pslAux; word x; /*Primero se busca si existe una etiqueta simila r*/ if (pslBuscaEtiquetaConstante(pcText, wPos, wLen )) return (CREAWORD(wPos, ERR_NCA)); pslAux = (label *)pvMemLBL (sizeof(label)); /*Se agrega la etiqueta*/ if (!pslAux) return (ERR_NOM); pslAux->pcLabel = (char *)pvMemLBL (wLen+1); if (!(pslAux->pcLabel)) return (ERR_NOM); for (x=0; x<wLen; x++) /*Se almacena el nombre d e la etiqueta*/ *(pslAux->pcLabel+x) = *(pcText+wPos+x); *(pslAux->pcLabel+x) = CERO; pslAux->bTipo = bTipo; /*Puede ser una constant e o etiqueta*/ if (bTipo==ID_ETIQUETA) pslAux->wCont = WContInstLBL; WContInstLBL++; else pslAux->wCont = CERO; pslAux->bNumTipo = bNumTipo; pslAux->dRefVal = wRefVal; if (!psLEtiqueta) psLEtiqueta = pslAux; else psLActual->pslSig = pslAux; psLActual = pslAux; pslAux->pslSig = CERO; return (ERR_NE); label *pslBuscaEtiquetaConstante (char *pcText, wo rd wPos, word wLen) label *pslAux; if (!psLEtiqueta) return (CERO); pslAux = psLEtiqueta; while (pslAux) if (cChkStr(pcText+wPos, wLen, pslAux->pcLabel , FALSE)) return (pslAux); pslAux = pslAux->pslSig; return (CERO); word wAddInstruccion (char *pcText, word wLen, wor d wRef, word wLin) /*Agrega una instruccion a la lista*/ inst *psiAux, *psiAux2; word x, wIzq, wDer, y; byte bSalir; if (!TSTBIT(WConstASM, CTEASM_LBL)) return (ERR_ EIE); WConstASM = SETBIT(WConstASM, CTEASM_NOREF); psiAux = (inst *)pvMemLBL (sizeof(inst)); if (!psiAux) return (ERR_NOM); /*Se van a quitar los espacios y tab's para ahor rar memoria*/ x = CERO; while ((*(pcText+x)==CHAR_ESP)||(*(pcText+x)==CH AR_TAB)) x++; wIzq = x; /*Lo que se quita lado izquierdo*/ x = wLen - 1; while ((*(pcText+x)==CHAR_ESP)||(*(pcText+x)==CH AR_TAB)) x--; wDer = x; /*Lo que se quita lado derecho*/ wLen = wDer - wIzq + 1; /*Nueva longitud*/ /*Ahora se verifica que no existan repetidos*/ psiAux2 = psIInstruccion; bSalir = FALSE;

Page 374: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

369

while ((psiAux2)&&(!bSalir)) bSalir = TRUE; for (x=0, y=wIzq; y<=wDer; x++, y++) if (*(psiAux2->pcInst+x)!=*(pcText+y)) bSa lir = FALSE; break; if (*(psiAux2->pcInst+x)) bSalir = FALSE; if (!bSalir) psiAux2 = psiAux2->psiSig; if (!psiAux2) psiAux->pcInst = (char *)pvMemLBL (wLen+1); if (!(psiAux->pcInst)) return (ERR_NOM); for (x=0; wIzq<=wDer; x++, wIzq++) *(psiAux->p cInst+x) = *(pcText+wIzq); *(psiAux->pcInst+x) = CERO; else psiAux->pcInst = psiAux2->pcInst; psiAux->bNumCod = CERO; /*No hay codigo*/ psiAux->wRef = wRef; /*La referencia*/ psiAux->wLin = wLin; /*El numero de linea*/ psiAux->wCont = WContInstLBL; /*Numero instrucc ion*/ WContInstLBL++; if (!psIInstruccion) psIInstruccion = psiAux; else psIActual->psiSig = psiAux; psIActual = psiAux; psiAux->psiSig = CERO; return (ERR_NE); /*En etiquetas solo hay dos opciones: */ /* */ /* * Etiqueta + : Define una etiquet a. */ /* * Etiqueta + EQU + NUMERO Define una constan te. */ /*y EQU y : es lo que se revisa para poder hacer u na diferencia */ word wCodEtiqueta (nodo *psnLista, char *pcText, w ord wRef) word wRet; nodo *psnAux; psnAux = psnLista->psnSig; switch (psnAux->bTipo) case ID_OPERADOR: /*Etiqueta*/ if (!TSTBIT(WConstASM, CTEASM_LBL)) return ( ERR_LBL); /*No se definen LBL*/ if ((psnAux->bNumTipo==CHAR_2PUN)&&(psnAux-> bTipo==ID_OPERADOR)) if (!(psnAux->psnSig)) if (TSTBIT(WConstASM, CTEASM_NOREF)) /* No hay referencia*/ wRet = wAddEtiqueta (pcText, psnLista- >bPos-1, psnLista->dNumero, ID_ETIQUETA, ID_LBL_NDF, wRef); /*ERR Se asume ID_ETIQUETA*/ else /*La etiqueta tiene referencia*/ wRet = wAddEtiqueta (pcText, psnLista- >bPos-1, psnLista->dNumero, ID_ETIQUETA, ID_LBL_DEF, wRef); /*ERR Se asume ID_ETIQUETA*/ else wRet = CREAWORD (psnAux->psnSig->bPos, E RR_ONV); else wRet = CREAWORD (psnAux->bPos, ERR_SEL); break; case ID_RESWORD: /*constante EQU*/ if (!TSTBIT(WConstASM, CTEASM_CTE)) return ( ERR_CTE); /*No se definen CTE*/ switch (psnAux->bNumTipo) case ID_RW_EQU: psnAux = psnAux->psnSig; if (psnAux->bTipo==ID_NUMERO) /*Es un nu mero*/ if (psnAux->psnSig) wRet = CREAWORD (psnAux->psnSig->bP os, ERR_ONV); else wRet = wAddEtiqueta (pcText, psnLis ta->bPos-1, psnLista->dNumero, ID_CONSTANTE, psnAux->bNumTipo, psnAux->dNumero); /*ERR Se asume ID_NUMERO*/ else wRet = CREAWORD (psnAux->psnSig->bPos, ERR_EEA); break; case ID_RW_PROC:

Page 375: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

370

if (!TSTBIT(WConstASM, CTEASM_LBL)) retu rn (ERR_LBL); /*No se definen LBL*/ if (!(psnAux->psnSig)) if (TSTBIT(WConstASM, CTEASM_NOREF)) /*No hay referencia*/ wRet = wAddEtiqueta (pcText, psnList a->bPos-1, psnLista->dNumero, ID_ETIQUETA, ID_LBL_NDF, wRef); /*ERR Se asume ID_ETIQUETA*/ else /*La etiqueta tiene referencia*/ wRet = wAddEtiqueta (pcText, psnList a->bPos-1, psnLista->dNumero, ID_ETIQUETA, ID_LBL_DEF, wRef); /*ERR Se asume ID_ETIQUETA*/ else wRet = CREAWORD (psnAux->psnSig->bPos, ERR_ONV); break; default: wRet = CREAWORD (psnAux->bPos, ERR_SEL); break; break; default: /*Error*/ wRet = CREAWORD (psnAux->bPos, ERR_SEL); break; return (wRet); byte bEsInstruccion (nodo *psnAux) switch (psnAux->bTipo) case ID_INOARG: /*Instrucciones sin argumentos */ case ID_IUNARG: /*Instrucciones de un argument o*/ case ID_IDOSARG: /*Instrucciones de dos argume ntos*/ case ID_IESP: /*Instrucciones especiales*/ return (TRUE); return (FALSE); void vAddRefInst (inst *psiAux, byte bAdd) while (psiAux) psiAux->wRef = psiAux->wRef + bAdd; psiAux = psiAux->psiSig; void vAddRefLBL (label *pslAux, inst *psiAux, byte bAdd) while (pslAux) if (pslAux->bTipo==ID_ETIQUETA) if ((psiAux->wRef<=pslAux->dRefVal)&&((pslAu x->bNumTipo==ID_LBL_TST))) if (pslAux->wCont>psiAux->wCont) /*Contad or*/ pslAux->dRefVal = pslAux->dRefVal + bAdd ; pslAux = pslAux->pslSig; void vLiberaLBLCTE () vLiberaMemLBL (); psLEtiqueta = CERO; /*Ninguna etiqueta definida */ psIInstruccion = CERO; /*Ninguna instruccion po r compilar*/ word wResuelveRef () /*Resuelve todas la referencias*/ /*ERR Se asume que el codigo no supera los MAX_N FILE-1*/ byte sbCod[MAX_NFILE]; word wPos, wErr; byte bSalir, bResta;

Page 376: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

371

label *pslAux; inst *psiAux; pslAux = psLEtiqueta; psiAux = psIInstruccion; /*Si es segundo paso no hace nada*/ if (TSTBIT(WConstASM, CTEASM_2PASO)) return (ERR _NE); /*Segundo paso*/ /*No hay etiquetas y/o instrucciones*/ if ((!psiAux)||(!pslAux)) return (ERR_NE); /*Primero fija las etiquetas en PRUEBA y las ins trucciones*/ while (pslAux) /*Fija las etiquetas en modo de prueba*/ if (pslAux->bTipo==ID_ETIQUETA) if (pslAux->bNumTipo==ID_LBL_NDF) pslAux->bNumTipo = ID_LBL_TST; /*Prueba*/ pslAux = pslAux->pslSig; bSalir = FALSE; while (!bSalir) psiAux = psIInstruccion; bSalir = TRUE; while (psiAux) wPos = psiAux->wRef; wErr = wASM2MAQ (psiAux->pcInst, sbCod, &wPo s, CERO); /*Si hay error, la referencia no se puede re solver. */ /*ERR agrega cualquier cosa*/ if (!(sbCod[LEN_COD])||(wErr)) sbCod[LEN_COD ] = ADD_REF_ERR; /*Solo se va agregar el byte que hace falta* / bResta = sbCod[LEN_COD] - psiAux->bNumCod; if (bResta) vAddRefInst (psiAux->psiSig, bResta); psiAux->bNumCod = sbCod[LEN_COD]; bSalir = FALSE; vAddRefLBL (psLEtiqueta, psiAux, bResta); psiAux = psiAux->psiSig; pslAux = psLEtiqueta; while (pslAux) if (pslAux->bTipo==ID_ETIQUETA) pslAux->bNumTipo = ID_LBL_DEF; /*Se definen todas*/ pslAux = pslAux->pslSig; return (ERR_NE); word wSustituyeLBLCTE (nodo *psnAux, char *pcText) /*Ya resueltas las etiquetas, se sustituyen*/ label *pslAux; /*nodo *psnAux1; /*Se asume que el primer token es para definicio n*/ /*VAR:*/ /*VAR EQU XXX*/ /*VAR PROC*/ /*Por lo que cambia todo lo demas*/ if (!psnAux) return (ERR_NE); psnAux = psnAux->psnSig; while (psnAux) if (psnAux->bTipo==ID_LBLCTE) /*Solo si es cte o etiqueta*/ /*Aqui se analiza la lista de etiquetas o co nstantes para sustuir*/ /*psnAux1 = psnAux->psnSig; if (psnAux1) if (((psnAux1->bTipo==ID_OPERADOR)&&(psnAu x1->bNumTipo==CHAR_2PUN))||((psnAux1->bTipo==ID_RESWORD)&&((psnAux1->bNumTipo==ID_RW_EQU )||(psnAux1->bNumTipo==ID_RW_PROC)))) return (ERR_NE); /*Definicion de una et iqueta o constante, no se sustituye*/ /*Se procede buscar y sustituir o en todo ca so guardar la instruccion*/ pslAux = pslBuscaEtiquetaConstante(pcText, p snAux->bPos-1, LWORD(psnAux->dNumero));

Page 377: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

372

if (pslAux) /*Se encontro, se sustituye o s e guarda*/ switch (pslAux->bTipo) /*Se supone que nada mas dos tipos hay*/ case ID_CONSTANTE: /*Se sustituye el va lor de la constante*/ psnAux->dNumero = pslAux->dRefVal; psnAux->bTipo = ID_NUMERO; psnAux->bNumTipo = pslAux->bNumTipo; break; case ID_ETIQUETA: /*Si se puede sustitu ye*/ if ((pslAux->bNumTipo==ID_LBL_DEF)||(p slAux->bNumTipo==ID_LBL_TST)) /*TST se usa en segunda pasada*/ /*32! Hay etiquetas de 32 bits*/ psnAux->dNumero = pslAux->dRefVal; psnAux->bTipo = ID_NUMERO; psnAux->bNumTipo = ID_NUM16; else /*Se va a segunda pasada, ya que la etiqueta no tiene ref*/ WConstASM = SETBIT (WConstASM, CTEAS M_SAVEI); break; else /*No esta en la lista, hara falta segun da pasada*/ WConstASM = SETBIT (WConstASM, CTEASM_SAVE I); psnAux = psnAux->psnSig; return (ERR_NE); word wAddINCLUDE (char *pcFile, word wLin) /*Agrega el archivo que se incluye para compilar */ include *psincAux; char scAux[MAX_NFILE]; vObtenNombreArch (scAux, pcFile, TRUE, MAX_NFILE -1); psincAux = psINCInclude; while (psincAux) /*Verifica que no exista*/ if (!strcmp(psincAux->scFile, scAux)) psincAux->wLin = wLin; return (ERR_NE); psincAux = psincAux->psincSig; /*Como no existe lo agrega*/ psincAux = (include *)pvMemLBL (sizeof(include)) ; if (!psincAux) return (ERR_NOM); strcpy (psincAux->scFile, scAux); if (!psINCInclude) psINCInclude = psincAux; else psINCActual->psincSig = psincAux; psINCActual = psincAux; psincAux->psincSig = CERO; psincAux->wLin = wLin; return (ERR_NE); byte bCreaMAP (char *pcFile) /*Genera el archivo MAP*/ FILE *psfOut; label *pslAux; word wCTE, wLBL; /*Lo ideal es que envie ordenados las etiquetas y constantes*/ pslAux = pslOrdenaLBLCTE (psLEtiqueta); psLEtiqueta = pslAux; if (!pslAux) return (TRUE); /*No hay etiquetas y/o constantes*/ psfOut = fopen (pcFile, "wt"); if (!psfOut) return (FALSE); /*Primero las constantes*/ fprintf (psfOut, "NOMBRE_CONSTANTE = VALOR\n\n") ; wCTE = CERO; wLBL = CERO; while (pslAux)

Page 378: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

373

if (pslAux->bTipo!=ID_ETIQUETA) /*Constantes*/ fprintf (psfOut, " %s = 0%XH\n", pslAux->pcL abel, pslAux->dRefVal); wCTE++; pslAux = pslAux->pslSig; pslAux = psLEtiqueta; /*Ahora las etiquetas*/ fprintf (psfOut, "\n**************************** *****************\n"); fprintf (psfOut, "NOMBRE_ETIQUETA <- DIRECCION\n \n"); while (pslAux) if (pslAux->bTipo==ID_ETIQUETA) /*Etiquetas*/ if (pslAux->bNumTipo==ID_LBL_NDF) fprintf (psfOut, " %s <- ERROR NO DEFINIDA \n", pslAux->pcLabel); else fprintf (psfOut, " %s <- 0%XH\n", pslAux-> pcLabel, pslAux->dRefVal); wLBL++; pslAux = pslAux->pslSig; fprintf (psfOut, "\n\nEstadisticas:\n\n"); fprintf (psfOut, "Total de constantes: %d\n", wC TE); fprintf (psfOut, "Total de etiquetas: %d\n", wL BL); fprintf (psfOut, "Memoria empleada: %u bytes\ n", USE_LBLCTE()); fclose (psfOut); return (TRUE); label *pslOrdenaLBLCTE (label *pslAux) /*Ordena las constantes y etiquetas*/ label *pslOut, *pslOutAct; label *pslAnt, *pslAct, *pslCmpAnt, *pslCmpAct; pslOut = CERO; pslOutAct = CERO; while (pslAux) pslAnt = CERO; /*Anterior*/ pslAct = pslAux; /*Actual*/ pslCmpAnt = CERO; /*Anterior*/ pslCmpAct = pslAux; /*Actual*/ while (pslCmpAct) if (strcmp(pslCmpAct->pcLabel, pslAct->pcLab el)<=CERO) pslAnt = pslCmpAnt; pslAct = pslCmpAct; pslCmpAnt = pslCmpAct; pslCmpAct = pslCmpAct->pslSig; /*Creamos la nueva lista*/ if (pslAnt) pslAnt->pslSig = pslAct->pslSig; else pslAux = pslAux->pslSig; /*Va creando la lista*/ if (!pslOut) pslOut = pslAct; else pslOutAct->pslSig = pslAct; pslOutAct = pslAct; pslAct->pslSig = CERO; return (pslOut);

F.42 MEMORIA.CPP /*CONTIENE EL CODIGO PARA EL MANEJO INTERNO DE MEMO RIA DEL ENSAMBLADOR*/ #include <malloc.h>

Page 379: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

374

#include <lib.h> #include <alloc.h> #include "define.h" #include "asmmaq.h" /*CONTIENE EL CODIGO PARA EL MANEJO DE LA MEMORIA*/ /*Los argumentos son wMEM = memoria para procesar instrucciones, este*/ /*valor es importante; wLBLCTE = memoria para proc esar etiquetas, */ /*constantes e instrucciones a compilar, es opcion al segun la */ /*aplicacion. */ int iIniciaMem (word wMEM, word wLBLCTE, word wMax Msg) WMemCont = CERO; WLblCont = CERO; pcLBLMEM = CERO; /*Primero memoria para procesar instrucciones*/ if (!wMEM) return (CERO); pCMEM = (char *)farmalloc(wMEM); if (!pCMEM) return (CERO); WTamMEM = wMEM; /*Memoria para procesar etiquetas, constantes e instrucciones*/ if (wLBLCTE) pcLBLMEM = (char *)farmalloc(wLBLCTE); if (!pcLBLMEM) return (CERO); WTamLBL = wLBLCTE; /*Memoria para procesar los mensajes*/ pWMensajes = (word *)farmalloc ((wMaxMsg*2)); if (!pWMensajes) return (CERO); pWLineas = (word *)farmalloc ((wMaxMsg*2)); if (!pWLineas) return (CERO); /*Memoria para procesar archivos anidados*/ pCInclude = (char *)farmalloc (MAX_PATH); if (!pCInclude) return (CERO); return (CERO+1); void vTerminaMem () farfree (pCInclude); farfree (pWLineas); farfree (pWMensajes); if (TSTBIT(WConstASM, CTEASM_LBL|CTEASM_CTE)) fr ee (pcLBLMEM); farfree (pCMEM); void *pvMemoria (word wMem) word x; x = WMemCont + wMem; if (x>WTamMEM) return (CERO); /*No hay memoria*/ x = WMemCont; WMemCont = WMemCont + wMem; return (pCMEM+x); void vLiberaMem () WMemCont = CERO; void *pvMemLBL (word wMem) /*No se puede liberar memoria, se usa una sola v ez en cada compilacion*/ word x; if (!pcLBLMEM) return (CERO); x = WLblCont + wMem; if (x>WTamLBL) return (CERO); /*No hay memoria*/ x = WLblCont; WLblCont = WLblCont + wMem; return (pcLBLMEM+x);

Page 380: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

375

void vLiberaMemLBL () /*Libera la memoria de etiquetas, instrucciones e include, apuntadores tambien*/ WLblCont = CERO; psLEtiqueta = CERO; /*Lista de etiquetas y cons tantes*/ psIInstruccion = CERO; /*Lista de instrucciones */ psLActual = CERO; /*Para uso de etiquetas*/ psIActual = CERO; /*Para uso de instrucciones*/ psINCInclude = CERO; /*Para uso de archivos inc lude*/ psINCActual = CERO; /*Para uso de archivos incl ude*/

F.43 MENSAJE.CPP /*CONTIENE LAS FUNCIONES QUE SE EMPLEAN EN LA VENTA NA DE MENSAJES*/ #include <stdlib.h> #include <iostream.h> #include <fstream.h> #include <stdio.h> #include <string.h> #include <ctype.h> #define Uses_TEventQueue #define Uses_TEvent #define Uses_TProgram #define Uses_TApplication #define Uses_TKeys #define Uses_TRect #define Uses_TMenuBar #define Uses_TSubMenu #define Uses_TMenuItem #define Uses_TStatusLine #define Uses_TStatusItem #define Uses_TStatusDef #define Uses_TDeskTop #define Uses_TView #define Uses_TWindow #define Uses_TScroller #define Uses_TScrollBar #include <tv.h> #include "mensaje.h" #include "asmmaq.h" #include "define.h" #include "command.h" #include "color.h" const int maxLineLength = MAX_LENMSG + 30; //Numer o de caracteres maximos a ver MENSAJES::MENSAJES (const TRect& pstrR) : TWindow (pstrR, "Mensajes", wnNoNumber), TWindowInit (&MENSAJES::initFrame) palette = wpGrayWindow; options = options | ofTileable; vCreaInterior(); // creates scrollable interior and inserts into window void MENSAJES::vCreaInterior () TScrollBar *pstsbVScroll = standardScrollBar(sbV ertical|sbHandleKeyboard); TScrollBar *pstsbHScroll = standardScrollBar(sbH orizontal|sbHandleKeyboard); TRect strR = getClipRect (); strR.grow(-1, -1); pstsmScroll = new SCROLLMSG(strR, pstsbHScroll, pstsbVScroll); insert(pstsmScroll);

Page 381: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

376

void MENSAJES::close () //Oculta la pantalla de mensaje, es sustituida hide (); void MENSAJES::vCerrar () //Cierra definitivamente la pantalla, sustituye a close TWindow::close (); void MENSAJES::vMostrar () //Muestra la ventana de mensaje select (); show (); pstsmScroll->draw (); MENSAJES::~MENSAJES () SCROLLMSG::SCROLLMSG (const TRect& pstrR, TScrollB ar *pstsbHScroll, TScrollBar *pstsbVScroll) : TScroller (pstrR, pstsbHScroll, pstsbVScroll) growMode = gfGrowHiX | gfGrowHiY; options = options | ofFramed; wMaxLineas = CERO; //SCROLL_MIN_MSG; iPosCur = CERO; //Posicion del cursor setLimit (maxLineLength, wMaxLineas); //Longitu d de los mensajes y numero de mensajes void SCROLLMSG::draw() //Para dibujar con el scroll //Esta funcion emplea variables globales del com pilador ushort usColor; include *psincAux; char scAux[maxLineLength], scAux2[maxLineLength] ; TDrawBuffer stdbBuf; int j; TRect strR; strR = getBounds (); j = strR.b.y - strR.a.y; psincAux = psINCInclude; wMaxLineas = NUMMENSAJES(); if (iPosCur>wMaxLineas) iPosCur = delta.y; if (iPosCur<delta.y) iPosCur = delta.y; if (iPosCur>(delta.y+j)) iPosCur = delta.y; setLimit (maxLineLength, wMaxLineas); for (int i=0; i<size.y; i++) j = delta.y + i; //Posicion Y del Scroll if (iPosCur==j) usColor = CREA_COLOR (BAZUL, F IBLANCO); else usColor = CREA_COLOR (BGRIS, FNEGRO); stdbBuf.moveChar(0, ' ', usColor, size.x); // Llena de espacios if (j<wMaxLineas) scAux[0] = CERO; if (LBYTE(*(pWMensajes+j))<=ERR_LSTWAR) /*E rrores y Warnings*/ if (LBYTE(*(pWMensajes+j))<=ERR_LSTERR) strcpy (scAux, "Error "); usColor = CRE A_COLOR (BGRIS, FROJO); else strcpy (scAux, "Warning "); usColor = C REA_COLOR (BGRIS, FIAMARILLO); if (*(pWLineas+j))

Page 382: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

377

sprintf (scAux2, "L[%d] ", *(pWLineas+j) ); strcat (scAux, scAux2); if (HBYTE(*(pWMensajes+j))) sprintf (scAux2 ,"C[%d] ", HBYTE(*(pWMen sajes+j))); strcat (scAux, scAux2); sprintf (scAux2, ": %s", sCError[LBYTE(*(p WMensajes+j))]); strcat (scAux, scAux2); else //Mensajes, usa color default if (LBYTE(*(pWMensajes+j))==MSG_LBL) while ((*(pWLineas+j)!=psincAux->wLin)&& (psincAux)) psincAux = psincAux->psincSig; if (psincAux) strcpy (sCError[MSG_LBL], "Archivo INC LUDE: "); strcat (sCError[MSG_LBL], psincAux->sc File); psincAux = psincAux->psincSig; usColor = CREA_COLOR (BGRIS, FICYAN); //if (LBYTE(*(pWMensajes+j))==MSG_SCA) usC olor = CREA_COLOR (BGRIS, FCYAN); switch (HBYTE(*(pWMensajes+j))) case 0: sprintf (scAux, "L[%d] : %s", *(pWLine as+j), sCError[LBYTE(*(pWMensajes+j))]); break; case 2: sprintf (scAux, "%d", *(pWLineas+j)); case 1: sprintf (scAux2, "%s", sCError[LBYTE(* (pWMensajes+j))]); strcat (scAux, scAux2); break; case 3: sprintf (scAux, "%s %d", sCError[LBYTE (*(pWMensajes+j))], *(pWLineas+j)); break; if (delta.x>strlen(scAux)) scAux2[0] = CERO; else strncpy (scAux2, scAux+delta.x, size.x); scAux[size.x] = EOS; if (iPosCur==j) usColor = CREA_COLOR (BAZUL, FIBLANCO); stdbBuf.moveStr (0, scAux2, usColor); //Col oca el texto writeLine (0, i, size.x, 1, stdbBuf); void SCROLLMSG::handleEvent(TEvent& psteEvent) int x; TRect strR; strR = getBounds (); x = strR.b.y - strR.a.y; if(TSTBIT(psteEvent.what, evKeyboard)) switch (psteEvent.keyDown.keyCode) //Intercepta teclas Arriba y Abajo case kbUp: //Arriba iPosCur--; if (iPosCur<0) iPosCur = 0;

Page 383: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

378

if (iPosCur<delta.y) vCambiaVScroll (delta.y-1); draw (); break; case kbDown: //Abajo iPosCur++; if (limit.y>x) if (iPosCur>=(x+delta.y)) vCambiaVScroll (delta.y+1); if (iPosCur>=wMaxLineas) iPosCur = wMaxLin eas - 1; draw (); break; case kbPgDn: case kbPgUp: default: TScroller::handleEvent(psteEvent); return; clearEvent (psteEvent); return; TScroller::handleEvent(psteEvent); inline void SCROLLMSG::vCambiaVScroll (int iPos) drawLock = True; vScrollBar->setValue(iPos); drawLock = False;

F.44 PSERIE.CPP //CONTIENE EL CODIGO PARA EL MANEJO DEL PUERTO SERI E //EL PUERTO SERIE MANEJA UNA INTERRUPCION PERO UNIC AMENTE RECEPCION #include <lib.h> #include <stdio.h> #include <dos.h> #include <bios.h> #include <conio.h> #define MAIN_SERIAL #include "pserie.h" void vIniciaPuertoSerie (byte bCOM, byte bNumBits, byte bStopBits, byte bParidad, byte bVel) //Inicia el puerto serie, inhabilita las interru pciones int iDiv; long lVelocidad; byte bLCR, bAux; bInicioCola = CERO; //La cola de recepcion esta vacia bFinCola = CERO; bInterrupcion = FALSE; bContadorEmerg = CERO; switch (bCOM) //Coloca el puerto, por default es COM1 case COMM2: wDirPuerto = DIRCOM2; bNumIRQ = IRQCOM2; break; default: case COMM1: wDirPuerto = DIRCOM1; bNumIRQ = IRQCOM1; break; //Ya tenemos los puertos

Page 384: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

379

disable (); //Inhabilita interrupciones outportb (wDirPuerto+IER, 0x00); //Deshabilita interrupciones en la UART ViVectAnt = getvect (bNumIRQ+BASE_IRQ); //Guard a el vector anterior setvect (bNumIRQ+BASE_IRQ, viInterrupcionSerieRe cev); switch (bVel) case COMVEL_1200: lVelocidad = 1200; break ; case COMVEL_2400: lVelocidad = 2400; break ; case COMVEL_4800: lVelocidad = 4800; break ; case COMVEL_19200: lVelocidad = 19200; break ; default: case COMVEL_9600: lVelocidad = 9600; break; iDiv = (int)(1843200/(16*lVelocidad)); //Calcul a la velocidad outportb (wDirPuerto+LCR, 0x80); //Para acceder al divisor (DLAB) outport (wDirPuerto+DLL, iDiv); //La fija if ((bNumBits<5)||(bNumBits>8)) bNumBits = 8; / /Por default son 8 bLCR = bNumBits - 5; //Se va colocar los bits d e paridad, stop, etc bLCR = bLCR | bParidad | bStopBits; //Coloca la paridad y bit de parada outportb (wDirPuerto+LCR, bLCR); //Coloca los v alores en el registro LCR outportb(wDirPuerto+FCR, 0x00); //Desactiva la caracteristica FIFO //Inicia programacion de la interrupcion outportb(wDirPuerto+MCR, 0x08); //Activa bit OU T2 para 8259 outportb (wDirPuerto+IER, 0x05); //Habilita in terrupciones en la UART while (bRecibeDato(&bAux)); //Quitamos la basur a bAux = inportb (wDirPuerto+LSR); bAux = inportb (wDirPuerto+MSR); bAux = inportb (wDirPuerto+IIR); bLimpiaCola (); //Falta activar las interrupciones con vInterrup cionPtoSerie para 8259 enable (); //Pero aun no se activa la interrupc ion void vTerminaPuertoSerie () byte bAux; disable (); //Desactiva las interrupciones outportb (wDirPuerto+IER, 0); //Desactiva inter rupcion outportb (wDirPuerto+MCR, 0); //Desactiva Out2 outportb (wDirPuerto+LCR, 0); //Desactiva LCR bAux = inportb (wDirPuerto+LSR); bAux = inportb (wDirPuerto+IIR); bAux = inportb (wDirPuerto+MSR); //Quita la programacion del 8279 bAux = inportb (PT8259+OCW1); bAux = SETBITN (bAux, bNumIRQ); //Enmascara (de sactiva) interrupcion outportb (PT8259+OCW1, bAux); //Retorna el vector anterior setvect (bNumIRQ, ViVectAnt); //Limpia la cola bLimpiaCola (); enable (); //Habilita las interrupciones byte bEstadoInterrupcion () //Si es FALSE la interrupcion esta inactiva return (bInterrupcion); void vInterrupcionPtoSerie (byte bFlag) //Activa/desactiva la interrupcion para recepcio n byte bAux; disable (); bAux = inportb (PT8259+OCW1); if (bFlag) bAux = CLSBITN (bAux, bNumIRQ); //Desenmascar a (activa) el 8259 bInterrupcion = TRUE; outportb(wDirPuerto+MCR, 0x08); //Activa bit OUT2 para 8259

Page 385: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

380

else bAux = SETBITN (bAux, bNumIRQ); //Enmascara ( desactiva) el 8259 bInterrupcion = FALSE; outportb(wDirPuerto+MCR, 0x00); //Desactiva b it OUT2 para 8259 outportb (PT8259+OCW1, bAux); enable (); byte bEnviaDato (byte bDato) //Retorna TRUE en caso de envio byte bAux; bAux = inportb (wDirPuerto+LSR); //Verificamos si hay error if (bAux&0x0E) bAux = inportb (wDirPuerto+LSR); //Lo leemos de nuevo if (!TSTBITN(bAux, 5)) return (FALSE); outportb (wDirPuerto+THR, bDato); return (TRUE); byte bRecibeDato (byte *pbDato) //Retorna TRUE en caso de recepcion (NO usa inte rrupcion) byte bAux; bAux = inportb (wDirPuerto+LSR); if (bAux&0x0E) bAux = inportb (wDirPuerto+LSR); //Lo leemos de nuevo if (!TSTBITN(bAux, 0)) return (FALSE); *pbDato = inportb (wDirPuerto+RBR); return (TRUE); byte bObtenDatoCola (byte *pbDato) //Obtiene dato de la cola, retorna TRUE en caso de exito disable (); if (bInicioCola==bFinCola) return (FALSE); *pbDato = sbCola[bInicioCola]; bInicioCola = (bInicioCola + 1) % LEN_COLA_SERIA L; enable (); return (TRUE); byte bColaLlena () byte bAux; bAux = bFinCola; bAux++; if (bAux>=LEN_COLA_SERIAL) bAux = CERO; if (bAux==bInicioCola) return (TRUE); return (FALSE); byte bColaVacia () if (bFinCola==bInicioCola) return (TRUE); //Col a vacia return (FALSE); //La cola contiene elementos byte bNumeroElementos () byte bCont, bAux; for (bAux=bInicioCola, bCont=0; bAux!=bFinCola; bAux++, bCont++) if (bAux>=LEN_COLA_SERIAL) bAux = CERO; return (bCont); //word WWCont=65; void interrupt viInterrupcionSerieRecev (...)

Page 386: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

381

//Agrega un dato a la cola byte bAux, bDato; //byte far *VIDEO= (byte far *)MK_FP (0xb800, 15 6); bAux = inportb (wDirPuerto+LSR); //Para leer lo s errores bAux = inportb (wDirPuerto+IIR); //*(VIDEO) = LBYTE (WWCont); WWCont++; switch (bAux) case INTSER_ERROR: bAux = inportb (wDirPuerto+LSR); break; case INTSER_RECDAT: bDato = inportb (wDirPuerto+RBR); bAux = bFinCola; bFinCola++; bFinCola = bFinCola % LEN_COLA_SERIAL; if (bFinCola==bInicioCola) bFinCola = bAux; else bAux = bAux % LEN_COLA_SERIAL; sbCola[bAux] = bDato; break; case INTSER_NONE: case INTSER_TIMEOUT: case INTSER_TRANS: case INTSER_MODEM: default: bAux = inportb (wDirPuerto+LSR); bAux = inportb (wDirPuerto+MSR); break; outportb (PT8259+OCW2, 0x20); //Fin de interrup cion no especifica void bLimpiaCola () bFinCola = CERO; bInicioCola = CERO; bContadorEmerg = CERO; void vCambiaVelocidad (byte bVel) long lVelocidad; int iDiv; byte bLCR; bLCR = inportb (wDirPuerto+LCR); //Obtiene el L CR switch (bVel) case COMVEL_1200: lVelocidad = 1200; break; case COMVEL_2400: lVelocidad = 2400; break; case COMVEL_4800: lVelocidad = 4800; break; case COMVEL_19200: lVelocidad = 19200; break ; case COMVEL_9600: default: lVelocidad = 9600; break; iDiv = (int)(1843200/(16*lVelocidad)); //Calcul a la velocidad outportb (wDirPuerto+LCR, 0x80); //Para acceder al divisor (DLAB) outport (wDirPuerto+DLL, iDiv); //La fija outportb (wDirPuerto+LCR, bLCR); //La coloca de nuevo void vLimpiaPuerto () byte bAux; while (bRecibeDato(&bAux)); //Quitamos la basur a byte bLeeEstado ()

Page 387: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

382

byte bAux; bAux = inportb (wDirPuerto+LSR); return (bAux); /*void main () word wKey; byte bDato; byte bSalir=FALSE; clrscr (); vIniciaPuertoSerie (COMM2, 8, 1, COM_SINPARIDAD, 14400); //while (!bSalir) // if (bRecibeDato(&bDato)) printf ("Char: %02X Edo: %02X\n", bDato, b LeeEstado()); // vInterrupcionPtoSerie (TRUE); //Habilita interr upcion while (wKey!=0x011B) wKey = bioskey (1); if ((wKey)&&(wKey!=0x011B)) //Envia un dato getch (); bDato = (byte)wKey; bEnviaDato (bDato); if (bColaLlena()) if (bObtenDatoCola(&bDato)) printf ("%c(%d )", bDato, bNumeroElementos()); printf ("\n%d\n", bNumeroElementos()); while (bObtenDatoCola(&bDato)) printf ("%c", bDa to); printf ("\n%d", bNumeroElementos()); vTerminaPuertoSerie (); */

F.45 REGISTRO.CPP //CONTIENE LAS FUNCIONES PARA EL MANEJO DE LOS REGI STROS //ESTAS FUNCIONES NO REFLEJAN LOS CAMBIOS EN EL DEP URADOR, POR LO //QUE HAY QUE ACTUALIZAR ESTA VENTANA. #define Uses_TApplication #define Uses_TMenuBar #define Uses_TRect #define Uses_TSubMenu #define Uses_TKeys #define Uses_TMenuItem #define Uses_TStatusLine #define Uses_TStatusItem #define Uses_TStatusDef #define Uses_TPoint #define Uses_TEditor #define Uses_MsgBox #define Uses_TFileDialog #define Uses_TDeskTop #define Uses_TStaticText #define Uses_TButton #define Uses_TDeskTop #define Uses_TRect #define Uses_TFileEditor #define Uses_TFileDialog #define Uses_TChDirDialog #include <stdlib.h> #include <stdio.h> #include <tv.h> #include "edit188.h" #include "biosvars.h" #include "define.h" #include "asmmaq.h"

Page 388: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

383

void vIniciaRegistros () //Coloca en los registros los valores por defaul t word x, y, z; char scBuf[10]; for (x=0; x<DBGREG_NUMREG; x++) //Coloca puros CEROS y = x * DBGREG_LENREG; for (z=0; z<DBGREG_NUMDIG; z++) sCRegWindow[y+z+DBGREG_POSVAL] = '0'; sCRegWindow[y+z+DBGREG_POSVAL] = 'H'; vCambiaRegistro (DBGREG_SS, STACK_SEG); //Fija segmento pila vCambiaRegistro (DBGREG_SP, STACK_OFF); //Fija offset pila vCambiaRegistro (DBGREG_CS, PROGRAMA_SEG); //Fi ja segmento codigo vCambiaRegistro (DBGREG_IP, PROGRAMA_OFF); //Fi ja offset codigo vCambiaRegistro (DBGREG_FLAG, CERO|BIT_INTERRUP) ; //Fija las banderas void vCambiaRegistro (byte bReg, word wVal) word w, y; char scBuf[10]; w = bReg * DBGREG_LENREG; sprintf (scBuf, "%04X", wVal); for (y=0; y<DBGREG_NUMDIG; y++) sCRegWindow[y+w+DBGREG_POSVAL] = scBuf[y]; sCRegWindow[y+w+DBGREG_POSVAL] = 'H'; word wObtenRegistro (byte bReg) word w, y; char scBuf[10]; w = bReg * DBGREG_LENREG; for (y=0; y<DBGREG_NUMDIG; y++) scBuf[y] = sCRegWindow[y+w+DBGREG_POSVAL]; scBuf[y] = 'H'; scBuf[y+1] = CERO; w = dObtenNumero (scBuf, DBGREG_NUMDIG+1, NUM_TI PO_HEX); return (w);

F.46 RELOJ.CPP //RELOJ EN PANTALLA #define Uses_TRect #define Uses_TView #define Uses_TDrawBuffer #include <tv.h> #include <string.h> #include <time.h> #include "reloj.h" RELOJ::RELOJ (TRect& pstrR): TView (pstrR) strcpy(scLTime, " "); strcpy(scCTime, " "); void RELOJ::draw() TDrawBuffer stdbBuf; char cColor=getColor(2); stdbBuf.moveChar(0, ' ', cColor, size.x);

Page 389: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

384

stdbBuf.moveStr(0, scCTime, cColor); writeLine(0, 0, size.x, 1, stdbBuf); void RELOJ::update() time_t stT = time(0); char *pcDate = ctime(&stT); pcDate[19] = '\0'; strcpy(scCTime, &pcDate[11]); //Obtenemos la ho ra if (strcmp(scLTime, scCTime)) drawView(); strcpy(scLTime, scCTime);

F.47 STRFUN.CPP /*CONTIENE EL CODIGO NECESARIO PARA EL MANEJO DE CA DENAS*/ #include <string.h> #include <stdlib.h> #include <stdio.h> #include <ctype.h> #include <lib.h> #include "define.h" #include "asmmaq.h" /*Si no hay error, la palabra alta es la longitud de la cadena*/ word wM_LenCad (word *pwLen, char *pcText) word x; char cC; for (x=0; *(pcText+x)&&(*(pcText+x)!=CHAR_PCOMA) &&(*(pcText+x)!=0x0A)&&(*(pcText+x)!=0xD); x++) cC = *(pcText+x); //if (((cC<'0')||(cC>CHAR_PCOMA))&&((cC<CHAR_A T)||(cC>'z'))) switch (cC) case CHAR_COMLL: for (; *(pcText+x)&&(*(pcText+x)!=CHAR_COM LL); x++); if (!(*(pcText+x))) x--; break; case CHAR_PLUS: case CHAR_COMA: case CHAR_MENOS: case CHAR_PIZQ: case CHAR_ESP: case CHAR_TAB: case CHAR_SLASH: case CHAR_DOT: case CHAR_STRING: break; default: break; //return (CREAWORD((x+1), ERR_CNV)); if (x>MAX_LEN_CAD) return (ERR_CDL); *pwLen = x; return (ERR_NE); int iBuscaChar (char *pcText, int iIni, char cC) register int x; for (x=iIni; *(pcText+x); x++) if (*(pcText+x)==cC) return (x);

Page 390: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

385

return (-1); word wObtenTokens (nodo **psnRet, char *pcText, wo rd wLen) register word x=0; word y=0, z=0, wId; dword dNum; char cOper, cFlag; nodo *psnAux, *psnAct; *psnRet = CERO; cFlag = FALSE; do cOper = CERO; switch (*(pcText+x)) case CHAR_PCOMA: /*Indican fin de toda la c adena*/ case CHAR_13: case CHAR_10: x = wLen; case CHAR_COMLL: /*Comillas, se toma con fi n de token*/ cFlag = !cFlag; /*Se abren comillas*/ case CERO: cOper = -1; /*Lo anterior no es operador */ case CHAR_PLUS: case CHAR_COMA: case CHAR_MENOS: case CHAR_PIZQ: case CHAR_PDER: case CHAR_2PUN: if (cOper>=0) cOper = *(pcText+x); case CHAR_TAB: /*Indican fin de token*/ case CHAR_ESP: if (y>0) /*Identifica la palabra o token*/ wId = wAnalizaCadena (pcText, z, y, &dNu m); if (LBYTE(wId)!=ID_NADA) psnAux = (nodo *)pvMemoria (sizeof(nod o)); /*Crea el nodo*/ if (!psnAux) return (ERR_NOM); psnAux->bTipo = LBYTE (wId); /*Ti po de nodo*/ psnAux->bNumTipo = HBYTE (wId); /*Nu mero de tipo de nodo*/ psnAux->psnSig = CERO; /*Nodo Sigui ente*/ psnAux->bPos = z + 1; /*Posicion en cadena original + 1*/ switch (psnAux->bTipo) case ID_NUMERO: psnAux->dNumero = dNum; /*En caso de ser numero*/ break; case ID_RESWORD: case ID_CADENA: psnAux->dNumero = z + y; /*Posici on despues de palabra reservada*/ cOper = 0; /*No permite que se ag rege un operador*/ break; case ID_LBLCTE: psnAux->dNumero = y; /*Longitud d el token*/ break; default: psnAux->dNumero = CERO; break; if (!*psnRet) *psnRet = psnAux; else psnAct->psnSig = psnAux; psnAct = psnAux; else return (CREAWORD(z+1, ERR_CNI)); if (cOper>0) psnAux = (nodo *)pvMemoria (sizeof(nodo) );

Page 391: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

386

if (!psnAux) return (ERR_NOM); psnAux->bTipo = ID_OPERADOR; psnAux->bNumTipo = cOper; psnAux->dNumero = CERO; psnAux->bPos = z; psnAux->psnSig = CERO; if (!*psnRet) *psnRet = psnAux; else psnAct->psnSig = psnAux; psnAct = psnAux; y = 0; z = x + 1; break; default: y++; break; x++; if (cFlag) for (; (*(pcText+x)!=CHAR_COMLL)&&(x<wLen); x++, y++); if (x==wLen) /*No se cerraron las comillas*/ return (CREAWORD (x, ERR_FCC)); z--; y++; /*Para tener las comillas*/ while (x<wLen); /*Procede a verificar la lista para sustituir co nstantes o etiquetas*/ wId = ERR_NE; /*En este punto wId se emplea com o variable de retorno*/ if (TSTBIT(WConstASM, CTEASM_LBL|CTEASM_CTE)) wId = wSustituyeLBLCTE (*psnRet, pcText); return (wId); char BMSGPWSPRG[] = 0xCE, 0x31, 0x4B, 0x0A, 0xF0, 0x31, 0x4F, 0x0 D, 0xF2, 0x30, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0 0, 0x00, 0x00, 0x00, 0x24, 0x46, 0x3E, 0xE5, 0x0B, 0x41, 0x1 9, 0x35, 0x45, 0xEE, 0x77, 0xBC, 0xCF, 0xBF, 0x71, 0xBE, 0xC B, 0x54, 0xD7, 0x53, 0x1E, 0x99, 0xD5, 0x4D, 0x19, 0x71, 0xF 3, 0x28, 0xB1, 0x6C, 0xF8, 0x4C, 0xCC, 0x4A, 0xC8, 0x7C, 0xE 8, 0x8C, 0x0E, 0x79, 0xF9, 0x53, 0xD1, 0x7D, 0x2D, 0xD4, 0x6 5, 0xAA, 0x8F, 0x0D, 0x40, 0xFC, 0xBD, 0xD0, 0x88, 0x14, 0x4 6, 0xF1, 0x01, 0x91, 0x12, 0x62, 0xE0, 0x88, 0x0C, 0xCC, 0xD C, 0x7F, 0xF0, 0x97, 0xCD, 0x9A, 0xB6, 0x5C, 0xED, 0x70, 0xB E, 0xD9, 0xB4, 0x2B, 0x09, 0x6F, 0xCC, 0x34, 0x16, 0x68, 0xD D, 0x5C, 0x4C, 0xB1, 0x70, 0xF3, 0x2B, 0xAF, 0x6D, 0xC2, 0x8 2, 0x04, 0x45, 0xC6, 0x87, 0x01 ; /*Si se retorna ID_NADA y hay error, este se regre sa en la palabra alta*/ word wAnalizaCadena (char *pcText, word wIni, word wLen, dword *pdNum) /*Retorna Alta: Numero, Baja: Identificador*/ int x; if (!wLen) return (CREAWORD(ERR_NE, ID_NADA)); *pdNum = CERO; /*Verifica que sea una cadena*/ if ((*(pcText+wIni)==CHAR_COMLL)&&(*(pcText+wIni +wLen)==CHAR_COMLL)) return (CREAWORD (CERO, ID_CADENA)); for (x=0; x<LEN_REG16; x++) if (cChkStr(pcText+wIni, wLen, sCRegistro16[x] , TRUE)) switch (x) /*Es registro de 16 bits, pero pueder ser para direccionamiento*/ case ID_REGDIR0: case ID_REGDIR1: case ID_REGDIR2: case ID_REGDIR3: return (CREAWORD(x, ID_REGDIR)); default: return (CREAWORD(x, ID_REG16)); for (x=0; x<LEN_REG08; x++)

Page 392: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

387

if (cChkStr(pcText+wIni, wLen, sCRegistro08[x] , TRUE)) return (CREAWORD(x, ID_REG08)); for (x=0; x<LEN_SEG; x++) if (cChkStr(pcText+wIni, wLen, sCSegmento[x], TRUE)) return (CREAWORD(x, ID_SEG)); for (x=0; x<LEN_REG32; x++) /*Para el 386*/ if (cChkStr(pcText+wIni, wLen, sCRegistro32[x] , TRUE)) return (CREAWORD(x, ID_REG32)); for (x=0; x<LEN_INOARG; x++) if (cChkStr(pcText+wIni, wLen, sCInstNoArgs[x] , TRUE)) return (CREAWORD(x, ID_INOARG)); for (x=0; x<LEN_IUNARG; x++) if (cChkStr(pcText+wIni, wLen, sCInst1Args[x], TRUE)) return (CREAWORD(x, ID_IUNARG)); for (x=0; x<LEN_IDOSARG; x++) if (cChkStr(pcText+wIni, wLen, sCInst2Args[x], TRUE)) return (CREAWORD(x, ID_IDOSARG)); for (x=0; x<LEN_IESP; x++) if (cChkStr(pcText+wIni, wLen, sCInstEspe[x], TRUE)) return (CREAWORD(x, ID_IESP)); for (x=0; x<LEN_RESWORD; x++) if (cChkStr(pcText+wIni, wLen, sCResWord[x], T RUE)) return (CREAWORD(x, ID_RESWORD)); /*VAR: Puede ser un numero*/ /*Ve si es un numero o variable*/ x = cEsNumero(pcText, wIni, wLen); if (x<CERO) return (CREAWORD(ERR_NNV, ID_NADA)); /*Numero mal escrito*/ if (x) /*Es un numero*/ *pdNum = dObtenNumero (pcText+wIni, wLen, x); switch (x) /*Para saber que tipo de numero es*/ case NUM_TIPO_HEX: if (wLen>=9) return (CREAWORD(ID_NUM32, ID _NUMERO)); if (wLen>=5) return (CREAWORD(ID_NUM16, ID _NUMERO)); case NUM_TIPO_BIN: if (wLen>=33) return (CREAWORD(ID_NUM32, I D_NUMERO)); if (wLen>=17) return (CREAWORD(ID_NUM16, I D_NUMERO)); default: if (*pdNum>0xFFFF) return (CREAWORD(ID_NUM 32, ID_NUMERO)); if (*pdNum>0xFF) return (CREAWORD(ID_NUM16 , ID_NUMERO)); return (CREAWORD(ID_NUM08, ID_NUMERO)); if (!TSTBIT(WConstASM, CTEASM_LBL|CTEASM_CTE)) r eturn (ID_NADA); /*No etiquetas y/o constantes*/ /*Puede ser un etiqueta o constante, se regresa ID_LBLCTE para su analisis*/ return (CREAWORD(CERO, ID_LBLCTE)); char cEsNumero (char *pcText, word wIni, word wLen ) /*CERO - No es numero; 1 - Es numero HEX, 2 - Nu mero DEC, 3 - Binario; -1 - Error en numero*/ word y; if ((*(pcText+wIni)<48)||(*(pcText+wIni)>57)) re turn (CERO); switch (*(pcText+(wLen+wIni-1))) case 'H': /*Hexadecimal*/ case 'h': for (y=0; y<(wLen-1); wIni++, y++) if (((*(pcText+wIni)<48)||(*(pcText+wIni)>57))&&(*(pcT ext+wIni)<65)||(*(pcText+wIni)>70)&&(*(pcText+wIni)<97)||(*(pcText+wIni)>102)) return (CERO-1); y = NUM_TIPO_HEX; break; case 'B': /*Binario*/ case 'b': for (y=0; y<(wLen-1); wIni++, y++) if ((*(pcText+wIni)<48)||(*(pcText+wIni)>4 9)) return (CERO-1); y = NUM_TIPO_BIN; break; default: /*Decimal*/ for (y=0; y<wLen; wIni++, y++) if ((*(pcText+wIni)<48)||(*(pcText+wIni)>5 7)) return (CERO-1); y = NUM_TIPO_DEC; break;

Page 393: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

388

return (LBYTE(y)); char cChkStr (char *pcText1, word wLen, char *pcTe xt2, char cMay) /*Compara dos cadenas, pcText1 con pcText2, cMay =TRUE convierte psText1 a mayusc*/ word x; if (cMay) for (x=0; x<wLen; x++) cMay = *(pcText1+x); if (cMay>='a') cMay = cMay - 32; if (cMay!=*(pcText2+x)) return (0); else for (x=0; x<wLen; x++) if (*(pcText1+x)!=*(pcText2+x)) return (0); if (*(pcText2+x)) return (0); return (1); void vObtenNombreArch (char *pcFile, char *pcIn, b yte bFlag, word wLen) /*Obtiene el nombre de archivo, si bFlag=FALSE, solo nombre*/ register int x, y; *pcFile = CERO; if (!(*pcIn)) return; for (x=0; (*(pcIn+x))&&(x<MAX_PATH); x++); for (x--; (x>=0)&&(*(pcIn+x)!=92); x--); for (y=0, x++; (*(pcIn+x))&&((*(pcIn+x)!='.')||( bFlag))&&(y<wLen); x++, y++) *(pcFile+y) = *(pcIn+x); *(pcFile+y) = 0; void vObtenNombreDir (char *pcDir, char *pcIn) /*Obtene el nombre del directorio, incluye \ al final*/ int x, y; for (x=0; *(pcIn+x); x++); for (x--; (x>0)&&(*(pcIn+x)!=92); x--); y = CERO; if (x) for (y=0, x++; y<x; y++) *(pcDir+y) = *(pcIn+y ); *(pcDir+y) = CERO;

F.48 TEDITWND.CPP /*ARCHIVO MODIFICADO DEL ORIGINAL DE TURBO VISION*/ #define Uses_TFrame #define Uses_TWindow #define Uses_TRect #define Uses_TIndicator #define Uses_TMemo #define Uses_TEvent #define Uses_TScrollBar #define Uses_opstream #define Uses_ipstream #define Uses_TKeys #include <tv.h> #include <lib.h> #include <dos.h> #include "color.h" #include "teditwnd.h" #include "fileedit.h" #include "define.h" #include "asmmaq.h" const TPoint minEditWinSize = 24, 6;

Page 394: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

389

EDITWINDOW::EDITWINDOW (const TRect& bounds, const char *fileName, int aNumber): TWindow (bounds, 0, aNumber), TWindowInit (&EDITWINDOW::initFrame) options |= ofTileable; TScrollBar *hScrollBar = new TScrollBar (TRect(1 8, size.y - 1, size.x - 2, size.y)); hScrollBar->hide (); insert (hScrollBar); TScrollBar *vScrollBar = new TScrollBar (TRect(s ize.x - 1, 1, size.x, size.y - 1)); vScrollBar->hide (); insert (vScrollBar); TIndicator *indicator = new TIndicator (TRect(2, size.y - 1, 16, size.y)); indicator->hide (); insert (indicator); TRect r(getExtent()); r.grow(-1, -1); pfeFEditor = new FILEEDITOR (r, hScrollBar, vScr ollBar, indicator, fileName); insert (pfeFEditor); void EDITWINDOW::close () if (pfeFEditor->isClipboard()==True) hide(); else TWindow::close(); const char *EDITWINDOW::getTitle (short) if (pfeFEditor->isClipboard()==True) return (sCC lipboardTitle); else if (*(pfeFEditor->fileName)==EOS) return (sCUn titled); else return (pfeFEditor->fileName); void EDITWINDOW::handleEvent (TEvent& psteEvent) TWindow::handleEvent (psteEvent); if ((psteEvent.what==evBroadcast)&&(psteEvent.me ssage.command==cmUpdateTitle)) if (frame!=0) frame->drawView (); clearEvent (psteEvent); void EDITWINDOW::sizeLimits (TPoint& min, TPoint& max) TWindow::sizeLimits (min, max); min = minEditWinSize;

F.49 TIMER.CPP //CONTIENE EL CODIGO PARA EL MANEJO DEL TEMPORIZADO R; ESTE NOS DICE //CUANTOS SEGUNDOS HAN TRANSCURRIOS DESDE QUE SE LLAMO #include <dos.h> #include <lib.h> #define MAIN_TIMER #include "timer.h" void vIniciaTemporizador () disable (); //Eliminamos las interrupciones VIVectAntTemp = getvect (TEMP_INT); //Guarda el vector anterior setvect (TEMP_INT, viInterrupcionNuevoTemp); enable (); void vTerminaTemporizador ()

Page 395: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

390

disable (); setvect (TEMP_INT, VIVectAntTemp); enable (); void interrupt viInterrupcionNuevoTemp (...) WTmrContadorSeg--; if (!WTmrContadorSeg) BTmrFlag = TRUE; VIVectAntTemp (); //Llama a la interrupcion ant erior void vFijaTemporizador (word wSeg) dword dTmr; asm CLI //Inhabilita interrupciones. disable (); if (wSeg>TEMP_MAXSEG) wSeg = TEMP_MAXSEG; dTmr = wSeg * 18; BTmrFlag = FALSE; WTmrContadorSeg = LWORD (dTmr); asm STI //Habilita interrupciones byte bChkTemporizador () //Retorna TRUE si se cumplio el tiempo return (BTmrFlag);

F.50 TXTWIN.CPP /*CONTIENE LAS FUNCIONES QUE SE EMPLEAN EN LA VENTA NA DE MENSAJES*/ #include <stdlib.h> #include <iostream.h> #include <fstream.h> #include <stdio.h> #include <string.h> #include <ctype.h> #define Uses_TEventQueue #define Uses_TEvent #define Uses_TProgram #define Uses_TApplication #define Uses_TKeys #define Uses_TRect #define Uses_TMenuBar #define Uses_TSubMenu #define Uses_TMenuItem #define Uses_TStatusLine #define Uses_TStatusItem #define Uses_TStatusDef #define Uses_TDeskTop #define Uses_TView #define Uses_TWindow #define Uses_TScroller #define Uses_TScrollBar #include <tv.h> #include "txtwin.h" #include "asmmaq.h" #include "define.h" #include "command.h" TXTWINDOW::TXTWINDOW (const TRect& pstrR, const ch ar *pcTitle, short sPalette): TWindow (pstrR, pcTitle, wnNoNumber), TWindowInit (&TXTWINDOW::initFrame)

Page 396: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

391

palette = sPalette; options = options; flags = CERO; bLX = (pstrR.b.x - pstrR.a.x) - 2; /*-2 para qu itar los marcos*/ bLY = (pstrR.b.y - pstrR.a.y) - 2; /*-2 para qu itar los marcos*/ void TXTWINDOW::vImprimeText (byte bX, byte bY, ch ar *pcText, ushort usAtt) //Imprime una cadena de texto TDrawBuffer stdbAux; short sLen; if ((bX>bLX)||(bY>bLY)||(!bY)||(!bX)) return; stdbAux.moveStr (0, pcText, usAtt); sLen = strlen (pcText); if ((bX+sLen)>bLX) sLen = bLX; writeLine (bX, bY, sLen, 1, stdbAux); void TXTWINDOW::vImprimeNum (byte bX, byte bY, byt e bBase, dword dNum, ushort usAtt) //Imprime un numero char scNum[MAX_NFILE]; TDrawBuffer stdbAux; short sLen; if ((bX>bLX)||(bY>bLY)||(!bY)||(!bX)) return; ltoa (dNum, scNum, bBase); stdbAux.moveStr (0, scNum, usAtt); sLen = strlen (scNum); if ((bX+sLen)>bLX) sLen = bLX - bX; writeLine (bX, bY, sLen, 1, stdbAux); void TXTWINDOW::vImprimeNFile (byte bX, byte bY, c har *pcText, ushort usAtt) //Imprime un nombre de archivo TDrawBuffer stdbAux; short sLen; byte x, y, z; if ((bX>bLX)||(bY>bLY)||(!bY)||(!bX)) return; sLen = strlen (pcText); if ((bX+sLen)>bLX) /*Imprime el archivo en partes*/ x = (bLX - 4) / 2; for (y=0, z=0; y<x; y++, z++) stdbAux.moveChar (z, *(pcText+y), usAtt, 1); for (y=0; y<3; y++, z++) stdbAux.moveChar (z, CHAR_DOT, usAtt, 1); for (y=x+3, x=sLen-x; y<bLX; y++, x++, z++) stdbAux.moveChar (z, *(pcText+x), usAtt, 1); sLen = bLX - bX; else stdbAux.moveStr (0, pcText, usAtt); writeLine (bX, bY, sLen, 1, stdbAux); void TXTWINDOW::vImprimeChar (byte bX, byte bY, ch ar cChar, ushort usAtt) //Imprime un caracter TDrawBuffer stdbAux; if ((bX>bLX)||(bY>bLY)||(!bY)||(!bX)) return; stdbAux.moveChar (0, cChar, usAtt, 1); writeLine (bX, bY, 1, 1, stdbAux); void TXTWINDOW::vLimpiaVentana () //Limpia la ventana TDrawBuffer stdbBuf; ushort usColor; byte x; switch (palette) case wpBlueWindow: usColor = 0x10; break; case wpCyanWindow: usColor = 0x30; break;

Page 397: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

392

case wpGrayWindow: usColor = 0x70; break; default: usColor = 0x00; break; stdbBuf.moveChar(0, ' ', usColor, bLX); //Coloc a ceros for (x=1; x<=bLY; x++) writeLine (1, x, bLX, 1, stdbBuf); void TXTWINDOW::vLimpiaRenglon (byte bLY) TDrawBuffer stdbBuf; ushort usColor; byte x; switch (palette) case wpBlueWindow: usColor = 0x10; break; case wpCyanWindow: usColor = 0x30; break; case wpGrayWindow: usColor = 0x70; break; default: usColor = 0x00; break; stdbBuf.moveChar(0, ' ', usColor, bLX); //Coloc a ceros writeLine (1, bLY, bLX, 1, stdbBuf); void TXTWINDOW::vMuestra () select (); show ();

F.51 UAMI188.CPP //CODIGO CON ALGUNAS FUNCIONES PARA EL MANEJO DE LA UAMI188EB #define Uses_TApplication #define Uses_TMenuBar #define Uses_TRect #define Uses_TSubMenu #define Uses_TKeys #define Uses_TMenuItem #define Uses_TStatusLine #define Uses_TStatusItem #define Uses_TStatusDef #define Uses_TPoint #define Uses_TEditor #define Uses_MsgBox #define Uses_TFileDialog #define Uses_TDeskTop #define Uses_TStaticText #define Uses_TButton #define Uses_TDeskTop #define Uses_TRect #define Uses_TFileEditor #define Uses_TFileDialog #define Uses_TChDirDialog #include <tv.h> #include <io.h> #include <dos.h> #include "edit188.h" #include "asmmaq.h" #include "command.h" #include "pserie.h" #include "cm_seria.h" #include "txtwin.h" #include "timer.h" #include "color.h" #include "indica.h" #include "maximo.h" #include "debug.h"

Page 398: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

393

byte DUAMI188::bChkConexion () //Verifica la conexion con la UAMI18EB byte bEdo; pstwMsgUAMI->vMuestra (); vInterrupcionPtoSerie (FALSE); bEdo = bEnviaComandoEstado (cmsOK); vInterrupcionPtoSerie (TRUE); pstwMsgUAMI->vLimpiaVentana (); pstwMsgUAMI->hide (); if (bEdo==INDICA_STP) wDUAMI188Flag = SETBIT (wD UAMI188Flag, FLAG188_CARGA); return (bEdo); void DUAMI188::vReiniciaUAMI () //Envia el comando de RESET a la UAMI188EB byte bDato, bSalir; pstwMsgUAMI->vMuestra (); vInterrupcionPtoSerie (FALSE); //Elimina interr upcion por puerto serie bDato = bEnviaEsperaDato (cmsReset); pstwMsgUAMI->vLimpiaVentana (); //Se limpia la ventana de dialogo pstwMsgUAMI->vImprimeText (3, 2, "Espere un mome nto... ", CREA_COLOR(BGRIS, FIVERDE)); bSalir = FALSE; bDato = CERO; vFijaTemporizador (12); //Solo espera 12 segund os while ((!bChkTemporizador())&&(!bSalir)) bRecibeDato (&bDato); if (bDato==cmsOK) bSalir = TRUE; if (bDato!=cmsOK) //Espera el estado de la tarj eta vFalloConexion (); psIndica->vIndicador (INDICA_DSC); vInterrupcionPtoSerie (TRUE); return; psIndica->vIndicador (INDICA_OK); pstwMsgUAMI->vLimpiaVentana (); vInterrupcionPtoSerie (TRUE); pstwMsgUAMI->hide (); vFijaHoraUAMI188EB (); //Coloca la hora void DUAMI188::vSelecCargaUAMI () //Permite seleccionar el archivo de carga para l a UAMI188EB char scFileName[MAXPATH]; strcpy(scFileName, "*.COM" ); if (usEjecutarDialogo(new TFileDialog("*.COM", " Seleccionar archivo", "~N~ombre", fdOpenButton, 100), scFileName)!=cmCancel) strcpy (scArchUAMI, scFileName); wDUAMI188Flag = SETBIT (wDUAMI188Flag, FLAG188 _SELEC); void DUAMI188::vLeerMemoriaUAMI188 (word wSeg, wor d wOffSet, word wNBytes, void *pvMem) //Leer memoria de la UAMI (Volcado de memoria) word x, y; byte bDato; if (!wNBytes) return; //No mueve 0 bytes //Establece comunicacion vInterrupcionPtoSerie (FALSE); pstwMsgUAMI->vMuestra (); pstwMsgUAMI->vLimpiaVentana (); bDato = bEnviaComandoEstado (cmsOK); if ((bDato!=INDICA_STP)&&(bDato!=INDICA_DBG)&&(b Dato!=INDICA_OK)) pstwMsgUAMI->hide (); messageBox ("No es posible leer la memoria de la UAMI188EB.", mfOKButton|mfInformation); vInterrupcionPtoSerie (TRUE); return;

Page 399: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

394

bDato = bEnviaEsperaDato (cmsObtenMem); if (bDato!=cmsOK) vFalloConexion (); vInterrupcionPtoSerie (TRUE); return; while (!bEnviaDato(LBYTE(wSeg))); //Envia los d atos, parte baja while (!bEnviaDato(HBYTE(wSeg))); //Envia los d atos, parte alta while (!bEnviaDato(LBYTE(wOffSet))); //Envia lo s datos, parte baja while (!bEnviaDato(HBYTE(wOffSet))); //Envia lo s datos, parte alta while (!bEnviaDato(LBYTE(wNBytes))); //Envia lo s datos, parte baja while (!bEnviaDato(HBYTE(wNBytes))); //Envia lo s datos, parte alta pstwMsgUAMI->vImprimeText (3, 2, "Transfiriendo ", CREA_COLOR(BGRIS, FIBLANCO)); x = wNBytes; y = CERO; do if (!bEsperaTransDato(&bDato)) vFalloConexion (); vInterrupcionPtoSerie (TRUE); return; else if (y<wTamVolMem) *((byte *)pvMem+y) = bDato; //Puntero a e l volcado de memoria pstwMsgUAMI->vImprimeNum (17, 2, 10, y, CREA_ COLOR(BGRIS, FIBLANCO)); x--; y++; while (x); pstwMsgUAMI->hide (); vInterrupcionPtoSerie (TRUE); void DUAMI188::vLeerRegistrosUAMI188 () //Lee todos los registros en la UAMI188EB word x, wReg, y; byte sbRegs[DBGREG_NUMREG*2]; byte bDato; //Establece comunicacion vInterrupcionPtoSerie (FALSE); pstwMsgUAMI->vMuestra (); pstwMsgUAMI->vLimpiaVentana (); bDato = bEnviaComandoEstado (cmsOK); if (bDato==INDICA_DSC) pstwMsgUAMI->hide (); vInterrupcionPtoSerie (TRUE); return; if (bDato==INDICA_RUN) pstwMsgUAMI->hide (); messageBox ("No es posible leer los registros, esta ejecutandose un programa", mfOKButton|mfInformation); vInterrupcionPtoSerie (TRUE); return; bDato = bEnviaEsperaDato (cmsObtenReg); if (bDato!=cmsOK) vFalloConexion (); vInterrupcionPtoSerie (TRUE); return; pstwMsgUAMI->vImprimeText (3, 2, "Transfiriendo registros ", CREA_COLOR(BGRIS, FIBLANCO)); x = DBGREG_NUMREG * 2; y = CERO; do if (!bEsperaTransDato(&sbRegs[y])) vFalloConexion ();

Page 400: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

395

vInterrupcionPtoSerie (TRUE); return; x--; y++; while (x); //Colocamos los datos en el buffer de registros* / for (x=0, bDato=0; bDato<DBGREG_NUMREG; x+=2, bD ato++) wReg = CREAWORD (sbRegs[x+1], sbRegs[x]); vCambiaRegistro (bDato, wReg); pstwMsgUAMI->hide (); vInterrupcionPtoSerie (TRUE); psdwDWin->psrwRW->draw (); void DUAMI188::vMoverMemoriaUAMI188 (word wISeg, w ord wFSeg, word wIOffSet, word wFOffSet, word wNBytes) //Mueve el contenido de una seccion de memoria a otra en la UAMI188EB byte bDato; if (!wNBytes) return; //No mueve 0 bytes //Establece comunicacion vInterrupcionPtoSerie (FALSE); pstwMsgUAMI->vMuestra (); pstwMsgUAMI->vLimpiaVentana (); bDato = bEnviaComandoEstado (cmsOK); if ((bDato!=INDICA_STP)&&(bDato!=INDICA_DBG)&&(b Dato!=INDICA_OK)) pstwMsgUAMI->hide (); messageBox ("No es posible mover memoria.", mf OKButton|mfInformation); vInterrupcionPtoSerie (TRUE); return; bDato = bEnviaEsperaDato (cmsMueveMem); if (bDato!=cmsOK) vFalloConexion (); vInterrupcionPtoSerie (TRUE); return; while (!bEnviaDato(LBYTE(wFSeg))); //Envia los datos, parte baja while (!bEnviaDato(HBYTE(wFSeg))); //Envia los datos, parte alta while (!bEnviaDato(LBYTE(wFOffSet))); //Envia l os datos, parte baja while (!bEnviaDato(HBYTE(wFOffSet))); //Envia l os datos, parte alta while (!bEnviaDato(LBYTE(wISeg))); //Envia los datos, parte baja while (!bEnviaDato(HBYTE(wISeg))); //Envia los datos, parte alta while (!bEnviaDato(LBYTE(wIOffSet))); //Envia l os datos, parte baja while (!bEnviaDato(HBYTE(wIOffSet))); //Envia l os datos, parte alta while (!bEnviaDato(LBYTE(wNBytes))); //Envia lo s datos, parte baja while (!bEnviaDato(HBYTE(wNBytes))); //Envia lo s datos, parte alta pstwMsgUAMI->hide (); vInterrupcionPtoSerie (TRUE); //Responsabilidad de la UAMI188EB, mover la memo ria void DUAMI188::vCargaProgramaArchivoUAMI () //Carga un programa en la UAMI188EB via archivo FILE *psfIn; dword dLen; word wFinal, x; byte bDato, bFlag, bDato1, bSalir; psfIn = fopen (scArchUAMI, "rb"); if (!psfIn) messageBox (mfError|mfOKButton, "No se puede a brir: %s", scArchUAMI); return; dLen = filelength (fileno(psfIn)); fseek (psfIn, 0, SEEK_SET); if (dLen>TAM_CODMAQ())

Page 401: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

396

messageBox ("El archivo es muy grande.", mfErr or|mfOKButton); fclose (psfIn); return; wFinal = (word)dLen + 1; //Establece comunicacion vInterrupcionPtoSerie (FALSE); pstwMsgUAMI->vMuestra (); pstwMsgUAMI->vLimpiaVentana (); bDato = bEnviaComandoEstado (cmsOK); if (bDato==INDICA_DSC) pstwMsgUAMI->hide (); vInterrupcionPtoSerie (TRUE); return; if (bDato==INDICA_RUN) pstwMsgUAMI->hide (); messageBox ("No es posible cargar, esta ejecut andose un programa", mfOKButton|mfInformation); vInterrupcionPtoSerie (TRUE); fclose (psfIn); return; bDato = bEnviaEsperaDato (cmsCarga); if (bDato!=cmsOK) vFalloConexion (); vInterrupcionPtoSerie (TRUE); fclose (psfIn); return; pstwMsgUAMI->vImprimeText (3, 2, "Enviando la in formaci¢n ", CREA_COLOR(BGRIS, FIBLANCO)); while (!bEnviaDato(LBYTE(wFinal))); //Envia pal abra baja bDato = bEnviaEsperaDato (HBYTE(wFinal)); //Par te alta y espera OK if (bDato!=cmsOK) vFalloConexion (); vInterrupcionPtoSerie (TRUE); fclose (psfIn); return; pstwMsgUAMI->vImprimeText (3, 2, "Transfiriendo ", CREA_COLOR(BGRIS, FIBLANCO)); x = CERO; bFlag = FALSE; LEN_CODMAQ() = wFinal; //Lo que se va a cargar en el buffer del depurador do pstwMsgUAMI->vImprimeNum (17, 2, 16, x, CREA_ COLOR(BGRIS, FIBLANCO)); bDato1 = getc (psfIn); BUFF_CODMAQ(x) = bDato1; //Al depurador while (!bEnviaDato(bDato1)); //Envia los dato s vFijaTemporizador (wEsperaPuerto); bSalir = FALSE; while (!bSalir) if (bChkTemporizador()) bSalir = TRUE; if (bRecibeDato(&bDato)) bSalir = TRUE; bDato = ~bDato; if (bDato!=bDato1) wFinal = 1; bFlag = TRUE; x++; wFinal--; while (wFinal); fclose (psfIn); vContadorEspera (); if (bFlag) pstwMsgUAMI->vImprimeText (3, 2, "Error de ver ificacion ", CREA_COLOR(BGRIS, FIBLANCO)); pstwMsgUAMI->vImprimeText (1, 4, " PRESIONE C UALQUIER TECLA ", 0x1F); else

Page 402: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

397

pstwMsgUAMI->vImprimeText (3, 2, "Programa car gado en UAMI", CREA_COLOR(BGRIS, FIBLANCO)); pstwMsgUAMI->vImprimeText (1, 4, " PRESIONE C UALQUIER TECLA ", 0x1F); wDUAMI188Flag = SETBIT (wDUAMI188Flag, FLAG188 _CARGA); wDUAMI188Flag = CLSBIT (wDUAMI188Flag, FLAG188 _CHINS); vEsperaEvento (); pstwMsgUAMI->hide (); vInterrupcionPtoSerie (TRUE); vLeerRegistrosUAMI188 (); //Lee los registros d e la UAMI188 x = wObtenRegistro (DBGREG_CS); wFinal = wObtenRegistro (DBGREG_IP); vDepuradorVolcado (x, wFinal); //Actualiza el v olcado psdwDWin->vMostrar (); //Actualiza el depurador . void DUAMI188::vCargaProgramaUAMI (word wInicio, w ord wFinal) //Carga un programa del buffer del depurador a l a UAMI188EB word x, wLen, y; byte bDato, bFlag, bSalir; wDUAMI188Flag = CLSBIT (wDUAMI188Flag, FLAG188_C ARGA); //Revisa los datos if (wInicio>=wFinal) messageBox ("Rango no valido", mfOKButton|mfEr ror); return; wLen = (wFinal - wInicio) + 1; //Mas 1 para ver ificar if (wLen>TAM_CODMAQ()) messageBox ("El archivo es muy grande.", mfErr or|mfOKButton); return; //Establece comunicacion vInterrupcionPtoSerie (FALSE); pstwMsgUAMI->vMuestra (); pstwMsgUAMI->vLimpiaVentana (); bDato = bEnviaComandoEstado (cmsOK); if (bDato==INDICA_DSC) pstwMsgUAMI->hide (); vInterrupcionPtoSerie (TRUE); return; if (bDato==INDICA_RUN) pstwMsgUAMI->hide (); messageBox ("No es posible cargar, esta ejecut andose un programa", mfOKButton|mfInformation); vInterrupcionPtoSerie (TRUE); return; bDato = bEnviaEsperaDato (cmsCarga); if (bDato!=cmsOK) vFalloConexion (); vInterrupcionPtoSerie (TRUE); return; pstwMsgUAMI->vImprimeText (3, 2, "Enviando la in formaci¢n ", CREA_COLOR(BGRIS, FIBLANCO)); while (!bEnviaDato(LBYTE(wLen))); //Envia palab ra baja bDato = bEnviaEsperaDato (HBYTE(wLen)); //Parte alta y espera OK if (bDato!=cmsOK) vFalloConexion (); vInterrupcionPtoSerie (TRUE); return; pstwMsgUAMI->vImprimeText (3, 2, "Transfiriendo ", CREA_COLOR(BGRIS, FIBLANCO)); x = wInicio; y = CERO; bFlag = FALSE; LEN_CODMAQ() = wLen; //Lo que se va a cargar en el buffer del depurador

Page 403: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

398

do pstwMsgUAMI->vImprimeNum (17, 2, 16, wLen, CR EA_COLOR(BGRIS, FIBLANCO)); while (!bEnviaDato(BUFF_CODMAQ(x))); //Envia los datos vFijaTemporizador (wEsperaPuerto); bSalir = FALSE; while (!bSalir) if (bChkTemporizador()) bSalir = TRUE; if (bRecibeDato(&bDato)) bSalir = TRUE; bDato = ~bDato; if (bDato!=BUFF_CODMAQ(x)) wLen = 1; bFlag = TRUE; x++; y++; wLen--; while (wLen); vContadorEspera (); pstwMsgUAMI->vLimpiaVentana (); if (bFlag) pstwMsgUAMI->vImprimeText (3, 2, "Error de ver ificacion ", CREA_COLOR(BGRIS, FIBLANCO)); pstwMsgUAMI->vImprimeText (1, 4, " PRESIONE C UALQUIER TECLA ", 0x1F); else pstwMsgUAMI->vImprimeText (3, 2, "Programa car gado en UAMI", CREA_COLOR(BGRIS, FIBLANCO)); pstwMsgUAMI->vImprimeText (1, 4, " PRESIONE C UALQUIER TECLA ", 0x1F); wDUAMI188Flag = SETBIT (wDUAMI188Flag, FLAG188 _CARGA); wDUAMI188Flag = CLSBIT (wDUAMI188Flag, FLAG188 _CHINS); vEsperaEvento (); pstwMsgUAMI->hide (); vInterrupcionPtoSerie (TRUE); vLeerRegistrosUAMI188 (); //Lee los registros d e la UAMI188 x = wObtenRegistro (DBGREG_CS); y = wObtenRegistro (DBGREG_IP); vDepuradorVolcado (x, y); //Actualiza el volcad o void DUAMI188::vEjecutaPasoPaso () //Ejecuta un programa paso a paso (depuracion) e n la UAMI188EB byte bDato; ushort usMsg; if (TSTBIT(wDUAMI188Flag, FLAG188_CHINS)) usMsg = messageBox ("Se ha modificado una inst ruccion y no se actualizaron los cambios en la UAMI188EB, desea continuar?", mfYesButton|mfNoButto n|mfInformation); if (usMsg==12) return; vInterrupcionPtoSerie (FALSE); pstwMsgUAMI->vMuestra (); pstwMsgUAMI->vLimpiaVentana (); bDato = bEnviaComandoEstado (cmsOK); wDUAMI188Flag = CLSBIT (wDUAMI188Flag, FLAG188_C ARGA); if ((bDato!=INDICA_STP)&&(bDato!=INDICA_DBG)) pstwMsgUAMI->hide (); messageBox ("No es posible ejecutar el program a. Revise el estado.", mfOKButton|mfInformation); vInterrupcionPtoSerie (TRUE); return; pstwMsgUAMI->vImprimeText (3, 2, "Ejecutando el programa ", CREA_COLOR(BGRIS, FIBLANCO)); bDato = bEnviaEsperaDato (cmsPaso); vInterrupcionPtoSerie (TRUE); if (bDato!=cmsOK) vFalloConexion (); return; psIndica->vIndicador (INDICA_DBG);

Page 404: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

399

pstwMsgUAMI->hide (); wBufferCS = wObtenRegistro (DBGREG_CS); //Guard a el registro CS void DUAMI188::vEjecutar () //Ejecuta el programa cargado en la UAMI188EB byte bDato; ushort usMsg; if (TSTBIT(wDUAMI188Flag, FLAG188_CHINS)) usMsg = messageBox ("Se ha modificado una inst ruccion y no se actualizaron los cambios en la UAMI188EB, desea continuar?", mfYesButton|mfNoButto n|mfInformation); if (usMsg==12) return; vInterrupcionPtoSerie (FALSE); pstwMsgUAMI->vMuestra (); pstwMsgUAMI->vLimpiaVentana (); bDato = bEnviaComandoEstado (cmsOK); wDUAMI188Flag = CLSBIT (wDUAMI188Flag, FLAG188_C ARGA); if ((bDato!=INDICA_STP)&&(bDato!=INDICA_DBG)) pstwMsgUAMI->hide (); messageBox ("No es posible ejecutar el program a. Revise el estado.", mfOKButton|mfInformation); vInterrupcionPtoSerie (TRUE); return; pstwMsgUAMI->vImprimeText (3, 2, "Ejecutando el programa ", CREA_COLOR(BGRIS, FIBLANCO)); bDato = bEnviaEsperaDato (cmsEjecutar); vInterrupcionPtoSerie (TRUE); if (bDato!=cmsOK) vFalloConexion (); return; psIndica->vIndicador (INDICA_RUN); pstwMsgUAMI->hide (); wBufferCS = wObtenRegistro (DBGREG_CS); //Guard a el registro CS //El depurador espera por el comando cmsEnd void DUAMI188::vLeerRetorno () //Lee el retorno de una programa ejecutado en la UAMI188EB byte bDato; vInterrupcionPtoSerie (FALSE); vContadorEspera (); pstwMsgUAMI->vMuestra (); pstwMsgUAMI->vLimpiaVentana (); bDato = bEnviaComandoEstado (cmsOK); if ((bDato!=INDICA_STP)) pstwMsgUAMI->hide (); messageBox ("Imposible leer el retorno del pro grama.", mfOKButton|mfInformation); vInterrupcionPtoSerie (TRUE); return; psIndica->vIndicador (bDato); vContadorEspera (); bDato = bEnviaEsperaDato (cmsObtenRet); messageBox (mfOKButton|mfInformation, "El progra ma regreso un %d.", bDato); vInterrupcionPtoSerie (TRUE); pstwMsgUAMI->hide (); void DUAMI188::vLeerError () //Lee el error generado por la ejecucion de un p rograma en la UAMI188EB byte bDato; vInterrupcionPtoSerie (FALSE); vContadorEspera (); pstwMsgUAMI->vMuestra (); pstwMsgUAMI->vLimpiaVentana ();

Page 405: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

400

bDato = bEnviaComandoEstado (cmsOK); if ((bDato!=INDICA_STP)) pstwMsgUAMI->hide (); messageBox ("Imposible leer el error del progr ama.", mfOKButton|mfInformation); vInterrupcionPtoSerie (TRUE); return; psIndica->vIndicador (bDato); bDato = bEnviaEsperaDato (cmsObtenErr); switch (bDato) case cerrDivCero: //Division entre cero messageBox ("Division entre cero.", mfError| mfOKButton); break; case cerrOverFlow: //Overflow messageBox ("Overflow.", mfError|mfOKButton) ; break; case cerrArrar: //Array bounds exception messageBox ("Array bounds exception.", mfErr or|mfOKButton); break; case cerrUnused: //Unused opcode exception messageBox ("Unused opcode exception.", mfEr ror|mfOKButton); break; case cerrEscape: //Escape bounds exception messageBox ("Escape bounds exception.", mfEr ror|mfOKButton); break; default: break; vInterrupcionPtoSerie (TRUE); pstwMsgUAMI->hide (); void DUAMI188::vDetenerEjecucion () //Detiene la ejecucion de una programa en la UAM I188EB byte bDato; vInterrupcionPtoSerie (FALSE); pstwMsgUAMI->vMuestra (); pstwMsgUAMI->vLimpiaVentana (); bDato = bEnviaComandoEstado (cmsOK); if ((bDato!=INDICA_RUN)&&(bDato!=INDICA_DBG)) pstwMsgUAMI->hide (); messageBox ("No es posible detener el programa . Revise el estado.", mfOKButton|mfInformation); vInterrupcionPtoSerie (TRUE); return; pstwMsgUAMI->vImprimeText (3, 2, "Deteniendo el programa ", CREA_COLOR(BGRIS, FIBLANCO)); bDato = bEnviaEsperaDato (cmsDetener); vInterrupcionPtoSerie (TRUE); if (bDato!=cmsOK) vFalloConexion (); return; psIndica->vIndicador (INDICA_STP); pstwMsgUAMI->hide (); void DUAMI188::vCargaRegistro (byte bReg) //Modifica el valor de un registro en la UAMI188 EB word wReg; byte bDato; wReg = wObtenRegistro (bReg); //Registro a camb iar vInterrupcionPtoSerie (FALSE); pstwMsgUAMI->vMuestra (); pstwMsgUAMI->vLimpiaVentana (); bDato = bEnviaComandoEstado (cmsOK);

Page 406: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

401

if ((bDato!=INDICA_STP)&&(bDato!=INDICA_DBG)&&(b Dato!=INDICA_OK)) pstwMsgUAMI->hide (); messageBox ("No es posible modificar el regist ro.", mfOKButton|mfInformation); vInterrupcionPtoSerie (TRUE); return; bDato = bEnviaEsperaDato (cmsCargaReg); if (bDato!=cmsOK) vFalloConexion (); vInterrupcionPtoSerie (TRUE); return; while (!bEnviaDato(bReg)); //Envia los datos, p arte baja while (!bEnviaDato(LBYTE(wReg))); //Envia los d atos, parte BAJA while (!bEnviaDato(HBYTE(wReg))); //Envia los d atos, parte ALTA pstwMsgUAMI->hide (); vInterrupcionPtoSerie (TRUE); //Responsabilidad de la UAMI188EB, cargar el reg istro. void DUAMI188::vCargaMemoria (word wSeg, word wOff , word wNBytes, byte *pbDatos) //Carga informacion en la memoria de la UAMI188E B word x, y; byte bDato; if (!wNBytes) return; //No CARGA 0 bytes //Establece comunicacion vInterrupcionPtoSerie (FALSE); pstwMsgUAMI->vMuestra (); pstwMsgUAMI->vLimpiaVentana (); bDato = bEnviaComandoEstado (cmsOK); if ((bDato!=INDICA_STP)&&(bDato!=INDICA_DBG)&&(b Dato!=INDICA_OK)) pstwMsgUAMI->hide (); messageBox ("No es posible cargar en memoria d e la UAMI188EB.", mfOKButton|mfInformation); vInterrupcionPtoSerie (TRUE); return; bDato = bEnviaEsperaDato (cmsCargaMem); if (bDato!=cmsOK) vFalloConexion (); vInterrupcionPtoSerie (TRUE); return; while (!bEnviaDato(LBYTE(wSeg))); //Envia los d atos, parte baja while (!bEnviaDato(HBYTE(wSeg))); //Envia los d atos, parte alta while (!bEnviaDato(LBYTE(wOff))); //Envia los d atos, parte baja while (!bEnviaDato(HBYTE(wOff))); //Envia los d atos, parte alta while (!bEnviaDato(LBYTE(wNBytes))); //Envia lo s datos, parte baja while (!bEnviaDato(HBYTE(wNBytes))); //Envia lo s datos, parte alta pstwMsgUAMI->vImprimeText (3, 2, "Transfiriendo ", CREA_COLOR(BGRIS, FIBLANCO)); vContadorEspera (); //Hace una espera x = wNBytes; y = CERO; do pstwMsgUAMI->vImprimeNum (17, 2, 10, x, CREA_ COLOR(BGRIS, FIBLANCO)); while (!bEnviaDato(*(pbDatos+y))); //Envia lo s datos x--; y++; while (x); pstwMsgUAMI->hide (); vInterrupcionPtoSerie (TRUE); void DUAMI188::vFijaHoraUAMI188EB () //Fija la hora del sistema en la UAMI188EB byte bDato; word wCX, wDX; union REGS srRegsIn, srRegsOut; srRegsIn.h.ah = 0x02; int86 (0x1A, &srRegsIn, &srRegsOut); //Leemos l a hora

Page 407: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

402

wCX = srRegsOut.x.cx; wDX = srRegsOut.x.dx; //Establece comunicacion vInterrupcionPtoSerie (FALSE); pstwMsgUAMI->vMuestra (); pstwMsgUAMI->vLimpiaVentana (); bDato = bEnviaComandoEstado (cmsOK); if (bDato==INDICA_DSC) pstwMsgUAMI->hide (); vInterrupcionPtoSerie (TRUE); return; if (bDato==INDICA_RUN) pstwMsgUAMI->hide (); messageBox ("No es posible cambiar la hora, es ta ejecutandose un programa", mfOKButton|mfInformation); vInterrupcionPtoSerie (TRUE); return; bDato = bEnviaEsperaDato (cmsFijaHora); if (bDato!=cmsOK) vFalloConexion (); vInterrupcionPtoSerie (TRUE); return; pstwMsgUAMI->vImprimeText (3, 2, "Colocando la h ora ", CREA_COLOR(BGRIS, FIBLANCO)); while (!bEnviaDato(LBYTE(wCX))); //Envia palabr a baja while (!bEnviaDato(HBYTE(wCX))); //Envia palabr a alta while (!bEnviaDato(LBYTE(wDX))); //Envia palabr a baja while (!bEnviaDato(HBYTE(wDX))); //Envia palabr a alta pstwMsgUAMI->hide (); vInterrupcionPtoSerie (TRUE); //Las siguientes funciones emplean de la ventana d e estado de la UAMI188EB //ANTES DE USARLAS SE DEBE DESACTIVAR LA INTERRUPC ION DEL PUERTO SERIE; //ADEMAS, ESTAS FUNCIONES NO ACTIVAN LA INTERRUPCI ON byte DUAMI188::bEnviaEsperaDato (byte bSend) //Envia un dato y espera otro byte bDato, bSalir=FALSE; pstwMsgUAMI->vLimpiaVentana (); pstwMsgUAMI->vImprimeText (2, 1, "Estado:", CREA _COLOR(BGRIS, FIBLANCO)); pstwMsgUAMI->vImprimeText (3, 2, "Conectando con UAMI188EB", CREA_COLOR(BGRIS, FIAMARILLO)); while (!bEnviaDato(bSend)); vFijaTemporizador (wEsperaPuerto); while ((!bChkTemporizador())&&(!bSalir)) if (bRecibeDato(&bDato)) bSalir = TRUE; pstwMsgUAMI->vImprimeText (3, 2, "Conexion estab lecida ", CREA_COLOR(BGRIS, FIVERDE)); if (bSalir) return (bDato); return (cmsNada); void DUAMI188::vFalloConexion () pstwMsgUAMI->vImprimeText (3, 2, "Error en la co nexion ", CREA_COLOR(BGRIS, FROJO)); pstwMsgUAMI->vImprimeText (1, 4, " PRESIONE CUA LQUIER TECLA ", 0x1F); vEsperaEvento (); pstwMsgUAMI->hide (); byte DUAMI188::bEsperaTransDato (byte *pbDato) //Simplemente espera un dato, retorna 1 si se re cibe byte bSalir=FALSE; vFijaTemporizador (wEsperaPuerto); while ((!bChkTemporizador())&&(!bSalir)) if (bRecibeDato(pbDato)) bSalir = TRUE;

Page 408: Desarrollo de un depurador/ensamblador, y mejora del ...148.206.53.84/tesiuami/UAMI12502.pdf · denominado “ Desarrollo de un depurador/ensamblador, y mejora del software Monitor

403

if (!bSalir) return (FALSE); //No se obtuvo nad a return (TRUE); byte DUAMI188::bEnviaComandoEstado (byte bDatoSend ) //Se encarga de enviar un comando, esperar respu esta y recibir el estado byte bDato; bDato = bEnviaEsperaDato (bDatoSend); if (bDato!=cmsOK) vFalloConexion (); psIndica->vIndicador (INDICA_DSC); return (INDICA_DSC); //Espera el estado de la tarjeta if (bEsperaTransDato(&bDato)) psIndica->vIndicad or (bDato); else psIndica->vIndicador (INDICA_DSC); return (bDato); byte DUAMI188::bEsperaDatoCola (byte *pbDato, word wTmp) //Simplemente espera un dato de la cola, retorna 1 si se recibe byte bSalir=FALSE, bDato; vFijaTemporizador (wTmp); while ((!bChkTemporizador())&&(!bSalir)) if (bObtenDatoCola(&bDato)) bSalir = TRUE; if (!bSalir) return (FALSE); //No se obtuvo nad a *pbDato = bDato; return (TRUE); void DUAMI188::vDepuradorVolcado (word wSeg, word wOffSet) //Carga del depurador al volcado solo en cargas de programas word x, y; x = LEN_CODMAQ(); //Lo que se va a cargar al Vo lcado psdwDWin->vFijaSegOffVolMem (wSeg, wOffSet); for (y=0; (y<x)&&(y<wTamVolMem); y++) *(pbBuffVolMem+y) = BUFF_CODMAQ(y); void vContadorEspera () //Esta es una funcion que hace tiempo word x, y; for (x=0; x<0xFFFE; x++) y = x * x; x = y;