El DEBUG es un programa de DOS que permite visualizar la memoria, introducir programas en ella y rastrear su ejecución. Es utilizado para probar y depurar programas ejecutables. Trabaja desplegando todo el código del programa y los datos en formato hexadecimal, y cualquier dato que se introduzca a la memoria también debe estar en formato hexadecimal. Permite también ejecutar un programa en “modo de paso sencillo”(un paso a la vez), de manera que se pueda ver el efecto de cada instrucción sobre las localidades de memoria y los registros.
Introducir “programas” con Debug
Como a partir de ahora tendremos más de una instrucción, y la introducción de las instrucciones las estamos realizando directamente en código de máquina (números hexadecimales) tal como CDh 21h
(INT 21), escribir estas instrucciones se torna complicado.
Para esto, el Debug incluye el comando A (Assemble, ensamblar), que nos permite introducir directamente la mnemotecnia, o instrucciones que nos resultan más fáciles de comprender y memorizar. Así que en ves de introducir los códigos de máquina en hexadecimal, a partir de ahora comenzaremos a utilizar el comando A.
Por ejemplo, si deseamos escribir las instrucciones INT 21 e INT 20 en las posiciones 100h y 102h respectivamente, desde el indicador del Debug debemos ingresar:
- A 100 [Enter]
11F5:0100 INT 21 [Enter]
11F5:0102 INT 20 [Enter]
11F5:0104 [Enter]
Nota: El listado anterior es un ejemplo, y no se debe ejecutar.
Mover datos a Registros
Como vimos, para realizar operaciones aritméticas debemos asignar valores a registros. Para evitar tener que hacerlo utilizando la orden R del Debug, utilizaremos la instrucción MOV para cargar números en registros.
Veamos como funciona moviendo números de un registro a otro:
Primero introducimos en AX el valor 1234h por medio de la instrucción MOV AX, 1234 y en DX el valor ABCDh, por medio de MOV DX, ABCD. El comando del Debug que debemos utilizar para introducir las instrucciones es A 100. para ubicar los códigos a partir de la dirección 100h. Escribamos en la próxima dirección, la instrucción MOV AH,DL y ejecutemos con T las tres instrucciones anteriores.
1) ¿Qué valores hay en los registros AX y DX?
Si ahora introducimos MOV BX, AX en la dirección 0108h (que debería ser la próxima dirección libre) y lo ejecutamos con T...
2) ¿Cuáles son los nuevos valores de los registros AX y BX?
Veamos ahora los siguientes ejemplos:
Utilizando el comando A del Debug, ingresar las siguientes instrucciones:
11F5:0100 MOV AX,1000
11F5:0103 MOV BX,1010
11F5:0106 ADD AX,BX
3) ¿Qué realiza cada una de las instrucciones del listado anterior?. Detallar
En nuestro próximo ejemplo, veremos una forma diferente de escribir en los registros los datos a sumar.
Primero, utilizando el comando E del Debug hagamos lo siguiente:
-E 1000 [Enter]
11F5:1000 00.FF 11.00 [Enter]
-E 1010 [Enter]
11F5:1010 EC.00 00.11 [Enter]
Luego, utilizando el comando A, introduzcamos las instrucciones:
- A 100 [Enter]
11F5:0100 MOV AX,[1000]
11F5:0103 MOV BX,[1010]
11F5:0107 ADD AX,BX
11F5:0109 MOV [1020],AX [Enter]
Para comprenderlo mejor, veamos el volcado de la memoria entre las direcciones 1000h y 1030h, utilizando para ello el comando D de Debug, y el rango de memoria que queremos ver
-D 1000, 1030 [Enter]
11F5:1000 FF 00 A3 01 74 08 3C 0C-77 43 75 02 32 C0 2E F6 ....t.<.wCu.2...
11F5:1010 00 11 A3 04 74 0C 3C 0C-74 08 04 0C 72 2F 3C 18 ....t.<.t...r/<.
11F5:1020 FF 11 8A D0 2E A1 36 A4-0A E4 75 21 8A F0 2E A1 ......6...u!....
11F5:1030 38
4) ¿Qué realizan las instrucciones que hemos ingresado en el paso anterior?. Detallar los pasos realizados.
Interrupciones (INT)
Veamos ahora el funcionamiento de una interrupción de software. Para eso utilicemos el siguiente ejemplo:
1. Carguemos el DEBUG.
2. Escribamos el valor 200h en AX y 41h en DX, utilizando el comando A del Debug.
3. La instrucción INT de las funciones del DOS es INT 21h (en código de máquina: CDh 21h). Esta es una instrucción de dos bytes. Escribamos dicha instrucción INT 21h, en la posición de memoria 106h, utilizando el comando A del Debug. Recuerde que para poder ejecutar este pequeño programa, el registro IP debe apuntar a la dirección 100h.
Veamos ahora que ocurre si utilizamos el comando T del Debug para ejecutar las instrucciones: Como T ejecuta las instrucciones línea a línea, y la instrucción INT llama a un programa muy largo del DOS, nos pasaríamos un buen rato presionando T, hasta que termine de ejecutarse la interrupción INT 21.
Para evitar esto, utilizamos el comando G (Go) del Debug, poniendo a continuación la dirección en la que queremos parar:
-G 108
El DOS a escrito el carácter A, y luego ha devuelto el control al nuestro pequeño programa.
¿Cómo sabía el DOS que tenía que imprimir la letra A?
El valor 02h del registro AH le dijo al DOS que imprimiese un carácter. Cualquier otro número que hubiese en AH le diría al DOS que ejecute una función diferente.
En cuanto al carácter, el DOS utiliza el número que hay en el registro DL como código ASCII del carácter que se va a imprimir. En DL habíamos almacenado el valor 41h; es decir, el código ASCII de la letra A.
5) ¿Cuáles son los pasos que debe seguir para imprimir la letra B? Enumérelos.
La Interrupción de salida (INT 20h)
INT 20h es otra instrucción de interrupción, e indica que queremos salir del programa, y en nuestro caso devolverá el control al Debug.
Como ejemplo, agreguemos en la línea 102 el código CD 20 (INT 20), y ejecutemos las dos líneas por medio de G.
NOTA: En las últimas versiones del DOS se presentan problemas con las INT 20h al ejecutar el
programa fuera del Debug. Por lo tanto utilizaremos la función 4Ch de la INT 21h como reemplazo de la INT 20h.
6) ¿Qué es lo que obtenemos en la pantalla?
7) ¿Cuáles son las 4 (ó 5) instrucciones necesarias para escribir un “*” en la pantalla y devolver el control al DOS?
Escribir una cadena de caracteres
Veamos un ejemplo del uso de interrupciones de software, cadenas de caracteres en ASCII y su almacenamiento en la memoria. Escribamos el siguiente código en la dirección 0100h:
11F5:0100 MOV AH,09
11F5:0102 MOV DX,0200
11F5:0105 INT 21
11F5:0107 INT 20
En la dirección 0200h escribamos lo siguiente, utilizando la orden E 200, separando cada par de dígitos hexadecimales por medio de un espacio, y terminando con Enter.
11F5:0200 51 75 65 20 65 73 20 65 73 74 6F 3F 24
Nota: Al ingresar una cadena de caracteres, se indica el final de la misma por medio del carácter “$”
en la última posición.
8) ¿Qué hemos hecho en el ejemplo anterior? Explicarlo.
9) Realizar un pequeño programa que nos permita escribir los nombres de cada uno de los integrantes del grupo en la pantalla, uno debajo del otro.
Por último, analicemos el siguiente segmento de código:
11F5:0100 MOV AX,4100
11F5:0103 MOV BX,0041
11F5:0106 ADD AX,BX
11F5:0108 MOV DL,AH
11F5:010A MOV AH,02
11F5:010C INT 21
11F5:010E MOV DL,AL
11F5:0110 INT 21
11F5:0112 INT 20
10)¿Qué ocurre si lo “corremos” por medio del comando G de Debug?. ¿Qué función cumple cada una de las líneas del listado anterior, y a que se debe el resultado obtenido?