P. 1
Trabajo rio Sistemas de Computacion Debug

Trabajo rio Sistemas de Computacion Debug

|Views: 25|Likes:

More info:

Published by: Marco Antonio Romero on Oct 24, 2011
Copyright:Attribution Non-commercial

Availability:

Read on Scribd mobile: iPhone, iPad and Android.
download as DOC, PDF, TXT or read online from Scribd
See more
See less

10/24/2011

pdf

text

original

Universidad Nacional de Córdoba Facultad de Ciencias Exactas, Físicas y Naturales

SISTEMAS DE COMPUTACION
Trabajo Recuperatorio Instructivo y Uso de DEBUG

Alumno: Romero, Marco Antonio Profesora: Ing. Silvia Arias

I.E.

Año 2011

Debug nos presenta el contenido actual del registro y la posibilidad de ingresar un nuevo valor para sustituirlo. el código de las instrucciones. saltar sobre procedimientos. . nos permite encontrarlo hoy en cualquier máquina DOS o Windows. Usando DEBUG es posible observar el comportamiento de las instrucciones. Recuérdese que los registros de esta arquitectura son un subconjunto elemental de aquellos presentes en modelos más modernos de la familia '86. S=0. los contenidos de la memoria. I=1. para editar el contenido de CX. pero el hecho que desde el principio haya sido provisto con el sistema operativo. Se puede especificar la dirección a partir de la que se desea transferir datos o bien usar el vector por defecto DS:DX. es posible modificar su contenido. además permite ensamblar código elemental usando los mnemotécnicos del 8086. y usando el comando R (mostrar registros) nos mostrará algo similar a esto: AX=0000 BX=0000 CX=0000 DX=0000 SP=0000 BP=0000 SI=0000 DI=0000 DS=1332 ES=1332 SS=1332 CS=1332 IP=0100 NV UP EI PL NZ NA PO NC 1332:0100 C3 RET . Arrancando desde una ventana DOS. La cantidad de bytes transferida en cada operación es el contenido de BX:CX. Los comandos L y W se utilizan para leer y escribir en archivos de disco. Incluso es posible correr programas cargados en memoria utilizando breakpoints elementales.USO DE DEBUG Posiblemente sea el debug el depurador más rudimentario que existe. Esto muestra el contenido de los registros del procesador incluyendo varias banderas: en el ejemplo. Z=0. Muchas tareas elementales pueden realizarse sin otra ayuda que el Debug y por eso vamos a ver algunos comandos básicos. y en el mismo orden tenemos: V=0. la forma cómo éstas afectan a las banderas. Con el sistema operativo DOS (MS-DOS = Microsoft Disk Operating System) se incluye un programa para observar el comportamiento de los registros del CPU 80386. P=0 y C=0 Si ponemos después de la R el nombre de un registro. D=0. Previamente es necesario darle un nombre al archivo con el comando N. AC=0. ejecutar paso a paso. Por ejemplo. hay que poner el comando RCX. editar programas en hexa y muchas más cosas.

el contenido de la memoria es arbitrario. El lector . b) Cuando se invoca (como en el ejemplo) sin argumentos. obsérvese lo siguiente: a) DEBUG opera bajo DOS.Todos los comandos de DEBUG se invocan usando una sola letra y son los siguientes: 01) A (assemble) 02) C (compare) 03) D (dump) 04) E (enter) 05) F (fill) 06) G (go) 07) H (aritmética hexadecimal) 08) I (input) 09) L (load) 10) M (move) 11) N (name) 12) O (output) 13) Q (quit) 14) R (register) 15) S (search) 16) T (trace) 17) U (unassemble) 18) W (write) En particular. En las siguientes secciones de hace un breve resumen de los comandos de DEBUG.

Interesado en detalles puede consultar.2. 1. SS:). ASSEMBLE (A) El comando A se usa para introducir mnemotécnicos de ensamblador y que éstos se traduzcan directamente a lenguaje de máquina en memoria. <dirección> es el inicio de otro bloque. 1. La sintaxis es: C <bloque> <dirección> <bloque> es la dirección de inicio y fin de un bloque o. DS:. 1. QUE Corporation. 1987. por ejemplo.1. La sintaxis es: . ENTER (E) Este comando permite cambiar los contenidos de localidades específicas de memoria. La 1a es la dirección de inicio de despliegue. Una excepción es que DEBUG no puede diferenciar entre NEAR y FAR returns. Se presupone que la longitud de ambos bloques es la misma. "USING ASSEMBLY LANGUAGE" de Allen L. DUMP (D) Este comando despliega el contenido de una serie de localidades de memoriaLa sintaxis es: D <dirección1> <dirección2> Ambas direcciones son opcionales. la 2a es la dirección de fin.3. COMPARE (C) Este comando compara y reporta diferencias entre los contenidos de dos bloques de memoria. si se preceden con "L". asume que RET es "near" y RETF es "far".4. Wyatt. 1. incluyendo los especificadores de "override" de segmento (CS:. la dirección de inicio y la longitud del bloque. ES:. La sintaxis es: A <dirección> Prácticamente cualquier mnemotécnico es soportado por DEBUG.

La sintaxis es: F <bloque> <valor de relleno> <bloque> es la dirección de inicio y final o .E <dirección> <cambios> <dirección> es el inicio de los cambios y <cambios> es una lista opcional de los cambios deseados. Cuando no se especifica <cambios> se entra en un modo especial en el que DEBUG despliega los valores de <dirección>. GO (G) Este comando ejecuta el código en memoria. la serie se repite hasta llenar el bloque. Por ejemplo. permite ejecutar el código cargado en memoria.6.5. Los cambios pueden ser especificados en la línea de comandos en cualquier combinación de números hexadecimales o caracteres ASCII. También permite establecer puntos de quiebre (breakpoints) que son direcciones en las que se detiene la ejecución del programa. cualquiera de las siguientes dos líneas llena (con 0s) el bloque DS:00FF: F DS:0000 DS:00FF 0 F DS:0000 LFF 0 1. la dirección de inicio y la longitud del bloque. Si <valor de relleno> representa menor bytes que los que se necesitan para llenar el bloque. Si se activa la barra espaciadora DEBUG pasa a la siguiente localidad. <valor de relleno> es(son) el(los) valor(es) con los que debe de llenarse el bloque. Si se está depurando un programa. los caracteres ASCII deben estar entre comillas simples o dobles. FILL (F) Este comando llena un bloque de memoria con un valor específico o una serie de valores. La sintaxis es: . Entonces es posible teclear nuevos valores que reemplacen a los que se muestran. si se preceden con "L". Si se teclea "-" DEBUG regresa a la localidad anterior. 1. Por ejemplo: E 100 'Buenas Tardes' Establece el patrón "42 75 65 6E 61 73 20 54 61 72 64 65 73" en memoria a partir de la localidad 100H.

INPUT (I) Este comando "jala" un byte de un puerto. La sintaxis es: H <valor1> <valor2> Como resultado de lo anterior.G =<inicio> <quiebre1> <quiebre2> . 2=C. Se lee el dato y se despliega en pantalla. . 1. Aritmética Hexadecimal (H) Este comando ejecuta restas y suma hexadecimales. Si DEBUG llega a CC todos los puntos de quiebre son restituidos. Para lograr los quiebres. No se pueden leer más de 80H (128) sectores. DEBUG reemplaza el código en las direcciones de quiebre por el valor hexadecimal CC. Si no se suministra la combinación <numdisco> <sectorini> <numsector> DEBUG presume que se desea leer un archivo. que es el código de interrupción. 1. etc.. <numsector> es la cantidad de sectores a leer.9. 1. Go inicia con la dirección contenida en CS:IP. La sintaxis es: L <buffer> <numdisco> <sectorini> <numsector> <buffer> es la dirección en donde se carga la información.. En este caso <buffer> es opcional. Debe usarse el comando N (ver más adelante) para especificar el archivo a leer. los registros se despliegan (como con el comando R [véase adelante]) y se usan para la ejecución. La sintaxis es: I <puerto> <puerto> es la dirección del puerto a leer. <sectorini> es el sector de disco absoluto (en hexadecimal) a leer. <quiebre1> hasta <quiebre10> son direcciones opcionales de paro del programa. <numdisco> es el número (opcional) del disco de donde se leerá la información (0=A. DEBUG regresa dos valores: la suma y la resta de los argumentos en hexa. <quiebre10> <inicio> es la dirección de inicio de ejecución. LOAD (L) Este comando se usa para cargar un archivo o sectores de disco a memoria.7. Si no se especifica <inicio>. 1=B.). Éste se carga en CS:0100.8.

IP y PC son sinónimos. <dirección> es la dirección destino. DI.).5. SP. SI.14. 1. <nomarch2> es la especificación de archivo que será colocada en CS:006C. 1.1. DX. NAME (N) Este comando se usa para especificar el nombre del archivo usado por los comandos LOAD y WRITE. La sintaxis es: N <nomarch1< <nomarch2> <nomarch1> es la especificación de archivo completa que será "parseada" y colocada en el bloque de control en CS:005C. CS. BX.13. precedida por el número de bytes tecleados. 1. MOVE (M) Este comando mueve un bloque de memoria de una localidad a otra. PC o F.12. SS. La expresión tal cual se tecleó se almacena en CS:0081. BP. . DS.10. La sintaxis es: M <bloque> <dirección> <bloque> es como arriba (ver 2. OUTPUT (O) Este comando pone un byte en el puerto especificado. El bloque de origen y la dirección destino pueden traslaparse. La sintaxis es: O <puerto< <valor> <valor> es el byte hexadecimal a escribir en <puerto>. La sintaxis es: R <registro> <registro> es el nombre opcional y puede ser alguno de los siguientes: AX. CX.11.1. 1. REGISTER (R) Este comando despliega los registros del CPU y los valores de las banderas. QUIT (Q) Este comando se usa para salir de DEBUG. IP. ES.

WRITE (W) Este comando se usa para escribir un archivo a sectores individuales de disco a disco. La sintaxis es: T =<inicio> <cuenta> <inicio> es la dirección de inicio de la traza <cuenta> es el número de instrucciones a trazar 1. la dirección de inicio y la longitud del área a desensamblar. La sintaxis es: W <buffer> <numdisco> <sectorini> <numsector> <buffer> es la dirección de donde se carga la información. Si no se suministra la combinación <numdisco> <sectorini> <numsector> DEBUG presume que el inicio . 1=B. etc. La sintaxis es la siguiente: U <alcance> <alcance>.15. UNASSEMBLE (U) Este comando decodifica los valores de un grupo de localidades de memoria a mnemotécnicos de 8086. es ya sea un par de direcciones de inicio y fin o.17. TRACE (T) Este comando permite ejecución paso-a-paso de las instrucciones de máquina. 1. Después de cada instrucción se muestra el estado de los registros. <numdisco> es el número (opcional) del disco en donde se escribirá la información (0=A.18.). <numsector> es la cantidad de sectores a leer. que es opcional. La sintaxis es: S <bloque> <valor_a_buscar> <bloque> se define como antes (ver la sección 1_1).16. si se precede con "L". <valor_a_buscar> es(son) el(los) valor(es) que deseamos buscar en el bloque. No se pueden escribir más de 80H (128) sectores. 2=C.1. <sectorini> es el sector de disco absoluto (en hexadecimal) en donde empieza la escritura. 1. SEARCH (S) Este comando permite buscar en un bloque de memoria una secuencia específica de valores.

4) Aunque nada se ha hablado de la INT 20. debemos leer el tutorial de +gthorne (Greythorne the Technomancer). nos va devolviendo la dirección de almacenamiento de la próxima instrucción que escribiremos. Debe usarse el comando N (ver arriba) para especificar el archivo a escribir. En este caso <buffer> es opcional. que será nuestro paso siguiente. de manera que nuestro programa puede lucir así: a 100 1322:0100 1322:0103 1322:0106 1322:0109 1322:010D 1322:010F Al apretar "enter" una vez más.finalizar y salir a Debug .2000 <cr> W <cr> PROGRAMA A MODO DE EJEMPLO: Usaremos el Debug para ensamblar un programa que realice algo tan útil como dejar en alguna parte de la memoria el nombre de nuestra escuela ECCE.cargamos BX con "CE" en ASCII . Nos proponemos hacer que ECCE sea escrito en memoria.cargamos el registro AX con el dato 4543 (EC en ASCII) . Sabemos que los códigos ASCII son E=45h y C=43h. 3) Las tres primeras instrucciones MOV ocuparon de memoria de programa 3 bytes cada una. Para sacar algo a pantalla. Debug nos devuelve su prompt "-" y ya estamos listos para nuestro próximo comando. pero la cuarta ocupó 4 bytes y la INT 20 sólo ocupó 2 bytes. Antes de escribir BX:CX debe ajustarse al número de bytes que desean grabarse.de archivo es CS:100. W no puede escribir a archivos con la extensión EXE o HEX.ax mov [202]. 5) Cuando hacemos mov ax.4543 mov bx.idem para BX. son hexadecimales.ponemos AX en la dirección de memoria 200 . 2) A medida que vamos ingresando el programa. es lo que por el momento usaremos para terminar el programa. en el offset 200h de nuestro segmento de datos DS.bx int 20 . sean direcciones o datos.4345 mov [200]. pero en la 202 (AX ocupó la 200 y 201) . Podemos ver algunas curiosidades del listado anterior: 1) Debug asume que los números que le damos. Por ahora sólo queremos practicar de manera que abramos una ventana DOS y escribamos DEBUG (enter). Ejemplo: N <nomarchivo> <cr> BX:CX <--.

Debug compiló nuestro programa ingresado en assembly y produjo ese código binario con representación hexadecimal para que el Pentium lo interprete.4543 MOV BX.4345 MOV [200].referencia al contenido de una posición de memoria. pero las líneas que siguen hacia abajo son alguna cosa que estaba en memoria. El prefijo "word ptr" es para que el procesador sepa que lo que moveremos a 200 es una word y no un byte o double-word. Luego cargamos "CE" en BX y lo dejamos en la 202. Es muy importante saber distinguir entre la dirección y el valor almacenado en esa dirección de memoria. . sin importar cómo escribimos nuestro código) 1322:0100 1322:0103 1322:0106 1322:0109 1322:010D B84345 BB4543 A30002 891E0202 CD20 MOV AX.4543 . en una columna entre la dirección y el listado en lenguaje assembly puso unos números hexadecimales. El listado es más largo. encerramos la dirección entre corchetes []. de modo que no ganamos espacio poniéndola en lugar del más elíptico procedimiento de cargar AX y con éste escribir en 200. Tanto AX como BX han sido meros vehículos para cargar la memoria con datos y sólo a los efectos didácticos porque también está permitido : MOV word ptr [200]. Nuestra lógica es muy simple: cargamos el ASCII "EC" en AX y lo dejamos en la dirección 200.AX MOV [202]. Son los códigos de operación (opcodes) que es lo que en definitiva se almacena en memoria y lo que nuestro Pentium debe interpretar y ejecutar. ya que Debug desensambla por defecto los 20h primeros bytes desde la dirección indicada (o desde la que esté apuntando). cargar la word de memoria 200 directamente con el dato 4543 Esta instrucción ocupa 6 bytes. salvo que las instalaciones de software sean idénticas y en ambas estén corriendo previamente al DEBUG los mismos programas. Veamos cómo se ve nuestro programa usando el comando desensamblar: -u 100 (desensamble a partir de la CS:100) (Nótese que Debug listará usando sólo mayúsculas. y en nuestro programa sólo hemos usado 0Fh bytes (15 en decimal). Observemos: Debug no deja de sorprendernos.BX INT 20 NOTA: el valor de 1322 (el contenido del registro CS) es válido para la PC donde se escribió este ensayo. Por lo general los valores no coinciden de una a otra PC.

Verifiquemos con el comando D 200: . Esperábamos los hexa 45. Veamos si nuestras siglas brillan en las posiciones 200 a 203 con el comando D 200. Para ello usamos el comando D 200. Usemos al Debug para depurar. Hemos guardado AX en la dirección 200 y por lo tanto debería haber un 4543 ("EC" en ASCII) en las direcciones 200 y 201. puede que en otra PC tenga otro valor. Para nuestro caso CS vale 1322. Corramos el programa con el comando G. pero como ya se ha dicho. Con el comando R nos aseguramos que CS:IP esté apuntando al inicio de nuestro programa (o sea a CS:0100). Para estar seguros.45 a partir de la 200 (miremos además en la columna ASCII del Debug. Debug nos debe informar: El programa ha finalizado con normalidad. Nos debe decir que IP apunta a 0100: 1322:0100 B84345 MOV AX. Repitamos el comando F 200 23F 00 para dejar nuevamente en cero la memoria y ejecutemos nuestro programa paso a paso. escribamos nuevamente el comando D 200. Debemos ver las cuatro primeras filas del listado con los datos en 00.AX Ejecutemos el comando D 200 para ver qué hay en la memoria: hasta ahora 00 de la dirección 200 a la 203.BX es la próxima instrucción. Ejecutemos con T: 1322:0106 A30002 MOV [200]. Hagamos otro T. vamos a llenar este espacio con ceros usando el comando . Lo relevante es: AX=4543 e IP=0103 1322:0103 BB4543 MOV BX. que nos muestra la basura que hay en nuestra RAM desde DS:0200 hasta DS:027F.4543 -T (comando para ejecutar una sola instrucción). porque hasta aquí sólo hemos cargado los registros AX y BX.F 200 23F 00 con lo que le indicamos a Debug que debe llenar el bloque de memoria que comienza en 200 y termina en 23F con "00". tenemos que ver qué hay en la posición de memoria 200. Todo ok.43.4345 es la próxima instrucción.43. 1322:0109 891E0202 MOV [0202]. Qué habrá pasado? Será que hemos escrito BX en 200 y AX en 202?.Antes de correr el fabuloso programa que hemos escrito. Primero el comando R. en donde claramente nos dice CEEC) y están al revés. Bien! todo resulto correcto. Estamos listos para correr nuestro programita. Como deseamos leer claramente nuestro nombre ECCE.

.... CE. ahí fue donde nos equivocamos!) desde la porción más baja hacia la más alta. y lo mismo para BX: a 100 1322:0100 MOV AX.. Ahora debemos modificar el registro IP.. Y el procesador hace algo sumamente lógico. debemos rescribir nuestro programa para que en AL se almacene la primera letra ("E") y en AH la segunda ("C"). QUE PASO???? Está al revés.. en la realidad lo debemos asumir como: En AL tengo un 43 ("C") y en AH un 45 ("E").... a la porción más baja del registro (AL) la almacena en la dirección de memoria más baja (200) y a la porción más alta del registro (AH) la almacena en la dirección de memoria más alta (201).4345 1322:0103 MOV BX. Todo parece bien pero no funciona? Pero está bien tal como lo hizo Intel... .. Por lo tanto.....1322:0200 43 45 00 00 . debemos acostumbrarnos a leer los registro (y a cargarlos.. Resulta que lo que leemos en AX como "EC". Si leemos la memoria en sentido de direcciones ascendentes.... que nos quedó apuntando a la mitad del programa: RIP (enter) nuestro comando IP 0109 respuesta de Debug :100 (enter) este valor lo ingresamos nosotros para decirle que queremos a IP=0100 Ejecutamos el programa nuevamente con G y examinamos la memoria con D 200 para ver nuestro sigla ECCE ya en su lugar y en el orden debido. Tengo "CE" en lugar de "EC"..4543 (enter) nuevamente para salir del comando A.

You're Reading a Free Preview

Descarga
scribd
/*********** DO NOT ALTER ANYTHING BELOW THIS LINE ! ************/ var s_code=s.t();if(s_code)document.write(s_code)//-->