Documentos de Académico
Documentos de Profesional
Documentos de Cultura
com
(Essential debug.com)
Propsito:
Debug.exe es un programa - depuradora de bajo nivel para uso general en el entorno de MS-DOS.
Debug.exe tiene soporte para el lenguaje de maquina (8086).
Funciones que realiza debug.exe:
Memoria y entrada salida:
- imprimir el contenido de la memoria como HEX-ASCII.
- cambiar el contenido de la memoria (entrada HEX o ASCII).
- ver el contenido de un puerto de entrada.
- emitir byte/word a un puerto de salida.
Cdigo esttico:
- entrada como mnemnicas (micro ensamblador de lenguaje de maquina)
- imprimir el contenido de la memoria como mnemnicas de 8086.
Ejecucin de programas:
- ejecucin de cdigo a partir de una direccin con hasta 16 puntos de interrupcin (sustituyendo los
puntos de interrupcin con INT 3 solo RAM).
- ejecucin de cdigo paso a paso (utilizando el bandera (FLAG)T del procesador RAM/ROM).
- Entrada del contenido de los registros del procesador.
- Impresin de los registros del procesador.
Otras funciones (no se consideran en el manual)
- leer/escribir en los discos (sector o fichero).
- Manejo de los registros de co-procesador
- .
Se consideran los comandos en base de ejemplos. El manual ni es completo ni es la manera mas eficaz de
hacer las cosas con DEBUG. Esto es solo un sub-conjunto mnimo de comandos de DEBUG, que nos
permite de utilizar DEBUG.
Ejemplo A escribir y comprobar un programa que imprime el contenido del puerto 378h como numero
hexadecimal. Las entradas del operador son en negrita. Los comentarios son en latina (no les consideras
como entrada):
C:\>debug
Como pedir ayuda de DEBUG entrar ?.
-a100
Tal como es mas cmodo primero convertir AL en dgitos y despus imprimir la cadena (con int 21, ah=9)
corregimos el programa. Para entrar de nuevo cdigo de maquina a partir de la direccin 104 tenemos
que salir del rgimen de entrada de cdigo.
106E:0108
Salimos del ensamblador con entrada de una lnea vaca.
-a104
Ensamblador de nuevo a partir de la direccin 104 (mirar arriba)
106E:0104 mov di,200
106E:0107 call 140
106E:0112 2BC6
muy distinto
106E:0114 8BC8
106E:0116 E87BF4
106E:0119 83F97F
106E:011C 3400
106E:011E 5D
106E:011F 1000
-u140
106E:0140 FC
106E:0141 E80000
106E:0144 D0C0
106E:0146 D0C0
106E:0148 D0C0
106E:014A D0C0
106E:014C 50
106E:014D 240F
106E:014F 3C0A
106E:0151 7602
106E:0153 0406
106E:0155 040A
106E:0157 AA
106E:0158 58
106E:0159 C3
106E:015A 215F5E
SUB
AX,SI
MOV
CALL
CMP
XOR
POP
ADC
CX,AX
F594
CX,+7F
AL,00
BP
[BX+SI],AL
CLD
CALL
ROL
ROL
ROL
ROL
PUSH
AND
CMP
JBE
ADD
ADD
STOSB
POP
RET
AND
0144
AL,1
AL,1
AL,1
AL,1
AX
AL,0F
AL,0A
0155
AL,06
AL,0A
AX
[BX+5E],BX
; basura
(como antes)
-a153
106E:0153 add al,7
-u140 (por sea caso).
. (con instruccin correcta).
-r
; veamos donde estamos
AX=0041 BX=0000 CX=0000 DX=0378 SP=FFE2 BP=0000 SI=0000 DI=0201
DS=106E ES=106E SS=106E CS=106E IP=0158 NV UP EI PL NZ NA PE NC
106E:0158 58
POP AX
; Seguimos.
-t
AX=005B BX=0000 CX=0000 DX=0378 SP=FFE4 BP=0000 SI=0000 DI=0201
DS=106E ES=106E SS=106E CS=106E IP=0159 NV UP EI PL NZ NA PE NC
106E:0159 C3
RET
-t
AX=005B BX=0000 CX=0000 DX=0378 SP=FFE6 BP=0000 SI=0000 DI=0201
DS=106E ES=106E SS=106E CS=106E IP=0144 NV UP EI PL NZ NA PE NC
106E:0144 D0C0
ROL AL,1
; Esto ya lo hemos visto. Andamos un poco mas deprisa.
-u
106E:0144 D0C0
ROL
AL,1
106E:0146 D0C0
ROL
AL,1
106E:0148 D0C0
ROL
AL,1
106E:014A D0C0
ROL
AL,1
106E:014C 50
PUSH
AX
106E:014D 240F
AND
AL,0F
106E:014F 3C0A
CMP
AL,0A
106E:0151 7602
JBE
0155
106E:0153 0407
ADD
AL,07
106E:0155 0430
ADD
AL,30
106E:0157 AA
STOSB
106E:0158 58
POP
AX
106E:0159 C3
RET
; Notar que se desensambla (u de un-assembly) desde la posicin actual (CS:IP).
Vamos hasta RET. En AL es:200..201 podemos ver los caracteres que se han escrito.
-g 159 ; g de GO mas el punto de control (breakpoint) 159. El DEBUG sustituye el contenido de CS:159
con INT 3 y despus ejecuta el programa desde la direccin actual (CS:IP). Notar que la parada del
programa no se garantiza (si el programa no ejecuta la instruccin de CS:159 no hay garanta que va a
parar. Adems 159 puede ser incluso en la mita de una instruccin.
AX=00B5 BX=0000 CX=0000 DX=0378 SP=FFE6 BP=0000 SI=0000 DI=0202
DS=106E ES=106E SS=106E CS=106E IP=0159 NV UP EI PL NZ NA PE NC
106E:0159 C3
RET
-d200 201
; Utilizamos la forma de direccin 200 hasta direccin 201.
106E:0200 41 35
A5
Menos mal el segundo carcter es 5 de B5 es correcto.
-t
AX=00B5 BX=0000 CX=0000 DX=0378 SP=FFE8 BP=0000 SI=0000 DI=0202
DS=106E ES=106E SS=106E CS=106E IP=010A NV UP EI PL NZ NA PE NC
106E:010A BA0002
MOV DX,0200
-t
AX=00B5 BX=0000 CX=0000 DX=0200 SP=FFE8 BP=0000 SI=0000 DI=0202
DS=106E ES=106E SS=106E CS=106E IP=010D NV UP EI PL NZ NA PE NC
106E:010D B409
MOV AH,09
-t
AX=09B5 BX=0000 CX=0000 DX=0200 SP=FFE8 BP=0000 SI=0000 DI=0202
DS=106E ES=106E SS=106E CS=106E IP=010F NV UP EI PL NZ NA PE NC
106E:010F CD21
INT 21
; En este punto es necesario ver si todo esta correcto en la memoria DS:200.
-d200 ; Sin longitud el DEBUG nos imprime 80 bytes.
106E:0200
106E:0210
106E:0220
106E:0230
106E:0240
106E:0250
106E:0260
106E:0270
41
00
3B
D2
0B
D5
2F
D8
35
03
75
80
00
E2
E7
B0
D7
F1
F6
3E
E8
00
BB
FF
D7
E8
4E
43
59
74
40
86
C3
03
C3
04
00
F7
00
47
BE
00
1E
00
5F
1E
BA
18
BC
3C
52
75
5E
0E
01
A2
DB-8B
0D-C3
50-53
0D-F6
59-5B
1F-BE
00-33
18-00
4C
AC
51
06
58
D5
FF
C3
05
E8
56
21
5A
E2
CD
0E
8B
04
57
04
1F
E8
21
1F
74
F9
2E
FF
C3
98
1F
E8
09
75
8E
75
2E
02
72
D2
E8
04
1E
06
80
2E
0B
00
08
3C
FE
E8
3E
A1
8B
3D
A5.......L..t...
......<......u.<
;u.N..RPSQVW....
..>C..u...!..u..
...Y._^Y[XZ....>
...t............
/..@....3..!.r..
....G..........=
; ERRROOOORRR!! La cadena no termina con $. Si ejecutamos int 21 puede ocurrir cualquier cosa.
; Otro error escribimos en ES:DI pero imprimimos de DS:DI. Por suerte el DEBUG asigna el mismo
valor de todos los registros del segmento.
Cambiamos el contenido de la memoria. Aadimos CR LF y $.
-e202
106E:0202 0D.0d 0A.a
Despus de 0d tenemos de teclear espacio. Despus del ultimo byte tenemos de teclear salto de linea.
Entramos $ como smbolo:
-e204 $
Comprobamos
-d200
106E:0200 41 35 0D 0A 24 BE BC DB-8B 4C 05 8B 74 09 E8 08 A5..$....L..t...
.
Ahora esta bien.
-r ; donde estamos
AX=09B5 BX=0000 CX=0000 DX=0200 SP=FFE8 BP=0000 SI=0000 DI=0202
DS=106E ES=106E SS=106E CS=106E IP=010F NV UP EI PL NZ NA PE NC
106E:010F CD21
INT 21
Estamos antes de ejecutar INT 21h con AH=9 y DX=200. Tenemos que ejecutar esta instruccin pero no
nos interesa de entrar en DOS. Por esto ejecutamos INT 21 no con t pero con p. El comando p sustituye la
siguiente instruccin con INT 3 (que en este caso es tambin INT 3) y ejecuta el programa como si
entramos G.
-p
A5
AX=0924 BX=0000 CX=0000 DX=0200 SP=FFE8 BP=0000 SI=0000 DI=0202
DS=106E ES=106E SS=106E CS=106E IP=0111 NV UP EI PL NZ NA PE NC
106E:0111 CC
INT 3
Bien! El programa escribe A5 (despus de la lnea de p), como debe ser (casi, tal como tiene que escribir
B5).
Tal como hemos ayudando al programa a mano de conseguir su tarea, corregimos aadiendo un patch
en 180 (a partir de este momento no escribo los comandos U necesarios):
-a180
106E:0180 push ds
106E:0181 pop es
106E:0182 call 140
106E:0185 mov al,d
; el CR
106E:0187 stosb
106E:0188 mov al,a
; El LF
106E:018A stosb
106E:018B mov al,24
; El $. Podemos verlo en la memoria ES:204
106E:018D stosb
106E:018E ret
106E:018F
-a107
106E:0107 call 180
; entramos en el patch y no en 140
106E:010A
ponemos en puerto 378 el valor que vamos a escribir:
-o378 5D ; esto es equivalente al programa: MOV DX,378h // MOV al,5Dh // OUT dx,al
Comprobamos el contenido del puerto:
-i378 ; Esto es casi equivalente al nuestro programa
5D
; Correcto, tal como el puerto es un simple I/O buffer.
Ejecutamos
-g=100 107 ; esta parte ya la sabemos
Un poco mas despacio con la nueva parte.
AX=095D BX=0000 CX=0000 DX=0378 SP=FFE2 BP=0000 SI=0000 DI=0200
DS=106E ES=106E SS=106E CS=106E IP=0107 NV UP DI PL NZ NA PE NC
106E:0107 E87600
CALL 0180
-t
AX=095D BX=0000 CX=0000 DX=0378 SP=FFE0 BP=0000 SI=0000 DI=0200
DS=106E ES=106E SS=106E CS=106E IP=0180 NV UP DI PL NZ NA PE NC
106E:0180 1E
PUSH DS
-t
AX=095D BX=0000 CX=0000 DX=0378 SP=FFDE BP=0000 SI=0000 DI=0200
DS=106E ES=106E SS=106E CS=106E IP=0181 NV UP DI PL NZ NA PE NC
106E:0181 07
POP ES
-t
AX=095D BX=0000 CX=0000 DX=0378 SP=FFE0 BP=0000 SI=0000 DI=0200
DS=106E ES=106E SS=106E CS=106E IP=0182 NV UP DI PL NZ NA PE NC
106E:0182 E8BBFF
CALL 0140
Con esto a toda marcha. Ya lo sabemos.
-p
AX=095D BX=0000 CX=0000 DX=0378 SP=FFE0 BP=0000 SI=0000 DI=0202
DS=106E ES=106E SS=106E CS=106E IP=0185 NV UP DI PL NZ NA PE NC
106E:0185 B00D
MOV AL,0D
-t
AX=090D BX=0000 CX=0000 DX=0378 SP=FFE0 BP=0000 SI=0000 DI=0202
DS=106E ES=106E SS=106E CS=106E IP=0187 NV UP DI PL NZ NA PE NC
106E:0187 AA
STOSB
-t
AX=090D BX=0000 CX=0000 DX=0378 SP=FFE0 BP=0000 SI=0000 DI=0203
DS=106E ES=106E SS=106E CS=106E IP=0188 NV UP DI PL NZ NA PE NC
106E:0188 B00A
MOV AL,0A
-t
AX=090A BX=0000 CX=0000 DX=0378 SP=FFE0 BP=0000 SI=0000 DI=0203
DS=106E ES=106E SS=106E CS=106E IP=018A NV UP DI PL NZ NA PE NC
106E:018A AA
STOSB
-t
AX=090A BX=0000 CX=0000 DX=0378 SP=FFE0 BP=0000 SI=0000 DI=0204
DS=106E ES=106E SS=106E CS=106E IP=018B NV UP DI PL NZ NA PE NC
106E:018B B024
MOV AL,24
-t
AX=0924 BX=0000 CX=0000 DX=0378 SP=FFE0 BP=0000 SI=0000 DI=0204
DS=106E ES=106E SS=106E CS=106E IP=018D NV UP DI PL NZ NA PE NC
106E:018D AA
STOSB
-t
AX=0924 BX=0000 CX=0000 DX=0378 SP=FFE0 BP=0000 SI=0000 DI=0205
DS=106E ES=106E SS=106E CS=106E IP=018E NV UP DI PL NZ NA PE NC
106E:018E C3
RET
-t
Comprobamos la memoria
-d200
106E:0200 35 44 0D 0A 24 BE BC DB-8B 4C 05 8B 74 09 E8 08 5D..$....L..t...
.
Y a toda marcha hasta el final.
-g
5D
AX=0924 BX=0000 CX=0000 DX=0200 SP=FFE2 BP=0000 SI=0000 DI=0205
DS=106E ES=106E SS=106E CS=106E IP=0111 NV UP DI PL NZ NA PE NC
106E:0111 CC
INT 3
Lo hemos conseguido. Lo nico malo de esta programa de DOS es que no termina correcto.
Arreglamos el problema:
-a111
106E:0111 int 20
Ahora ejecutamos desde el principio:
-g=100 ; ejecutamos desde direccin CS:100 sin paradas.
Salvamos el programa en el disco.