Vous êtes sur la page 1sur 30

Colima

El comando DEBUG By Benji 2007 V3.0

Mxico

Un Poco de Historia En 1980, Tim Paterson con 24 aos de edad, basndose en el CP/M (Control Program for Microcomputers, escrito por Gary Kildall) comenz a trabajar en un Sistema Operativo llamado QDOS (Quick and Dirty Operating System, sistema operativo rpido y sucio) para el microprocesador 8086 de 16-bit incorporado en una tarjeta tipo S-100 que haba diseado para SCP (Seattle Computer Products) un ao anterior. Para ayudar a conseguir que QDOS (ms tarde llamado 86-DOS Disk Operating System, sistema operativo de disco) funcionara correctamente, Tim cre un depurador en un chip ROM, la versin del cdigo se publico como de dominio pblico. Ms tarde, Tim adapto el cdigo para que se ejecutara como un programa .COM en el QDOS y tambin le aadi la posibilidad de desensamblar cdigo maquina del 8086. Mientras tanto, IBM haba encargado un sistema operativo para su IBM-PC a Microsoft, al cual ya se le terminaba el plazo de entrega estipulado y no dispona an del software, por lo cual Bill Gates y Paul Allen decidieron comprar los derechos por $50 000 dlares (primero una licencia parcial y ms tarde una licencia completa) del sistema creado por Tim Paterson y contrataron a ste (en mayo de 1981) para reescribir el QDOS y adaptarlo al microprocesador usado en el IBM-PC, el 8088 de Intel. El resultado fue vendido como PC-DOS (Personal Computer Disk Operating System) a IBM y ms tarde comercializado como MS-DOS (Micro Soft Disk Operating System) a las computadoras clones que surgiran tras el xito de IBM-PC. En la versin del DOS 1.00 de 1981, el programa DEBUG.COM se encuentra incluido como un componente ms del DOS. Toda la funcionalidad que Tim pone en DEBUG est todava all y poco se ha aadido a ella [1] . Tim fue contratado por Microsoft en diversos periodos de su vida y trabaj en el desarrollo de Visual Basic. Algn tiempo despus tambin recibi algunas acciones de la misma. Actualmente tiene una compaa de hardware Paterson Tech.

Introduccin El "DEBUG.EXE" es una utilidad de MS-DOS (Microsoft Disk Operating System) que permite visualizar el contenido de la memoria, introducir programas en ella y rastrear su ejecucin. Una caracterstica de DEBUG.EXE es que despliega todo el cdigo del programa en formato hexadecimal. Otra utilidad es que se puede utilizar tambin para el desarrollo de pequeas aplicaciones en ensamblador [2]. Usando DEBUG es posible observar el comportamiento de las instrucciones, la forma en cmo stas afectan a las banderas, los contenidos de la memoria, el cdigo de las instrucciones; adems permite ensamblar cdigo elemental usando los mnemotcnicos del 8086.

Nota: "Bug" significa fallo, defecto en un programa; "DEBUG" significa depurar (escrutar y eliminar fallos). La palabra ha quedado como verbo (depurar), de la que han derivado otras. Por ejemplo: "DEBUGger" (depurador). Por extensin, todos los programas y utilidades que sirven para escudriar los datos y el cdigo a bajo nivel, se identifican genricamente con esta denominacin.

Se trata de una utilidad interactiva de exploracin de bajo nivel, pero que tambin puede utilizarse para ciertas funciones. Por ejemplo, como un rudimentario traductor de sentencias ensamblador a lenguaje mquina. Como todos los programas de su tipo, debe utilizarse con

cierto cuidado. En especial si utiliza el comando W (se puede borrar todo un disco duro con un simple comando errneo). Para utilizarlo basta invocarlo desde MS-DOS o desde una ventana DOS de Windows. Aunque en este ltimo caso algunas de sus funcionalidades ms interesantes no se pueden ejecutar (limitadas por Windows). Como se dijo anteriormente, el DEBUG es un programa de utilera del Sistema Operativo DOS y Windows; Es til para:

Ensamblar pocas lneas de cdigo ensamblador Des-ensamblar cdigo en RAM, ROM y Archivos ejecutables Correr paso-a-paso programas Desplegar datos en memoria Verificar estado de los registros del CPU

Nota: Es importante recordar que muchos usos de estas utilidades de bajo nivel, requieren un funcionamiento stand-alone. Es decir, fuera de un Sistema Operativo multiusuario, ya que stos encapsulan y ocultan (virtualizan) muchos aspectos del hardware.

El Microprocesador 8088 tiene 14 registros internos, cada uno de 16 bits. Los primeros cuatro, AX, BX, CX, y DX son registros de uso general y tambin pueden ser utilizados como registros de 8 bits, para utilizarlos como tales es necesario referirse a ellos como por ejemplo: AH y AL, que son los bytes alto (high) y bajo (low) del registro AX. Esta nomenclatura es aplicable tambin a los registros BX, CX y DX.

Arquitectura del microprocesador 8088

El registro AX

Todos los registros ocupan dos bytes de longitud (16 bits). Los registros de propsito general se pueden utilizar divididos en dos partes de un byte de longitud respectivamente, por consiguiente, AX se divide en AH y AL, donde AL es la parte LOW o Baja del registro AX, mientras que AH es la parte HIGH o parte Alta del registro AX.

AX |------------------------| 11010110 10111000 AH AL

Si se almacena en AL un dato (de 8 bits por supuesto), la parte alta AH no se modifica y viceversa. Los registros son conocidos por sus nombres especficos:

AX BX CX DX DS ES SS CS BP SI DI SP IP F

Acumulador Registro base Registro contador Registro de datos Registro del segmento de datos Registro del segmento extra Registro del segmento de pila Registro del segmento de cdigo Registro de apuntadores base Registro ndice fuente Registro ndice destino Registro del apuntador de la pila Registro de apuntador de siguiente instruccin Registro de banderas

Registro AX Este registro es el acumulador principal, implicado en gran parte de las operaciones de aritmticas y de E/S.

Registro BX Recibe el nombre de registro base ya que es el nico registro de propsito general que se usa como un ndice en el direccionamiento indexado. Se suele utilizar para clculos aritmticos. Registro CX Es conocido como registro contador ya que puede contener un valor para controlar el nmero de veces que se repite una cierta operacin. Registro DX Se conoce como registro de datos. Algunas operaciones de E/S requieren su uso, y las operaciones de multiplicacin y divisin con cifras grandes suponen que el DX y el AX trabajando juntos. Registro CS Registro Segmento de Cdigo. Establece el rea de memoria dnde est el programa durante su ejecucin. Registro DS Registro Segmento de Datos. Especifica la zona donde los programas leen y escriben sus datos. Registro SS Registro Segmento de Pila. Permite la colocacin en memoria de una pila, para almacenamiento temporal de direcciones y datos. Registro ES Registro Segmento Extra. Se suele utilizar en algunas operaciones con cadenas de caracteres para direccionar la memoria. Registro SP Proporciona un valor de desplazamiento que se refiere a la palabra actual que est siendo procesada en la pila. Registro BP Facilita la referencia a los parmetros de las rutinas, los cuales son datos y direcciones transmitidos va la pila. Registro SI Registro ndice fuente requerido en algunas operaciones con cadenas de caracteres. Este registro est asociado con el registro DS. Registro DI Registro ndice destino requerido tambin en determinadas operaciones con cadenas de caracteres. Est asociado al registro DS o ES. Registro Apuntador de Instrucciones (IP). Se trata de un registro de 16 bits que contiene el desplazamiento de la direccin de la siguiente instruccin que se ejecutar. Est asociado con el registro CS en el sentido de que IP indica el desplazamiento de la siguiente instruccin a ejecutar dentro del segmento de cdigo determinado por CS: Registro de banderas, FLAGS, o registro de estado (FL). Es un registro de 16 bits, pero slo se utilizan nueve de ellos. Sirven para indicar el estado actual de la mquina y el resultado del procesamiento. La mayor parte de las instrucciones de

comparacin y aritmticas modifican este registro. Algunas instrucciones pueden realizar pruebas sobre este registro para determinar la accin siguiente.

OF (O) Bit de Overflow o desbordamiento. Indica desbordamiento de un bit de orden alto (ms a la izquierda), despus de una operacin aritmtica. DF (D) Bit de Direccin. Designa la direccin, creciente (0) o decreciente (1), en operaciones con cadenas de caracteres. IF (I) Bit de Interrupcin. Indica que una interrupcin externa, como la entrada desde el teclado, sea procesada o ignorada. TF (T) Bit de Trap o Desvo. Procesa o ignora la interrupcin interna de trace (procesamiento paso a paso). SF (S) Bit de Signo. Indica el valor del bit ms significativo del registro despus de una operacin aritmtica o de desplazamiento. ZF (Z) Bit Cero. Se pone a 1 si una operacin produce 0 como resultado. AF (A) Bit de Carry Auxiliar. Se pone a 1 si una operacin aritmtica produce un acarreo del bit 3 al 4. Se usa para aritmtica especializada (ajuste BCD). PF (P) Bit de Paridad. Se activa si el resultado de una operacin tiene paridad par. CF (C) Bit de Acarreo. Contiene el acarreo de una operacin aritmtica o de desplazamiento de bits.

Cargando el DEBUG en memoria Es posible visualizar los valores de los registros internos del microprocesador utilizando el programa DEBUG. Para empezar a trabajar con DEBUG escriba en el prompt del DOS de la computadora:

C:\> DEBUG [Enter]

Una vez que el programa est en ejecucin, el indicador ("prompt") es un guin "-", indicando que el "Shell" espera recibir rdenes. Para salir basta pulsar una Q. Como muchos programas de su gnero, sus comandos empiezan por una letra o combinacin de ellas (pueden usarse indistintamente maysculas o minsculas) y ciertos parmetros opcionales (no es imprescindible separar la letra de opcin de los parmetros opcionales que siguen). La opcin ms sencilla es la interrogacin (?), cuyo resultado es una lista resumida de las opciones disponibles:

Ensamblar A [direccin] Comparar C direccin de intervalo Volcar D [intervalo] Escribir E direccin [lista de valores] Llenar F lista de intervalos Ir G [=direccin] [direcciones] Hex H valor1 valor2 Entrada I puerto Cargar L [direccin] [unidad] [primer_sector] [nmero] Mover M direccin de intervalo Nombre N [nombre_ruta] [lista_argumentos] Salida O byte de puerto Proceder P [=direccin] [nmero] Salir Q Registro R [registro] Buscar S lista de intervalos Seguimiento T [=direccin] [valor] Desensamblar U [intervalo] Escribir W [direccin] [unidad] [primer_sector] [nmero] Asignar memoria expandida XA [#pginas] Desasignar memoria expandida XD [identificador] Asignar pginas de memoria expandida XM [Lpgina] [Ppgina] [identificador] Mostrar estado de la memoria expandida XS

En particular, obsrvese lo siguiente:

a) DEBUG opera bajo el sistema operativo DOS. b) Cuando se invoca (como en el ejemplo) sin argumentos, el contenido de la memoria es arbitrario. c) Si se invoca desde el DOS con argumentos, como por ejemplo: DEBUG EJEMPLO.COM, entonces carga a EJEMPLO.COM en memoria a partir de la direccin 0100h.

Comandos del DEBUG D: DUMP D <direccin1> <direccin2> Muestra el contenido de una zona de memoria en hexadecimal y en ASCII. Sin parmetros muestra los primeros 128 bytes a partir de la posicin a la que se lleg en el ltimo "d". Si se le da un rango, mostrar ese rango. Ambas direcciones son opcionales. La 1ra es la direccin de inicio de despliegue; la 2da es la direccin de fin. Ejemplo:

NOTA: El contenido de la memoria seguramente no coincide con el que otra persona obtenga.

E: EDIT E <direccin><lista> Permite editar, byte por byte, una zona de memoria. Muestra -en hexadecimal- el byte de esa posicin y permite escribir otro valor para cambiarlo. Pulsando espacio pasa al byte siguiente, dejando como estaba el anterior si no se ha cambiado, o guardando los cambios si s se ha hecho. Para terminar la edicin se pulsa INTRO. Los cambios pueden ser especificados en la lnea de comandos en cualquier combinacin de nmeros hexadecimales o caracteres ASCII; los caracteres ASCII deben estar entre comillas simples o dobles. Por ejemplo: E 100 'Benjamin Iglesias Establece el patrn "42 65 6E 6A 61 6D 69 6E 20 49 67 6C 65 73 69 61 73" en memoria a partir de la localidad 100H. Cuando no se especifica <lista> se entra en un modo especial en el que DEBUG despliega los valores de <direccin>. Entonces es posible teclear nuevos valores que reemplacen a los que se muestran. Si se teclea "-" DEBUG regresa a la localidad anterior. Si se activa la barra espaciadora, DEBUG pasa a la siguiente localidad.

R: REGISTERS R <registro> Sin parmetros, muestra el contenido de los registros de la CPU, as como la prxima instruccin a ejecutar."R [REGISTRO]" muestra el contenido del registro especificado y cambia

el prompt de "-" a ":" invitando a que se cambie su valor. Pulsando Enter sin ms lo deja como estaba. Ejemplo: R <registro> Donde <registro> es el nombre opcional y puede ser alguno de los siguientes: AX, BX, CX, DX, SP, BP, SI, DI, DS, ES, SS, CS, IP, PC o F. IP y PC son sinnimos.

A: ASSEMBLE A <direccin> Sin parmetros ensambla las instrucciones que se introduzcan, guardndolas en la direccin siguiente a la que se lleg en el ltimo "a". Cuando se utiliza este comando se le puede dar como parmetro la direccin donde se desea que se inicie el ensamblado, si se omite el parmetro el ensamblado se iniciar en la localizacin especificada por CS:IP, usualmente 0100H, que es la localizacin donde deben iniciar los programas con extensin .COM, y ser la localizacin que utilizaremos debido a que DEBUG solo puede crear este tipo especfico de programas. La sintaxis es A <direccin> Prcticamente cualquier mnemotcnico es soportado por DEBUG, incluyendo los especificadores de "override" de segmento (CS:, DS:, ES:, SS:). Una excepcin es que DEBUG no puede diferenciar entre NEAR y FAR returns; asume que RET es "near" y RETF es "far". Ejemplo: Vamos a usar la instruccin MOV, que como veremos ms adelante, sirve para copiar datos de la memoria a los registros y viceversa, adems de copiar datos entre registros, que es justo lo que vamos a usar en el ejemplo.

-a 2048:0106 mov ax,bx 2048:0108 mov bx,cx 2048:010A <RET> -u 106 108 2048:0106 89D8 MOV AX,BX 2048:0108 89CB MOV BX,CX

Como veremos ms adelante, la instruccin 'U' sirve para hacer volcados de memoria, pero no viendo el contenido de la misma, sino interpretndola como instrucciones en lenguaje ensamblador. ; Ejemplo 2

-r cs CS 2048 :2050 -a 200 2050:0200 mov ax,bx 2050:0202 <RET> -u 200 200 2050:0200 89D8 MOV AX,BX

F: FILL F <bloque> <valor de relleno> Este comando llena un bloque de memoria con un valor especfico o una serie de valores. La sintaxis es: F <bloque> <valor de relleno> <bloque> es la direccin de inicio y final o , si se preceden con "L", la direccin de inicio y la longitud del bloque; <valor de relleno> es(son) el(los) valor(es) con los que debe de llenarse el bloque. Si <valor de relleno> representa menor bytes que los que se necesitan para llenar el bloque, la serie se repite hasta llenar el bloque. Por ejemplo, cualquiera de las siguientes dos lneas llena (con 0s) el bloque DS:00FF:

F DS:0000 DS:00FF 0 DS:0000 LFF 0

Ejemplo:

-f 100 105 66 -d 100 105 2048:0100 66 66 66 66 66 66 ffffff

Q: QUIT Q Salir de DEBUG y volver al DOS.

P: PROCEED P <=direccin><nmero> Similar al comando T, pero al encontrarse un CALL o INT lo ejecuta de golpe sin entrar en su interior (ojo, esto ltimo falla al tracear sobre memoria ROM!). Trace puede ser incmodo si no se quiere depurar el cdigo de las rutinas de interrupcin o si ya se sabe el cdigo que hay en las subrutinas y tan slo interesa seguir avanzando sin entrar en ellas. En estos casos se usa p, por lo que si ejecutamos una interrupcin de MS-DOS no sabramos que estamos haciendo Ejemplo:

-r AX=0261 BX=0000 CX=0000 DX=0061 SP=FFEE BP=0000 SI=0000 DI=0000 DS=2048 ES=2048 SS=2048 CS=2048 IP=0107 NV UP EI PL NZ NA PO NC 2048:0107 3D5000 CMP AX,0050 -a 100 2048:0100 mov ax,0200 2048:0103 mov dl,61 2048:0105 int 21 2048:0107 -p =100 3

AX=0200 BX=0000 CX=0000 DX=0061 SP=FFEE BP=0000 SI=0000 DI=0000 DS=2048 ES=2048 SS=2048 CS=2048 IP=0103 NV UP EI PL NZ NA PO NC 2048:0103 B261 MOV DL,61 AX=0200 BX=0000 CX=0000 DX=0061 SP=FFEE BP=0000 SI=0000 DI=0000 DS=2048 ES=2048 SS=2048 CS=2048 IP=0105 NV UP EI PL NZ NA PO NC 2048:0105 CD21 INT 21 a AX=0261 BX=0000 CX=0000 DX=0061 SP=FFEE BP=0000 SI=0000 DI=0000 DS=2048 ES=2048 SS=2048 CS=2048 IP=0107 NV UP EI PL NZ NA PO NC 2048:0107 3D5000 CMP AX,0050

T: TRACE T <=direccin> <valor> Ejecuta una instruccin del programa (a partir de CS:IP) mostrando a continuacin el estado de los registros y la siguiente instruccin. Ejecutar T10 equivaldra a ejecutar 16 veces el comando T. Si la instruccin es CALL o INT, se ejecutar como tal introducindose en la subrutina o tabla de de interrupciones. Ejemplo:

-r AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=2048 ES=2048 SS=2048 CS=2048 IP=0100 NV UP EI PL NZ NA PO NC 2048:0100 3D0000 CMP AX,0000 -r bx BX 0000 :2 -a 100 2048:0100 mov ax,bx 2048:0102 -t AX=0002 BX=0002 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=2048 ES=2048 SS=2048 CS=2048 IP=0102 NV UP EI PL NZ NA PO NC 2048:0102 00AC01D8 ADD [SI+D801],CH DS:D801=74

; Ejemplo 2

-r AX=0000 BX=0007 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=2048 ES=2048 SS=2048 CS=2048 IP=0100 NV UP EI PL NZ NA PO NC 2048:0100 3D0000 CMP AX,0000 -a 100 2048:0100 mov ax,bx 2048:0102 mov cx,bx 2048:0104 -t 2 AX=0007 BX=0007 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=2048 ES=2048 SS=2048 CS=2048 IP=0102 NV UP EI PL NZ NA PO NC 2048:0102 89D9 MOV CX,BX AX=0007 BX=0007 CX=0007 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=2048 ES=2048 SS=2048 CS=2048 IP=0104 NV UP EI PL NZ NA PO NC 2048:0104 01D8 ADD AX,BX

N: NAME N <nombre_archivo> Se asigna un nombre al programa que est siendo creado o modificado. Se puede indicar la trayectoria de directorios.

L: LOAD L <buffer> <numdisco> <sectorini> <numsector> <buffer> es la direccin en donde se carga la informacin; <numdisco> es el nmero (opcional) del disco de donde se leer la informacin (0=A, 1=B, 2=C, etc.); <sectorini> es el sector de disco absoluto (en hexadecimal) a leer; <numsector> es la cantidad de sectores a leer. No se pueden leer ms de 80H (128) sectores. Si no se suministra la combinacin <numdisco> <sectorini> <numsector> DEBUG presume que se desea leer un archivo. En este caso <buffer> es opcional. Debe usarse el comando N (ver ms adelante) para especificar el archivo a leer. ste se carga en CS:0100. Ejemplo: Se va a leer el sector 0 del disco A y se vuelca a partir de la direccin DS:100, como se puede observar, el disco contiene mucha informacin ( ESTO NO QUIERE DECIR QUE TENGA QUE SALIR LO MISMO EN SU VOLCADO )

l 100 0 0 1 -d 100 300

W: WRITE W <direccin> Graba el contenido de una zona de memoria a disco. Si no se indica la direccin, se graba desde CS:100h hasta CS:100h+nmero_bytes; el nmero de bytes se indica en BX:CX (no es una direccin segmentada sino un valor de 32 bits). Si se trata de un EXE no se permitir grabarlo (para modificarlos, hay que renombrarles para cambiarles la extensin, aunque de esta manera no sern montados al cargarlos). La sintaxis es: W <buffer> <numdisco> <sectorini> <numsector> <buffer> es la direccin de donde se carga la informacin; <numdisco> es el nmero (opcional) del disco en donde se escribir la informacin (0=A, 1=B, 2=C, etc.); <sectorini> es el sector de disco absoluto (en hexadecimal) en donde empieza la escritura; <numsector> es la cantidad de sectores a leer. No se pueden escribir ms de 80H (128) sectores. Si no se suministra la combinacin <numdisco> <sectorini> <numsector> DEBUG presume que el inicio de archivo es CS:100. En este caso <buffer> es opcional. Debe usarse el comando N (ver arriba) para especificar el archivo a escribir. Antes de escribir BX:CX debe ajustarse al nmero de bytes que desean grabarse. W no puede escribir a archivos con la extensin EXE o HEX. [5] Ejemplo:

N <nomarchivo> BX:CX <--- 2000 W

S: SEARCH S <rango> <lista> Busca una cadena de bytes por la memoria. Para buscar la cadena "PEPE" terminada por cero en un rea de 512 bytes desde DS:100 se hara: S 100 L 200 "PEPE",0 (por defecto se busca en DS:). No se encontrara sin embargo "pepe" (en minsculas).

C: COMPARE C <rango> <direccin> Compara dos zonas de memoria mostrando las diferencias. Por ejemplo, para comparar 5 bytes de DS:100 y DS:200 se hace: C 100 L 5 200.

M: MOVE M <rango> <direccin> Ms que mover, copia una zona de memoria en otra de manera inteligente (controlando los posibles solapamientos de los bloques).

I: INPUT I <puerto> Visualiza la lectura del puerto de E/S indicado.

O: OUTPUT O <puerto> <valor> Enva un valor a un puerto de E/S.

H: HEX H <valor1> <valor2> Muestra la suma y resta de valor1 y valor2, ambos operandos de un mximo de 16 bits (si hay desbordamiento se trunca el resultado, que tampoco excede los 16 bits). Resultado: <resultado_1> ; Es la suma ( <valor1> + <valor2>), <resultado_2> ; es la resta (<valor1> - <valor2> ) Ejemplo:

-h 0003 0002 0005 0001 -h 0000 0001 0001 FFFF

como se observa, el resultado de la segunda operacin es FFFF que es el equivalente en complemento a 2 de -1

G: GO G =<inicio> <quiebre1> <quiebre2> ... <quiebre10> Este comando ejecuta el cdigo en memoria. Si se est depurando un programa, permite ejecutar el cdigo cargado en memoria. Tambin permite establecer puntos de quiebre (breakpoints) que son direcciones en las que se detiene la ejecucin del programa. La sintaxis es: G =<inicio> <quiebre1> <quiebre2> ... <quiebre10> <inicio> es la direccin de inicio de ejecucin; <quiebre1> hasta <quiebre10> son direcciones opcionales de paro del programa. Si no se especifica <inicio>, Go inicia con la direccin contenida en CS:IP. Para lograr los quiebres, DEBUG reemplaza el cdigo en las direcciones de quiebre por el valor hexadecimal CC, que es el cdigo de interrupcin. Si DEBUG llega a CC todos los puntos de quiebre son restituidos, los registros se despliegan (como con el comando R [vase adelante]) y se para la ejecucin. U: UNASSEMBLE U <rango> Este comando desensambla el contenido de la memoria a partir de la posicin actual. Registros y Banderas del DEBUG La mayora de los comandos de DEBUG ejecutan una accin y vuelven al indicador del shell, pero si es un comando largo, como puede ser mostrar un trozo grande de cdigo, puede detenerse pulsando CTRL-Pausa o interrumpirse con CTRL-C para volver al shell. Por ejemplo, al teclear lo siguiente: - r [Enter]

-R AX=0000 BX=0000 CX=2917 DX=0000 SP=FFFE BP=0000 SI=0000 DI=0000 DS=17A7 ES=17A7 SS=17A7 CS=17A7 IP=0100 NV UP EI PL NZ NA PO NC 17A7:0100 E8CD0F CALL 10D0 Se desplegaran todos los contenidos de los registros internos del microprocesador; una forma alternativa de mostrarlos es usar el comando "r" utilizando como parmetro el nombre del registro cuyo valor se quiera visualizar. Por ejemplo:

- r bx

Esta instruccin desplegar nicamente el contenido del registro BX y cambia el indicador del DEBUG de " - " a " : " Estando as el prompt es posible cambiar el valor del registro que se visualiz tecleando el nuevo valor y a continuacin [Enter], o se puede dejar el valor anterior presionando [Enter] sin teclear ningn valor. Es posible cambiar el valor del registro de banderas, as como utilizarlo como estructura de control en nuestros programas como se ver ms adelante. Cada bit del registro tiene un nombre y significado especial, la lista dada a continuacin describe el valor de cada bit, tanto apagado como prendido y su relacin con las operaciones del microprocesador:

Overflow (O) NV = no hay desbordamiento; OV = si lo hay Direction (D) UP = hacia adelante; DN = hacia atrs; Interrupts (I) DI = desactivadas; EI = activadas Sign (S) PL = positivo; NG = negativo Zero (Z) NZ = no es cero; ZR = s' lo es Auxiliary Carry (A) NA = no hay acarreo auxiliar;

AC = hay acarreo auxiliar Parity (P) PO = paridad non; PE = paridad par; Carry (C) NC = no hay acarreo; CY = Si lo hay

La estructura del ensamblador En el lenguaje ensamblador las lneas de cdigo constan de dos partes, la primera es el nombre de la instruccin que se va a ejecutar y la segunda son los parmetros del comando u operandos. Por ejemplo:

add ah,bh

Aqu "add" es el comando a ejecutar (en este caso una adicin) y tanto "ah" como "bh" son los parmetros. El nombre de las instrucciones en este lenguaje est formado por dos, tres o cuatro letras, a estas instrucciones tambin se les llama nombres mnemnicos o cdigos de operacin, ya que representan alguna funcin que habr de realizar el microprocesador. Existen algunos comandos que no requieren parmetros para su operacin, as como otros que requieren solo un parmetro. Algunas veces se utilizarn las instrucciones como sigue:

add al,[170]

Los corchetes en el segundo parmetro nos indican que vamos a trabajar con el contenido de la posicin de memoria nmero 170 y no con el valor 170, a esto se le conoce como direccionamiento directo.

Primer programa en ensamblador con el DEBUG Vamos a crear un programa que sirva para ilustrar lo que hemos estado viendo, lo que haremos ser una suma de dos valores que introduciremos directamente en el programa: El primer paso es iniciar el DEBUG, este paso consiste nicamente en teclear DEBUG [Enter] en el prompt del sistema operativo. Para ensamblar un programa en el DEBUG se utiliza el comando "a" (assemble); cuando se utiliza este comando se le puede dar como parmetro la direccin donde se desea que se inicie el ensamblado. Si se omite el parmetro el ensamblado se iniciar en la localidad especificada por CS:IP, usualmente 0100H, que es la localidad donde deben iniciar los programas con extensin .COM, y ser la localidad que utilizaremos debido a que DEBUG solo puede crear este tipo especfico de programas.

Aunque en este momento no es necesario darle un parmetro al comando "a" es recomendable hacerlo para evitar problemas una vez que se haga uso de los registros CS:IP, por lo tanto tecleamos: - a 100 [Enter] Al hacer esto aparecer en la pantalla algo como: 0C1B:0100 y el cursor se posiciona a la derecha de estos nmeros, ntese que los primeros cuatro dgitos (en sistema hexadecimal) pueden ser diferentes, pero los ltimos cuatro deben ser 0100, ya que es la direccin que indicamos como inicio. Ahora podemos introducir las instrucciones:

0C1B:0100 mov ax,0002 0C1B:0103 mov bx,0004 0C1B:0106 add ax,bx 0C1B:0108 int 20 0C1B:010A

;coloca el valor 0002 en el registro ax ;coloca el valor 0004 en el registro bx ;le adiciona al contenido de ax el contenido de bx ;provoca la terminacin del programa.

No es necesario escribir los comentarios que van despus del ";". Una vez escrito el ltimo comando, int 20, se le da [Enter] sin escribir nada ms, para volver al prompt del DEBUG. La ltima lnea escrita no es propiamente una instruccin de ensamblador, es una llamada a una interrupcin del sistema operativo, estas interrupciones sern tratadas ms a fondo en un captulo posterior, por el momento solo es necesario saber que nos ahorran un gran nmero de lneas y son muy tiles para accesar a funciones del sistema operativo. Para ejecutar el programa que escribimos se utiliza el comando "g", al utilizarlo veremos que aparece un mensaje que dice: "Program terminated normally". Naturalmente con un mensaje como ste no podemos estar seguros que el programa haya hecho la suma, pero existe una forma sencilla de verificarlo, utilizando el comando "r" del DEBUG podemos ver los contenidos de todos los registros del microprocesador, simplemente teclee:

- r [Enter]

Aparecer en pantalla cada registro con su respectivo valor actual: -R AX=0006 BX=0004 CX=0000 DX=0000 SP=FFFE BP=0000 SI=0000 DI=0000 DS=0C1B ES=0C1B SS=0C1B CS=0C1B IP=010A NV UP EI PL NZ NA PO NC 17A7:0100 E8CD0F CALL 10D0 Existe la posibilidad de que los registros contengan valores diferentes, pero AX y BX deben ser los mismos, ya que son los que acabamos de modificar. Otra forma de ver los valores, mientras se ejecuta el programa es utilizando como parmetro para "g" la direccin donde queremos que termine la ejecucin y muestre los valores de los registros, en este caso ser: g108, esta instruccin ejecuta el programa, se detiene en la direccin 108 y muestra los contenidos de los registros. Tambin se puede llevar un seguimiento de lo que pasa en los registros utilizando el comando "t" (trace), la funcin de este comando es ejecutar lnea por lnea lo que se ensambl mostrando cada vez los contenidos de los registros. Para salir del DEBUG se utiliza el comando "q" (quit).

Guardar y cargar los programas No sera prctico tener que escribir todo un programa cada vez que se necesite, para evitar eso es posible guardar un programa en el disco, con la enorme ventaja de que ya ensamblado no ser necesario correr de nuevo DEBUG para ejecutarlo, ya que cuando el DEBUG guardo nuestro programa en el disco, ste se guardo en binario (archivo con la extensin .com). Los pasos a seguir para guardar un programa ya almacenado en la memoria son: Obtener la longitud del programa restando la direccin final de la direccin inicial, naturalmente en sistema hexadecimal. Darle un nombre al programa y una extensin Poner la longitud del programa en el registro CX Ordenar a DEBUG que escriba el programa en el disco.

Utilizando como ejemplo el programa del ejemplo anterior tendremos una idea ms clara de cmo llevar estos pasos: Al terminar de ensamblar el programa se vera as:

0C1B:0100 0C1B:0103 0C1B:0106 0C1B:0108 0C1B:010A

mov ax,0002 mov bx,0004 add ax,bx int 20

Para almacenarlo en el disco, hacemos lo siguiente:

- h 10a 100 020a 000a - n prueba.com - r cx CX 0000 :000a -w Writing 000A bytes

Para obtener la longitud de un programa se utiliza el comando "h", el cual nos muestra la suma y resta de dos nmeros en hexadecimal. Para obtener la longitud del programa, le proporcionamos como parmetros el valor de la direccin final de nuestro programa (10A) y el valor de la direccin inicial (0100). El primer resultado que nos muestra el comando es la suma de los parmetros y el segundo es la resta. El comando "n" nos permite poner un nombre al programa. El comando "r cx" nos permite cambiar el contenido del registro CX al valor que obtuvimos del tamao del archivo con "h", en este caso 000a, ya que nos interesa el resultado de la resta de la direccin inicial a la direccin final.

Por ltimo el comando w escribe nuestro programa en el disco, indicndonos cuantos bytes escribi.

NOTA: Si se trabaja en una ventana de DOS de Windows Vista o 7, es probable que al momento de guardar su programa el DEBUG escriba mas cdigo que el sealado por el registro CX, por consiguiente ser necesario limpiar el registro BX, esto es, ponerlo a ceros y despus utilizar el comando w. Por ejemplo:

_r bx BX 000E : 0000 w

Para cargar un archivo ya guardado son necesarios dos pasos:

Proporcionar el nombre del archivo que se cargar a memoria. Cargarlo utilizando el comando "l" (load).

Para obtener el resultado correcto de los siguientes pasos es necesario que previamente se haya creado el programa anterior. Dentro del DEBUG escribimos lo siguiente:

- n prueba.com -l - u 100 109 0C3D:0100 0C3D:0103 0C3D:0106 0C3D:0108

B80200 BB0400 01D8 CD20

MOV AX,0002 MOV BX,0004 ADD AX,BX INT 20

El ltimo comando, "u", se utiliza para verificar que el programa se carg en memoria, lo que hace es desensamblar el cdigo y mostrarlo ya desensamblado. Los parmetros le indican a DEBUG desde donde y hasta donde desensamblar. DEBUG siempre carga los programas en memoria en la direccin 100H, a menos que se le indique alguna otra.

Un programa que realiza un conteo en pantalla Con el DEBUG es posible escribir un programa que realice un conteo en pantalla, por razones de comprensin, nuestro programa solo realizara un conteo de 9 a 0 (conteo descendente).

0B3B:0100 0B3B:0103 0B3B:0105 0B3B:0108 0B3B:010A

B90A00 88CA 80C22F B402 CD21

MOV MOV ADD MOV INT

CX,000A DL,CL DL,2F AH,02 21

; CX=10 en decimal ; sumamos 02Fh a DL ; funcin 02 de INT 21 para imprimir un caracter

0B3B:010C E2F5 0B3B:010E CD20

LOOP 0103 INT 20

; CX=0? Si no, salta a 0103 ; termina el programa

En la lnea 0103 se puede observar que el valor del registro CX en su parte baja (en CL) se almacena en el registro DL. Si se omitiera la lnea 0105, entonces cuando se ejecutara la lnea 010A solo se imprimira en pantalla el cdigo ASCII del valor que contenga DL (el cdigo ASCII de 0Ah que es 10 en decimal es un carcter especial no imprimible). Para conseguir el efecto de que el programa realiza el conteo en decimal se hace un corrimiento de 02F (47 en decimal). Por ejemplo, cuando se ejecuta la lnea 0105, DL tendra el valor de 39h=57d (02Fh+0Ah=39h=57d) y el cdigo ASCII de 57d es el carcter 9. El sentencia LOOP decrementa CX en 1, si CX es diferente a 0 salta a la lnea 0103. El proceso se repite y el programa imprime en pantalla 9876543210. Sera interesante que el programa anterior fuera modificado para que la numeracin se imprimiera de la siguiente manera: 9, 8, 7, 6, 5, 4, 3, 2, 1, 0.

NOTA: Como se dijo anteriormente, cuando el DEBUG almacena un programa en el disco, este archivo se graba en binario, esto es en ejecutable. Por lo tanto no es necesario cargar el DEBUG para volver a ejecutar nuestro programa, sino que se hace de manera directa desde DOS. El problema surge cuando al ejecutar nuestro programa el resultado no se puede observar porque el DOS borra la pantalla despus de terminar de ejecutar el programa. Para evitar el borrado automtico ser necesario agregarle a nuestro programa antes de la INT 20h una instruccin para la lectura de un carcter desde el teclado. Para tal efecto utilizaremos la funcin 08 de la INT 21h (un buen truco para que el programa haga una pausa), as el programa esperara hasta que el usuario presiona una tecla, permitiendo observar el resultado. Ejemplo mov ah,08 Int 21 Int 20

Condiciones, ciclos y bifurcaciones Estas estructuras, o formas de control le dan a la mquina un cierto grado de decisin basado en la informacin que recibe. La forma ms sencilla de comprender este tema es por medio de ejemplos. Vamos a crear tres programas que hagan lo mismo: desplegar un nmero determinado de veces una cadena de caracteres en la pantalla.

- a100 0C1B:0100 jmp 125 ; salta a la direccin 125H 0C1B:0102 [Enter] - e 102 'Cadena a visualizar 15 veces' 0d 0a '$' - a125 0C1B:0125 MOV CX,000F ; veces que se desplegara la cadena 0C1B:0128 MOV DX,0102 ; copia cadena al registro DX 0C1B:012B MOV AH,09 ; copia valor 09 al registro AH 0C1B:012D INT 21 ; despliega cadena 0C1B:012F LOOP 012D ; si CX>0 salta a 012D 0C1B:0131 INT 20 ; termina el programa.

Por medio del comando "e" es posible introducir una cadena de caracteres en una determinada localidad de memoria, dada como parmetro, la cadena se introduce entre comillas, le sigue un espacio, luego el valor hexadecimal del retorno de carro, un espacio, el valor de lnea nueva y por ltimo el smbolo '$' que el ensamblador interpreta como final de la cadena. La interrupcin 21 utiliza el valor almacenado en el registro AH para ejecutar una determinada funcin, en este caso mostrar la cadena en pantalla, la cadena que muestra es la que est almacenada en el registro DX. La instruccin LOOP decrementa automticamente el registro CX en uno y si no ha llegado el valor de este registro a cero salta a la posicin de memoria indicada como parmetro, lo cual crea un ciclo que se repite el nmero de veces especificado por el valor de CX. La interrupcin 20 termina la ejecucin del programa. Otra forma de realizar la misma funcin pero sin utilizar el comando LOOP es la siguiente: - a100 0C1B:0100 jmp 125 ; salta a la direccin 125H 0C1B:0102 [Enter] - e 102 'Cadena a visualizar 15 veces' 0d 0a '$' - a125 0C1B:0125 MOV BX,000F ; veces que se desplegara la cadena 0C1B:0128 MOV DX,0102 ; copia cadena al registro DX 0C1B:012B MOV AH,09 ; copia valor 09 al registro AH 0C1B:012D INT 21 ; despliega cadena 0C1B:012F DEC BX ; decrementa en 1 a BX 0C1B:0130 JNZ 012D ; si BX es diferente a 0 salta a 012D 0C1B:0132 INT 20 ; termina el programa.

En este caso se utiliza el registro BX como contador para el programa, y por medio de la instruccin "DEC" se disminuye su valor en 1. La instruccin "JNZ" verifica si el valor de BX es diferente a 0, esto con base en la bandera NZ, en caso afirmativo salta hacia la direccin 012D. En caso contrario contina la ejecucin normal del programa y por lo tanto se termina. Una ltima variante del programa es utilizando de nuevo a CX como contador, pero en lugar de utilizar LOOP utilizaremos decrementos a CX y comparacin de CX a 0.

- a100 0C1B:0100 jmp 125 ; salta a la direccin 125H 0C1B:0102 [Enter] - e 102 'Cadena a visualizar 15 veces' 0d 0a '$' - a125 0C1B:0125 MOV DX,0102 ; copia cadena al registro DX 0C1B:0128 MOV CX,000F ; veces que se desplegara la cadena 0C1B:012B MOV AH,09 ; copia valor 09 al registro AH 0C1B:012D INT 21 ; despliega cadena 0C1B:012F DEC CX ; decrementa en 1 a CX 0C1B:0130 JCXZ 0134 ; si CX es igual a 0 salta a 0134 0C1B:0132 JMP 012D ; salta a la direccin 012D 0C1B:0134 INT 20 ; termina el programa

En este ejemplo se us la instruccin JCXZ para controlar la condicin de salto, el significado de tal funcin es: salta si CX=0 El tipo de control a utilizar depender de las necesidades de programacin en determinado momento.

Manipulacin de Posiciones de Memoria Con el DEBUG es posible almacenar y recuperar datos numricos en memoria por medio de un programa a travs de los registros del microprocesador. Por ejemplo, el siguiente programa almacena previamente dos valores numricos en la posicin 0300h y 0400h respectivamente, despus el programa los recupera, realiza la operacin de suma con esos valores y el resultado lo almacena en la posicin 0500h.

-a 100 0B1C:0100 0B1C:0103 0B1C:0106 0B1C:0109 0B1C:010C 0B1C:010F 0B1C:0113 0B1C:0115 0B1C:0118 0B1C:011A -

mov ax,0002 mov [0300],ax mov ax,0004 mov [0400],ax mov ax,[0300] mov bx,[0400] add ax,bx mov [0500],ax int 21

;ax=2 ;almacenamos 2 en la direccin 0300h ;ax=4 ;almacenamos 4 en la direccin 0400h ;recuperamos el dato1 en AX ;recuperamos el dato2 en BX ;hacemos la operacin de suma en AX ;almacenamos el 6 en la direccin 0500h

Un nmero entre corchetes [numero_hex] indica una posicin de memoria, y su manejo se hace a travs de registros, ya que no es posible almacenar valores numricos de manera directa.

Ejecutamos el programa

-g 118 AX=0006 BX=0004 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=0B1C ES=0B1C SS=0B1C CS=0B1C IP=0118 NV UP EI PL NZ NA PE NC 0B1C:0118 CD21 INT 21 -

Para ver si el resultado se almaceno en la direccin correcta, hacemos:

Como se puede observar en la direccin 0B1C:0500 se encuentra el 06 y en 0B1C:0501 se encuentra el 00, que es el resultado de la operacin 2+4. Pero. Porque aparece el 06 y despus el 00, parecera que el resultado fue de 0600, pero no es as, lo que sucedes que los datos se almacenan en memoria de la siguiente manera:

Como se hizo la operacin AX=AX+BX, entonces el resultado es de 16 bits (dos bytes).

AX=6, entonces AX=0000 0000 0000 0110 (16 bits), por lo tanto los 8 bits de menor peso de AX son 0000 0110 y deben almacenarse en la direccin 0500 y en la direccin 0501 se almacena 0000 0000. 0 0 x x x x 0 0 x x x x 0 0 x x x x 0 0 x x x x 0 0 x x x x 1 0 x x x x 1 0 x x x x 0 0 x x x x 0500 0501 0502 0503 0504 0505

Orden creciente de la memoria

Interrupciones Definicin de interrupcin:

Una interrupcin es una instruccin que detiene la ejecucin de un programa para permitir el uso del microprocesador en un proceso prioritario. Una vez concluido este ltimo proceso se devuelve el control a la aplicacin anterior.

Por ejemplo, cuando estamos trabajando con un procesador de palabras y en ese momento llega un aviso de uno de los puertos de comunicaciones, se detiene temporalmente la aplicacin que estbamos utilizando para permitir el uso del microprocesador al manejo de la informacin que est llegando en ese momento. Una vez terminada la transferencia de informacin se reanudan las funciones normales del procesador de palabras. Las interrupciones ocurren muy seguido, sencillamente la interrupcin que actualiza la hora del da ocurre aproximadamente 18 veces por segundo. Para lograr administrar todas estas interrupciones, la computadora cuenta con un espacio de memoria, llamado memoria baja, donde se almacenan las direcciones de cierta localidad de memoria donde se encuentran un juego de instrucciones que el microprocesador ejecutar para despus regresar a la aplicacin que estaba en proceso. En los programas anteriores hicimos uso de la interrupcin nmero 20H para terminar la ejecucin de nuestros programas y en otros ejemplos, utilizamos otra interrupcin para mostrar informacin en pantalla (INT 21h): Utilizando DEBUG tecleamos:

- a100 2C1B:0100 JMP 011D 2C1B:0102 [ENTER] - E 102 'Hola, como estas.' 0D 0A '$' - A011D 2C1B:011D MOV DX,0102 2C1B:0120 MOV AH,09 2C1B:0122 INT 21 2C1B:0123 INT 20

En este programa la interrupcin 21h manda al monitor la cadena localizada en la direccin a la que apunta el registro DX. El valor que se le da a AH determina cual de las opciones de la interrupcin 21h ser utilizada, ya que esta interrupcin cuenta con varias opciones. El manejo directo de interrupciones es una de las partes ms fuertes del lenguaje ensamblador, ya que con ellas es posible controlar eficientemente todos los dispositivos internos y externos de una computadora gracias al completo control que se tiene sobre operaciones de entrada y salida.

Ms del DEBUG Una caracterstica poco conocida, es que DEBUG puede aceptar entradas desde un archivo "Script", que puede ser un simple archivo de texto ASCII en el que cada comando est separado del anterior por un INTRO. Despus del ltimo, que debe ser una "Q" para salir de DEBUG, es conveniente dejar una lnea en blanco pulsando INTRO dos veces. Las lneas pueden contener comentarios. Cualquier cosa a partir del caracter punto y coma (;) hasta el final de la lnea, ser ignorado.

; esto es un comentario D ; aqu se mostrar algo...

Suponiendo que tengamos un archivo "Script" de nombre Ordenes.txt, puede ser utilizado como entrada para DEBUG mediante un comando de redireccin en la siguiente forma:

DEBUG < ordenes.txt

Tambin puede conseguirse que el programa redireccione la salida hacia un archivo que puede ser inspeccionado ms tarde. Aunque tiene la dificultad de tener que trabajar "a ciegas", puede ser de utilidad en determinadas circunstancias. Por ejemplo, cuando se desea un volcado de determinadas zonas de la memoria. En el caso anterior podra obtenerse un archivo Result.txt con el siguiente comando:

DEBUG < ordenes.txt > Result.txt

Errores Cuando DEBUG no sabe interpretar un comando, muestra un mensaje de error y un indicador "^" debajo del sitio del comando donde est el error.

Entradas y Salidas DEBUG asume que los datos numricos proporcionados son hexadecimales, y cuando se trate de direcciones de memoria, deben introducirse en forma segmentada. A su vez, los resultados son mostrados tambin en formato hexadecimal cuando se refieren a direcciones de memoria. Cuando se trata simplemente del contenido de ciertas posiciones de memoria, el resultado es mostrado en formato hexadecimal y en ASCII. Por ejemplo, una salida puede presentar el siguiente aspecto:

Cada fila muestra 16 posiciones de memoria a partir de la posicin sealada por las columnas de la izquierda, que las muestran como segmento:desplazamiento. El bloque central muestra el contenido hexadecimal de cada byte, mientras que el bloque derecho contiene la representacin ASCII. Por ejemplo, la 3ra fila muestra el contenido de las posiciones 0B77:0120 a 0B77:012F (ambas inclusive). Sus tres ltimos bytes contienen respectivamente los caracteres r, 9 y 2, que corresponden a las cantidades 72h 39h y 32h del bloque central. Que como sabemos, equivalen a los decimales 114, 57 y 50, que son precisamente los valores ASCII de los caracteres r, 9, y 2 anteriormente mencionados.

Nota: Por razn de que ste tipo de salida pueda ser listado a impresora, el bloque derecho no contiene en realidad la representacin ASCII de todos los caracteres (algunos ni siquiera tienen una representacin imprimible). En realidad solo se muestran los caracteres imprimibles del primer bloque (US-ASCII). El resto est representado por un punto.

No perder de vista que, a pesar de que algunas posiciones de memoria puedan contener valores cuya equivalencia ASCII sea un carcter imprimible. Esto no significa que dichas posiciones representen efectivamente tales valores para la aplicacin que las utiliza. Por ejemplo, puede que en realidad, las dos posiciones de memoria mencionadas (dos octetos o bytes), en vez de los caracteres 5 y a, representen una palabra de 16 bits en formato Little Endian, que a su vez representan una cantidad entera (un nmero).

Comandos Aunque su descripcin completa llenara todo un captulo, a continuacin comentamos algunas de las opciones ms interesantes relativas a inspeccin del cdigo y de contenidos de memoria. La opcin D ("Dump") permite obtener un volcado del contenido de la memoria (de DEBUG). La sintaxis acepta dos formas:

D [direccin-inicial] [L posiciones-desde-direccin-inicial ] D [direccin-inicial][direccin-final]

Naturalmente, para que exista algo en el bfer de memoria (al principio quizs solo contiene basura) es preciso indicarle que lea algo. Este algo puede ser un rango de direcciones de memoria RAM; una direccin absoluta de disco (sector); un archivo, o el contenido de los registros del procesador. Para empezar puede indicrsele que cargue un archivo xxx.xyz, que tenemos en el directorio actual o en el PATH, cuyo contenido queremos ver.

C:\> DEBUG xxx.xyz -D

aqu se obtendra una salida anloga a la comentada.

Hemos visto un ejemplo al tratar de los servicios de interrupciones del PC, aqu mostraremos otro. Sabemos que el punto de inicio de la BIOS es la direccin F000:FFF0, y que desde sta posicin hasta el final de la memoria DOS hay 16 bytes. Puede obtenerse un volcado de estas posiciones con el siguiente comando:

-D F000:FFF0

La salida en un equipo puede ser: F000:FFF0 CD 19 E0 00 F0 30 36 2F-33 30 2F 39 37 00 FC 38 .....06/30/97..8

En este caso el comando solo muestra una lnea porque ha alcanzado el final de la memoria. Puede verse que la fecha de la BIOS del sistema ocupa las ltimas posiciones. Si se ordena el volcado de una direccin suficientemente alejada del final de la memoria, sin indicar ningn nmero de posiciones, por defecto se toma el valor 128 (8 filas de 16 posiciones). Si desea una cantidad distinta, hay que aadir una L ("Long") y el nmero de posiciones, hasta un mximo de 64 KB (FFFF). Todos los nmeros deben ser expresados en hexadecimal. Por consiguiente los dos comandos que siguen son equivalentes (recuerde que 80 es el equivalente hexadecimal de 128): D FE00:0000 D FE00:0000 L 80

He aqu el resultado:

Sabemos que esta zona corresponde al rea de la BIOS del Sistema... Otra opcin muy interesante nos permite buscar determinados contenidos a travs de la memoria utilizando el prefijo S ("Search"). Existen dos sintaxis alternativas:

S direccin-de-inicio L longitud-a-explorar contenido-a-buscar S direccin-de-inicio direccin-final L contenido-a-buscar

El contenido debe ser proporcionado en hexadecimal (tal como aparecera en la columna central del ejemplo anterior) o entre comillas si es un texto ASCII. Por ejemplo, en un equipo IBM, deseo ver algunas caractersticas de la BIOS. S que estos datos se alojan a partir de la posicin F000:0000 hasta el final de la memoria. Es decir, una longitud de 64 Kbytes (FFFF) a partir de la posicin de inicio, y que seguramente, los datos buscados estarn cerca de la identificacin de la propia BIOS (la cadena "IBM"). Por lo que se utiliza la siguiente sintaxis [3]:

-s f000:0000 L ffff "IBM"

y se obtiene la siguiente salida:

F000:E00E F000:E111

con las direcciones donde se ha encontrado la ocurrencia buscada. A continuacin puedo explorar las proximidades de cada posicin. Por ejemplo para la primera: -D f000:e000

Si lo que se busca est en un archivo, primero hay que cargarlo. Lo que se puede hacer de dos formas: en la propia invocacin de DEBUG, o mediante los comandos N y L. Por ejemplo, si queremos inspeccionar el contenido del archivo more.com, podemos utilizar dos formas:

C:\WINDOWS>DEBUG c:\windows\command\more.com C:\WINDOWS>DEBUG - N c:\windows\command\more.com -L

La sintaxis para el prefijo N es:

N [path-name]nombre-de-archivo

En ambos casos el contenido del archivo ser cargado en memoria y podr ser utilizado. Atencin: despus de la orden L ("Load"), DEBUG le avisar si no encuentra el archivo, pero seguir su funcionamiento. En tal caso simplemente piensa que N seala el nombre de un nuevo archivo que crear, con el contenido de la memoria -de DEBUG-, cuando posteriormente seleccione la opcin escribir W ("Write")[4].

Nota: Como ya habr deducido, DEBUG permite leer un archivo, realizar modificaciones en l (con la opcin E) y escribir el archivo modificado bajo otro nombre con N/W.

A continuacin podemos comprobar el tamao del archivo cargado. Para ello usamos la opcin R (ver estado de los registros) y obtenemos el siguiente resultado:

-R AX=0000 BX=0000 CX=2917 DX=0000 SP=FFFE BP=0000 SI=0000 DI=0000 DS=17A7 ES=17A7 SS=17A7 CS=17A7 IP=0100 NV UP EI PL NZ NA PO NC 17A7:0100 E8CD0F CALL 10D0 -

Aqu nos interesa especialmente el contenido del registro CX, cuyo valor, 2917h (1519d) en este caso, seala el tamao del archivo en bytes. Tambin podamos haber utilizado directamente el comando R CX que nos proporciona el valor de dicho registro:

-R CX CX 2917 : -

Nota: A continuacin del valor correspondiente, DEBUG muestra dos puntos (:), sealando que puede cambiar el valor del registro introduciendo un nuevo nmero. Pulse INTRO para dejar las cosas como estn y volver al "prompt" (-) de DEBUG.

Al llegar a este punto, es importante sealar que, a excepcin de los archivos .exe, DEBUG carga los archivos a partir de la direccin 100h (256d) de "su" memoria. De forma que el primer octeto del archivo se carga en la direccin 100; el segundo en 101; etc. En nuestro caso, el archivo se extender desde la posicin 100h hasta 2A17h (100h + 2917h). A continuacin, para buscar la cadena "Microsoft" en el archivo, utilizamos cualquiera de los siguientes comandos: - S 100 L 2917 "Microsoft" - S 100 2a17 "Microsoft"

El primer comando seala el punto de inicio y el tamao de la zona a buscar; el segundo utiliza los puntos inicial y final de la exploracin. Con ambos se obtiene la misma respuesta:

17A7:1083 17A7:10B2

Truco: Debido a la forma especial en que se cargan los ejecutables .exe, si quiere inspeccionar la forma nativa de uno de estos archivos (como es su imagen en el disco), debe hacer una copia del archivo; renombrarlo con cualquier otra terminacin (o sin ella) y cargar esta copia. En caso contrario, DEBUG se preparar para funcionar como un verdadero depurador de tiempo de ejecucin (run-time), para lo que cargar el archivo y lo acomodar en memoria de forma que pueda ejecutarse [5].

Como ejercicio, compruebe las distintas longitudes y aspecto (especialmente al principio) de un mismo archivo .exe cargndolo con DEBUG de las dos formas (busque en su sistema un .exe lo ms pequeo posible). Adems de la capacidad de leer archivos antes mencionada, quizs una de las opciones ms interesantes (y peligrosas) de DEBUG es la posibilidad de leer/escribir el contenido de disco a bajo nivel mediante los prefijos L ("Load") y W ("Write"). Se utiliza la siguiente sintaxis:

L [Direccin] [Unidad] [Primer_sector] [Nmero] W [Direccin] [Unidad] [Primer_sector] [Nmero]

El significado de los parmetros es como sigue:

Direccin: Posicin de la memoria de DEBUG, a partir de la cual se instalarn los datos ledos del disco, o se tomarn para el proceso de escritura (aqu se utiliza generalmente el valor 100h). Unidad: Valor numrico que indica la lgica a utilizar. 0 = A:; 1 = B:; 2 = C:; 3 = D:, etc [6] Primer sector: A partir del que se realizar la lectura, o se comenzar a escribir. Nmero: Nmero de sectores que se desea cargar/escribir. Como DEBUG no puede 16 leer/escribir ms de 64 Kbytes (2 = 65536) y los sectores de disco son de 512 bytes, el mximo nmero de sectores es 128 (80h). As pues, el valor mximo aqu es 80.

Ejemplo: Para obtener el contenido del sector de arranque ("Master boot sector" MBR) de un disquete en A:, utilizaremos el comando:

C:\WINDOWS>DEBUG - L 100 0 0 1 - D 100 L 200

Como el resultado no cabe en una pantalla, ingeniaremos un procedimiento para conservarlo en un archivo (ms adelante nos servir para otro propsito). Para ello creamos un archivo script.txt con el siguiente contenido (dos INTRO despus de la "Q"): L 100 0 0 1 D 100 L 200 Q

A continuacin invocamos DEBUG con el comando

C:\WINDOWS>DEBUG < D:\buzon\script.txt > D:\buzon\resultad.txt

Despus de un breve parpadeo del disco y del disquete, vuelve el "prompt" del DOS. La operacin ha concluido, y en el directorio correspondiente de la unidad D: tenemos el archivo resultad.txt con el volcado del sector de arranque del disquete, adems de los "ecos" de los comandos introducidos (los hemos mantenido para orientacin del lector). Otra forma de poder visualizar el contenido del Sector de Arranque del disco es utilizando el DEBUG. Por ejemplo, dentro del DEBUG tecleamos lo siguiente:
-L 100 0 0 1 -D 100 L 200 177C:0100 177C:0110 177C:0120 177C:0130 177C:0140 177C:0150 177C:0160 177C:0170 177C:0180 177C:0190 177C:01A0 177C:01B0 177C:01C0 EB 02 00 4D FA 1E F3 F9 66 46 03 8B 8B 3E E0 00 45 33 56 A4 FB 16 FC C3 FB 76 90 00 00 20 C9 16 06 38 03 89 48 B1 3E 2B 40 00 20 8E 55 1F 66 46 56 F7 01 F3 79 0B 00 20 D1 BF BD 24 1C FE F3 E8 A6 73 F0 00 20 BC 22 00 7C 13 B8 01 94 5E 57 09 29 46 FC 05 7C 04 56 20 46 00 74 29-49 00-12 5D-3B 41-54 7B-16 89-7E C6-45 CD-13 1E-03 00-8B FC-11 72-47 4A-4E 48 00 DD 31 07 00 FE 72 46 76 4E 38 74 43 02 10 32 BD 89 0F 3C 0E 11 FE 2D 0B 00 00 4E 20 78 4E 8B 8A 13 F7 5A 74 03 02 00 4F 20 00 02 46 46 D1 E6 58 19 F9 01 00 20 20 C5 B1 18 10 50 8B BB B1 83 01 00 4E F1 76 0B 88 98 52 5E 00 0B C7 00 00 41 7D 00 FC 45 F7 89 0B 07 56 15 .>.+ysW)IHC..... ...@............ ......)];..NO NA ME FAT12 .} .3.....{...x..v. .V.U."..~..N.... ......|.E...F..E ..8f$|...r<.F... f..F..V..F...PR. F..V.. ..v....^. ..H...F..N.ZX... .......rG8-t...V .v>..^tJNt......

177C:01D0 177C:01E0 177C:01F0 177C:0200 177C:0210 177C:0220 177C:0230 177C:0240 177C:0250 177C:0260 177C:0270 177C:0280 177C:0290 177C:02A0 177C:02B0 177C:02C0 177C:02D0 177C:02E0 177C:02F0 -Q

3B 75 74 BE CD 48 B1 00 33 F2 13 03 72 72 62 72 61 53 00

FB 99 09 81 19 8A 04 02 D2 8A 59 18 72 20 69 65 20 59 57

72 BE B4 7D BE 4E E8 42 F7 56 5A 01 65 45 65 73 20 53 49

E5 80 0E EB 82 0D 16 4A 76 24 58 27 63 2F 20 69 20 4D 4E

EB 7D BB E0 7D F7 00 75 18 8A 72 0D 74 53 65 6F 20 53 42

D7 AC 07 33 8B E1 5B 9F 91 E8 09 0A 6F 20 6C 6E 0D 44 4F

2B 98 00 C0 7D 03 72 EA F7 D0 40 44 20 20 20 65 0A 4F 4F

C9-B8 03-F0 CD-10 CD-16 0F-83 46-FC C8-81 00-02 76-18 CC-D0 75-01 69-73 20-20 20-20 64-69 20-75 00-49 53-20 54-20

D8 AC EB 5E FF 13 3F 70 42 CC 42 63 FF 20 73 6E 4F 20 53

7D 84 EE 1F 02 56 4D 00 87 0A 03 6F 0D FF 63 61 20 20 59

87 C0 BE 8F 72 FE 5A 50 CA CC 5E 20 0A 0D 6F 20 20 53 53

46 74 83 04 C8 BB 75 52 F7 B8 0B 69 45 0A 20 74 20 59 00

3E 17 7D 8F 8B 00 A7 51 76 01 E2 6E 72 43 79 65 20 53 00

3C 3C EB 44 C7 07 81 91 1A 02 CC 63 72 61 20 63 20 80 55

D8 FF E5 02 48 53 BF 92 8A CD C3 6F 6F 6D 70 6C 20 01 AA

;.r...+...}.F><. u...}.......t.<. t............}.. ..}..3...^....D. ....}.}....r...H H.N....F..V....S .....[r..?MZu... ..BJu....p.PRQ.. 3..v...v.B...v.. ..V$............ .YZXr.@u.B.^.... ...'..Disco inco rrecto ...Erro r E/S ...Cam bie el disco y p resione una tecl a ...IO SYSMSDOS SYS.. .WINBOOT SYS..U.

FIN [1] En las primeras versiones de MS-DOS era un modesto programita DEBUG.COM de apenas 16 KB. La versin que acompaa a Windows98 es ya un ejecutable en formato .EXE de 21 KB. [2] En realidad DEBUG es una utilidad de enorme potencia que requerira todo un libro para ella sola. Puede encontrarse una amplia descripcin de esta herramienta en el libro de Paul Somerson "PC Magazine: DOS Powers Tools". [3] Desgraciadamente no hay una convencin estndar sobre la colocacin de los datos en la BIOS, de forma que cada fabricante sigue sus propias reglas y es imposible por tanto, utilizarla para cualquier tipo de identificacin del sistema. [4] En palabras del mencionado Paul Somerson: "Desgraciadamente, debido a que DEBUG es un programa tan increblemente potente, tambin es increblemente peligroso".... "Hay un dicho que afirma que 'El software no puede destruir el hardware'. Desgraciadamente esto no es cierto. Adems de enviar mecanismos sensibles de la unidad de disco a tierra de nadie, es posible hacer saltar monitores o transformadores. Repito, si sigue al pie de la letra las instrucciones y hace caso a todos los avisos, todo ir bien." [5] Recuerde que la imagen de un ejecutable .exe cargado en memoria es distinta de su imagen en disco. Solo en los ejecutables .com la imagen en disco es una imagen exacta de su disposicin en memoria. [6] Es evidente que un pequeo error de nmero en este parmetro puede acarrear consecuencias nefastas. Por ejemplo, si cree que est "jugando" con el disquete e inadvertidamente se dirige al disco duro!! (relea la nota [4]).

Vous aimerez peut-être aussi