1.2 Limitaciones de DEBUG NOTAS SOBRE DEBUG

1 NOTAS SOBRE DEBUG CLASE INEL 4206: MICROPROCESADORES I Preparadas por Rogelio Palomera G. Verano 1997. Versión corregida, Febrero 2006 1. Generalid...
46 downloads 2 Views 112KB Size
1

NOTAS SOBRE DEBUG CLASE INEL 4206: MICROPROCESADORES I Preparadas por Rogelio Palomera G. Verano 1997. Versión corregida, Febrero 2006 1. Generalidades DEBUG es un programa provisto con DOS. Versiones más avanzadas de este programa son SYMDEB y CodeView (CV), los cuales se proveen junto con MASM (Micro-Soft Assembler). El nombre sugiere "debugger", que significa programa para corregir errores de programación en un código. Existen otros programas que cumplen la misma función, así como otros tipos de ensambladores 1.1 Ventajas de los programas depuraadores ("debuggers") a) examinar el contenido de la memoria y los registros; b) ejecutar instrucciones de un programa, ya sea en forma contínua o una a la vez, y verificar su ejecución (lo que permite identificar errores -de ahí el nombre- entre otras cosas). c) modificar directamente una o más instrucciones del programa sin necesidad de seguir todo el proceso de ensamblado. d) escribir instrucciones en lenguaje ensamblador (ensamblar) y ejecutarlas Esto permite estudiar el efecto de las instrucciones; e) desensamblar instrucciones, esto es, interpretar el contenido de memoria como instrucción de ensamblador. f) crear y cargar archivos

1.2 Limitaciones de DEBUG A) Toda expresión numérica es hexadecimal, con un máximo de cuatro cifras hexadecimales. Se escriben sin el sufijo H B) El ensamblador DEBUG no acepta variables ni símbolos en las instrucciones del ensamblador. C) Solamente trabaja en modo real, y existen algunos comandos de ensamblador que no pueden probarse en este DEBUG D) Solamente trabaja con registros de 16 y 8 bits, y no incluye al FS ni GS. Para trabajar con los registros de 32 bits, como EAX, EBX, etc. debe usarse el CodeView. 2. Usando DEBUG 2.1 Abriendo y saliendo de DEBUG. Help Para comenzar DEBUG, simplemente escriba el comando DEBUG y oprima ENTER. Se puede abrir desde cualquier directorio. C:\>DEBUG El "prompt" de DEBUG es el guión. Los comandos en DEBUG no se ejecutan mientras no se oprima la tecla ENTER. Cuando se abre DEBUG solo con el comando anterior, el programa inicializa automáticamente los registros: Los segmentos de registro se inicializan en el primer lugar de memoria disponible después de cargar DEBUG, IP=0100, SP= FFEE y los demás registros a 0000. Se puede abrir DEBUG cargándolo con un programa:

2

C:\> DEBUG > Cuando se invoca al programa file.exe, éste ocupa un lugar en la memoria y los registros se inicializan de la manera siguiente: * el par de registros BX-CX indica el número de bytes que contiene el programa. ** CS y SS, y los indicadores IP y SP se inicializan de acuerdo al inicio de los segmentos correspondientes. ** IP = 0000 si no se uso la directiva ORG en el programa fuente.

register R [register] search S range list trace T [=address] [value] unassemble U [range] write W [address] [drive] [firstsector] [number] allocate expanded memory XA [#pages] deallocate expanded memory XD [handle] map expanded memory pages XM [Lpage] [Ppage] [handle display expanded memory status XS Los corchetes [ ] indican que el parámetro pedido es opcional. En esta práctica no usamos todos los comandos. 2.2 Parámetros Importantes:

Se puede iniciar usando un archivo que contiene comandos de DEBUG: C:\> DEBUG < -

file.DBG

Los parámetros comunes, opcionales o no, son: address: Una dirección puede ser

En este caso, los comandos incluidos en el archivo se ejecutan inmediatamente.

a) un offset – 1 a 4 cifras hex - ( ejm 100). , DS es el segmento implícito para los comandos E, D y F. CS para los comandos A, G, P, T, W, U

El comando "?" genera una lista de los comandos de DEBUG :

b) un segmento y un offset ( 0230: 100) ;

-? assemble compare dump enter fill go hex input load [number] move name output proceed quit

A C D E F G H I L

[address] range address [range] address [list] range list [=address] [addresses] value1 value2 port [address] [drive] [firstsector]

M N O P Q

range address [pathname] [arglist] port byte [=address] [number]

c) un registro de segmento y un offset (CS: 100) range: bloque de direcciones que empieza en un “address” determinado. El rango se especificar como a) address1 - address2 (address2 solamente offset ya que el segmento es el mismo que address1) b) address L > El el segundo caso, se indica en hexadecimal el número de bytes que abarca el rango.

3

2.3 Examinando y modificando memoria y registros. 2.3.1 Registros: El comando R permite examinar y modificar el contenido de los registros. Con el comando R solamente, aparece una lista de los registros y su contenido. -R AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=2D14 ES=2D14 SS=2D14 CS=2D14 IP=0100 NV UP EI PL NZ NA PO NC 2D14:0100 0F DB 0F El “Flag Register” se muestra como NV UP EI PL NZ NA PO NC La última línea muestra: 1. la dirección de la siguiente instrucción (2D14:0100); 2. el lenguaje máquina de la instrucción (0F ) y 3. el lenguaje mnemónico de la instrucción ( DB 0F). Observe que el offset de la dirección de la siguiente instrucción está dado por IP Como los registros se inicializaron, las banderas están a "0" (cleared), a excepción de la bandera de interrupción (EI = "1", interrupt enabled). La lectura de las banderas se muestra en la tabla siguiente. La bandera T (trap) no se incluye, ya que ésta se usa solamente para correr programas paso a paso. Bandera

= 1 (set)

= 0 (cleared)

Carry (C) 1: yes; 0: no

CY

NC

Parity (P) (Even/Odd)

PE

PO

Auxiliary half carry (A) (yes/no)

AC

NA

Zero (Z)

ZR

NZ

Sign (S) (Negative/Positive)

NG

PL

Interrupt (I) (Enable/disable)

EI

DI

Direction (D) (Decrement/increm ent)

DN

UP

Overflow (O) (yes/no)

OV

NV

(Yes/ No)

Para modificar el contenido de un registro, se invoca el comando R seguido del registro que se desea modificar . DEBUG responde indicando el valor actual del registro y en la línea siguiente dos puntos (:), después de lo cual se introduce el nuevo valor deseado. Ejemplo: -R DS DS 2D14 :2D24 -R

4 AX=0000 BX=0000 BP=0000 SI=0000 DS=2D24 ES=2D14 NV UP EI PL NZ NA 2D14:0100 0F

CX=0000 DX=0000 DI=0000 SS=2D14 CS=2D14 PO NC DB 0F

SP=FFEE

2D14:0100

IP=0100

B2) Escribiendo inmediatamente después de la dirección la lista desead de bytes (la lista puede escribirse numéricamente como números o como ASCII:

2.3.2 Memoria Para trabajar con la memoria se usan tres comandos: E, D y F. En estos tres comandos debemos especificar una dirección o un rango. En el comando D éstos son opcionales. 2.3.2.1 Comando E: Este comando nos permite examinar y/o modificar contenidos de memoria. A) Examinando: El comando E seguido de la dirección nos muestra el contenido de la memoria en esa dirección, seguida de un punto. Oprimiendo la barra de espacio se muestra la siguiente direccion, y asi sucesivamente hasta que se aprieta "Enter" o "Return". En el siguiente ejemplo, se ve que el contenido de memoria con dirección DS:0100 es el byte 0E. -E 100 2D14:0100

0E.

0E.

00.

B9.

8A.

B) Modificando:Para modificar uno o más lugares de memoria hay dos formas: B1) Escribiendo inmediatamente después del punto el nuevo byte deseado. (En el ejemplo, las negritas): -E 100

38.40

98.37

0A.0B

90 40 37 B

-E 200 'ABC' -E 200 2D14:0200 41.

42.

43.

2.3.2.2 Comando D: Este comando permite ver bloques de memoria, y muestra aquellos lugares con código ASCII, el cual se muestra a la derecha. . Tiene las modalidades siguientes: A) El comando D solo presenta 128 bytes, en grupos de 16, a partir de la última dirección utilizada con D. B) D presenta lo mismo que D, pero a partir de la dirección indicada. C) D > presenta solamente el bloque en el rango indicado.

Usando ahora la tecla de espacio, se ve el contenido de las direcciones 100 (0E), 101 (00), 102 (B9) y 103 (8A): -E 100 2D14:0100

-E 100

05.90

2.3.2. 3 Comando F . Permite "llenar" uno o más lugares en un rango dado, con bytes especificados en una lista. En los ejemplos usamos el comando D para verificar el resultado: -F 100 L 5 88 -D 100 L 5 2D14:0100 88 88 88 88 88 -F 200 L 5 A B C D E -D 200 L 5 2D14:0200 0A 0B 0C 0D 0E

5 2.3.3 Otros comandos con memoria:

B) El comando S localiza los bytes de la lista los bytes dentro del rango indicado. El comando devuelve las direcciones donde se encuentran los bytes indicados.

A) El comando M nos permite copiar en la dirección el bloque de memoria indicada en el .

-D 100 2D14:0100 0F 00 B9 8A FF F3 AE 47-61 2D14:0110 04 8B C6 F7 0A 0A D0 D3-48 2D14:0120 00 DB D2 D3 E0 03 F0 8E-DA 2D14:0130 C0 16 F8 8E C2 AC 8A D0-00 2D14:0140 C2 24 FE 3C B0 75 05 AC-F3 2D14:0150 75 6D 6D 13 A8 01 50 14-74 2D14:0160 8E FC 12 A8 33 D2 29 E3-13 2D14:0170 0B F8 83 FF FF 74 11 26-01 -M 100 105 120 -D 100 130 2D14:0100 0F 00 B9 8A FF F3 AE 47-61 2D14:0110 04 8B C6 F7 0A 0A D0 D3-48 2D14:0120 0F 00 B9 8A FF F3 F0 8E-DA 2D14:0130 C0 . -S 100 130 16 2D14:012B 2D14:012F -S 100 120 'Ga' 2D14:0107 3. Instrucciones en lenguaje ensamblador (mnemónicas) y corriendo programas. 3.1 Comandos U(nassembly) y A(ssembly) 3.1.1 Comando U [ Ejecutan la instrucción en la dirección indicada. Si solamente se da el offset, el segmento es CS. D) T=> > P=> > Ejecuta instrucciones a partir de la dirección indicada. En el ejemplo siguiente el objetivo es ir incrementando el registro AL tantas veces (16H = 22) como lo indica el contador. Primero escribimos las instrucciones. Al ejecutar la primera instrucción observe que CX = 0016. Cuando se ejecuta la segunda instrucción: AX=0001 , que es lo que se pidió. Como CX no es cero , se vuelve a la instrucción de incrementar. Luego hacemos un T 5 para ejecutar cinco instrucciones. Cuando usamos P, como hay un LOOP, se realiza todo el lazo y se sale de el. Observe que despues de P tenemos AX = 0016 y CX=0000. Observe también IP: C:\>debug -a 2D14:0100 mov cx, 16 2D14:0103 inc al 2D14:0105 loop 103 2D14:0107 -t AX=0000 BX=0000 BP=0000 SI=0000 DS=2D14 ES=2D14 NV UP EI PL NZ NA 2D14:0103 FEC0

CX=0016 DX=0000 DI=0000 SS=2D14 CS=2D14 PO NC INC AL

SP=FFEE IP=0103

AX=0001 BX=0000 BP=0000 SI=0000 DS=2D14 ES=2D14 NV UP EI PL NZ NA 2D14:0105 E2FC -t

CX=0016 DX=0000 SP=FFEE DI=0000 SS=2D14 CS=2D14 IP=0105 PO NC LOOP 0103

AX=0001 BX=0000 BP=0000 SI=0000 DS=2D14 ES=2D14 NV UP EI PL NZ NA 2D14:0103 FEC0

CX=0015 DX=0000 DI=0000 SS=2D14 CS=2D14 PO NC INC AL

SP=FFEE IP=0103

-t 5 AX=0002 BX=0000 BP=0000 SI=0000 DS=2D14 ES=2D14 NV UP EI PL NZ NA 2D14:0105 E2FC

CX=0015 DX=0000 SP=FFEA DI=0000 SS=2D14 CS=2D14 IP=0105 PE NC LOOP 0103

AX=0002 BX=0000 BP=0000 SI=0000 DS=2D14 ES=2D14 NV UP EI PL NZ NA 2D14:0103 FEC0

CX=0014 DX=0000 DI=0000 SS=2D14 CS=2D14 PE NC INC AL

AX=0003 BX=0000 BP=0000 SI=0000 DS=2D14 ES=2D14 NV UP EI PL NZ NA 2D14:0105 E2FC

CX=0014 DX=0000 SP=FFEA DI=0000 SS=2D14 CS=2D14 IP=0105 PO NC LOOP 0103

AX=0003 BX=0000 BP=0000 SI=0000 DS=2D14 ES=2D14 NV UP EI PL NZ NA 2D14:0103 FEC0

CX=0013 DX=0000 DI=0000 SS=2D14 CS=2D14 PO NC INC AL

SP=FFEA IP=0103

SP=FFEA IP=0103

9 AX=0004 BX=0000 BP=0000 SI=0000 DS=2D14 ES=2D14 NV UP EI PL NZ NA 2D14:0105 E2FC

CX=0013 DX=0000 SP=FFEA DI=0000 SS=2D14 CS=2D14 IP=0105 PE NC LOOP 0103

-p AX=0017 BX=0000 BP=0000 SI=0000 DS=2D14 ES=2D14 NV UP EI PL NZ NA 2D14:0107 47

CX=0000 DX=0000 DI=0000 SS=2D14 CS=2D14 PE NC INC DI

SP=FFEA IP=0107

4. Manejando archivos de datos, bytes o programas. 4.1 Salvando archivos Se pueden salvar bloques de memoria (que pueden corresponder a instrucciones, a datos o cualquier informacion particular) en archivos. El procedimiento es el siguiente: 1) Utilice el comando N con el siguiente formato: -N > Si se omite [path], el archivo se generará en el directorio desde el cual se invocó a DEBUG. Con este comando hemos llamado a un archivo file_name, o lo hemos creado si no existía. 2) Usando los dos registros BX y CX escriba el número de bytes que se van a guardar. La parte más significativa se escribe en BX ( Si son menos de 64Kbytes, BX=0000) 3) Comando W. En la sección 5 se muestra un ejemplo.

4.2 Cargando archivos Un archivo que consista de bytes, o que sea un programa ejecutable (.EXE o .COM), puede cargarse dentro de DEBUG para examinarse, usarse como datos, etc. Hay dos maneras de hacerlo. Cuando se carga un archivo, los registros BX-CX se inicializan con el número de bytes dentro del archivo (parte más significativa en BX). Si éste es un programa, IP se inicializa además con el offset de la primera instrucción. Se puede cargar el archivo o programa al invocar a DEBUG desde DOS: C:> DEBUG

PROGRAM.EXE

También se puede cargar desde DEBUG con los comandos Name y Load con el formato siguiente: : - N - L

PROGRAM.EXE

5. Ejemplo de un programa en lenguaje máquina y .COM Como primer ejemplo, vamos a escribir un programa directamente en lenguaje máquina usando DEBUG. Este programa será guardado como PRUEB1.COM. Es completamente ejecutable desde DOS (o Windows). 5.1 Programa en lenguaje máquina Paso 1: Inicie DEBUG e Paso 2: introduzca los siguientes 48 bytes en la dirección CS:100. Esta dirección se pone para asegurar que se empieza justamente en offset 100 dentro del segmento CS. Esta es una condición de los programas con extensión .COM. -E CS:100 BA 12 01 B4 09 CD 21 BA 24 01 84 09 CD 21 B4 4C

10 -E 43 -E 36

CS:110 CD 21 0D 0A 43 55 52 53 4F 20 4D 49 52 4F 20 CS:120 49 0D 0A 24 49 4E 45 4C 20 34 32 30 0D 0A 24

Paso 3: Indicar en los registros BX-CX el número de bytes que se desean guardar, es decir, la longitud del programa. Como 48D = 30H, cargamos CX con 30H, BX=00. Crear el archivo PRUEB1.COM y salvarlo (comando W). DEBUG responde indicando el número de bytes salvados. -R CX CX 0034 :30 -N PRUEB1.COM -W Writing 00030 bytes Ahora podemos correr el programa desde DOS: C:> PRUEB1 CURSO MICRO I INEL 4206 También lo podemos correr dentro de DEBUG con G=100. 5.2 Programa en Assembly: El mismo programa de la subsección anterior puede escribirse dentro de DEBUG con lenguaje ASSEMBLY de la siguiente manera (LAS NEGRITAS INDICAN LO QUE SE ENTRO, CON UN "RETURN" AL FINAL): -A 100 2D30:0100 2D30:0103 2D30:0105 2D30:0107

MOV MOV INT MOV

DX, 112 AH,09 21 DX,011C

2D30:010A MOV AH, 09 2D30:010C INT 21 2D30:010E MOV AH, 4C 2D30:0110 INT 21 2D30:0112 DB 0D, 0A, 'MICRO I','$' 2D30:011C DB 0D, 0A, 'INEL 4206' 2D30:0127 DB 0D, 0A, '$' 2D30:012A Puede usted verificar los comandos y el lenguaje máquina con U 100 110 Sin embargo, de 0112 en adelante se ven resultados diferentes a lo que introdujo. Esto se debe a la interpretación que da el comando U a los binarios. Usar entonces D CS:112 6. Archivos con comandos de DEBUG Usted puede escribir, usando un editor de texto, un archivo con los comandos que usaría en una sesión de DEBUG.. Los comandos incluyen el return , que aparece como una línea en blanco. Por ejemplo, supongamos que queremos cambiar el contenido de la memoria 400 a la memoria 402. Podemos probar las instrucciones MOV AL, [400] y MOV [402], AL usando DEBUG. Pero en lugar de abrir DEBUG y hacerlo, sigamos los pasos que se indican: Paso 1. Usando un editor de texto, escriba el siguiente archivo, con A 200 como primera línea ( Respete las líneas en blanco):

A 200 MOV AL, [400] MOV [402], AL INT 20 U 200 208 E 400 6C 0 0

11 G =200 E 402 Q Paso 2:. Salve el archivo como EJEM.DEB Paso 3:. En DOS escriba el comando C: >

DEBUG