DEBUG_note

@ debug
@ http://thestarman.pcministry.com/asm/debug/debug.htm
@ uselessstest
@ 2010.1.9

1: 以不带参数的方式启动debug时.
   即命令行下debug, 回车.
   (1) 占据64K的空闲空间, 作为一个段.
   (2) 段寄存器CS,DS,ES,SS都设置为该段的地址, CS=DS=ES=SS=segment location
   (3) 指令指针(IP)指向cs:0100, 堆栈指针指向ss:FFEE
   (4) 寄存器AX, BX, CX, DX, BP, SI, DI的值都为0

2: 以debug filename方式启动(file不为.exe)
   (1) 占据至少64KB的空闲空间, 具体情况取决于你的操作系统和可用内存空间大小.
   (2) CS=DS=ES=SS=Segment Location
   (3) 这时IP设为cs:0100, SP设为ss:FFFE(注意与上面的区别)
   (4) 文件大小的值设置到BX和CX中. 如文件大小为360,247B(57F37)那么BX=0005,
       CX=7F37.  其他寄存器都设为0.

3: 对于exe文件, 可以先讲exe文件后缀改成其他, 然后用debug调入.

4: 有一些代码或数据存于开始的256B, 这些由DEBUG来使用, 但当你把这个区域的数据全部
   清0后, debug依然可以正常工作.
   开头两字节为 "CD 20"表示指令: INT 20
   偏移量为50h和51h的两字节为"CD 21"表示指令 INT 21, 其后的字节"CB"表示指令RETF.

5: 每次运行DEBUG(在CMD.EXE里), 开头的256B都一样.显示的字符是NTVDM程序读取
   的AUTOEXEC.NT的后面一次读取一行, 存入命令行参数所保存的内存地区. 文件中最长
   的一行包括回车符(0D), 被更短的行覆盖, 最后填满偏移量82H到CEH的debug段.
   AUTOEXEC.NT里换行符(0AH)在这里不会出现,因为回车符在它们前面讲光标送到新一行的
   开头, 而且每一行的第一个空格符(20h)前的字符都不会出现, 这也是为什么REM没出现
   的原因.而且不管怎样偏移量81H的值总是0DH.
C:/>debug
-d 0 cf
0B20:0000  CD 20 FF 9F 00 9A EE FE-1D F0 4F 03 84 05 8A 03   . ........O.....
0B20:0010  84 05 17 03 84 05 25 04-01 01 01 00 02 FF FF FF   ......%.........
0B20:0020  FF FF FF FF FF FF FF FF-FF FF FF FF 28 05 4E 01   ............(.N.
0B20:0030  44 0A 14 00 18 00 20 0B-FF FF FF FF 00 00 00 00   D..... .........
0B20:0040  05 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B20:0050  CD 21 CB 00 00 00 00 00-00 00 00 00 00 20 20 20   .!...........
0B20:0060  20 20 20 20 20 20 20 20-00 00 00 00 00 20 20 20           .....
0B20:0070  20 20 20 20 20 20 20 20-00 00 00 00 00 00 00 00           ........
0B20:0080  00 0D 20 20 20 53 45 54-20 42 4C 41 53 54 45 52   ..   SET BLASTER
0B20:0090  3D 41 30 0D 64 64 72 65-73 73 2E 20 20 46 6F 72   =A0.ddress.  For
0B20:00A0  20 65 78 61 6D 70 6C 65-3A 0D 20 6F 6E 20 4E 54    example:. on NT
0B20:00B0  56 44 4D 2C 20 73 70 65-63 69 66 79 20 61 6E 20   VDM, specify an
0B20:00C0  69 6E 76 61 6C 69 64 0D-20 6F 6E 6C 79 2E 0D 00   invalid. only...
 

6: 删掉AUTOEXEC.NT后就不能运行DEBUG, 也不能运行其他16位程序, 因为这些都必须
   在NTVDM下运行. AUTOEXEC.NT文件位于C:/WINDOWS/SYSTEM32.

7: 命令

-?
assemble    A [address]
compare     C range address
dump        D [range]
enter       E address [list]
fill        F range list
go          G [=address] [addresses]
hex         H value1 value2   (Learn 2's Complement!)
input       I port
load        L [address] [drive] [firstsector] [number]
move        M range address
name        N [pathname] [arglist]
output      O port byte
proceed     P [=address] [number]
quit        Q . . . . . . . . . (Learn this first!)
register    R [register]
search      S range list
trace/step  T [=address] [number]
unassemble  U [range]
write       W [address] [drive] [firstsector] [number]

[]中的为可选参数.

adress: 表示内存地址(16进制), 可以只用一个偏移量, 也可以使用段地址:偏移量的形
        式,  前面的0可以忽略, 如1f表示CS:001F
range: 两个16进制表示的内存地址, 可以用偏移量表示,也可以使用段地址:偏移量的形式
       有些命令要求后一个地址只能使用偏移量的表示方法如-c命令.
list: 一连串的十六进制数,用空格分开. 或者是一些ASCII字符, 由单引号或双引号界定.

number: 数字,  DEBUG中所有的数字都是16进制形式的.

8: Quit : Q
   退出debug

9: Hex: H value1 value2
   计算value1和value2的和与差, value1和value2不能超过4位.
   例: H ffff 1
       0000  fffe
       相加就是按照16进制的加法, 但相减有时是按照二进制补码来算的. 比如
       H 1 FFFF
       0000 0002     因为ffff是-1的补码所有1-(-1)=2
       H 7FFF 8000
       FFFF FFFF
       因为7FFF+8000=FFFF, 7FFF-8000=7FFF+8000=FFFF.  8000的补码还是8000

10: Dump : D [range]
           D [address] [length]
    比如D C000:0010
        D 100 L30

11: Search: S [range] [list]
    返回list所在的段地址:偏移量

12: Compare: C [range] [address]
    比较range指定的块1和address指定的块2之间的区别, 若有区别则显示.
    由于range说明了块1的大小, 所以指定块2的时候只用给出起始地址.

13: Fill : F [range] [list]
    可以用于清空或填入一段内存区域, 填入的时候是连续循环填入的.
    例:
    f 100 12f 'buffer'
    d 100 12f
    可以看到100-12f这一段内存都填入了buffer字符.
    使用-f 100 ffff 0将指派的段全部清0

14: Enter: E [address] [list]
    用于直接将数据或指令(机器码)存入内存.
    例:
    -e 100 B4 09 BA 0B 01 CD 21 B4 00 CD 21
    -e 7EA 24
    -G =100
    会看到"Program terminated normally"显示出来, 数据24h表示的是"$"
    上述指令的代码为
    mov AH, 09
    MOV DX, 010B
    INT 21H
    MOV AH, 00
    INT 21H
    于是我们可以用同样的方法来显示255个字符从00H~FFH.
    e 100 B4 09 BA 0B 01 CD 21 B4 00 CD 21 0D 0A 0D 0A 00 01 02
                                           换行与回车 |
    e 112 03 04 05 06 07 08 09 20 0B 0C 20 0E 0F 10 11 12 13 14
                               --       --
                               回车和换行用空格代替
    E 124 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 20 25 26
                                                       ---
    e 136 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38
    e 148 39 3A 3B 3C 3D 3E 3F 0D 0A 0D 0A 40 41 42 43 44 45 46
    e 15a 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58
    e 16c 59 5A 5B 5C 5D 5E 5F 60 61 62 63 64 65 66 67 68 69 6A
    e 17e 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C
    e 190 7D 7E 7F 0D 0A 0D 0A 80 81 82 83 84 85 86 87 88 89 8A
    e 1a2 8B 8C 8D 8E 8F 90 91 92 93 94 95 96 97 98 99 9A 9B 9C
    e 1b4 9D 9E 9F a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aA aB aC aD aE
    e 1c6 aF b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 bA bB bC bD bE bF 0D
    e 1d8 0A 0D 0A c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 cA cB cC cD cE
    e 1ea cF d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 dA dB dC dD dE dF e0
    e 1fc e1 e2 e3 e4 e5 e6 e7 e8 e9 eA eB eC eD eE eF f0 f1 f2
    e 20e f3 f4 f5 f6 f7 f8 f9 fA fB fC fD fE fF 0D 0A 0D 0A 24

用g =100来运行该代码

15: GO: G [=address] [address]
    G用于运行一个程序, 并在程序代码中设置断点.
    =address用于告诉DEBUG从哪里开始执行, 如果仅使用G不加参数, 则程序从CS:IP指向
    处开始运行.
    address用于设置断点, 断点处的第一个字节必须为可用的8088/8086操作码. 因此有时
    随意设置的断点, 程序运行到此处可能不会停止. 再比如要是代码中的操作码为80286
    及以上的CPU指令, 则DEBUG不认识, 在此处设置的断点也不会HALT.
    DEBUG设置断点的方式: 在原指令序列中加入"CCH" (INT 3). 设置断点后将代码存储为
    文件时, 这些"CCH"也会存入.  因此使用断点时最好先保存文件的一个备份.

16: Assemble: A [address] 
    创建一段机器可执行代码, 在内存区域CS:0100或者是由address所指定的地址.
    尽管所有的宏指令和标签都不能使用, 但你可以使用伪指令DB和DW.
    A可以记住上次汇编代码的最后的地址, 因此连续使用A命令时都会从上次的最后地址开
    始(Dump命令也是如此). 在一个空行输入回车后结束汇编码的输入.
    可以使用分号;表示后面的内容为注释.但不能注释DB/DW行.
    DEBUG使用[]来引用内存数据
    DEBUG可以使用"WORD PTR"和"BYTE PTR"来表明数据的大小.
    对所有的8087操作码, WAIT和FWAIT前缀必须明确指明.

17: Unassemble: U [range]
    没有range时, 使用偏移量100, 32B大小来反汇编.(32B大小并不是一定的, 有时最后一
    条指令可能需要多一些的字节, 但大小还是在32B左右)
    80286,80386及更新的INTEL CPU指令不能识别,故也不能被反汇编.

18: Input: I [port]
    在windows系统下用I/O命令要么不可靠, 要不就是被模拟的.
    -o 70 04
    -i 71
    11                  ;得到系统时间里的小时.
    -o 70 02
    -i 71
    45                  ;得到系统时间里的分钟.

19: Output: O [port] [byte]

20: Load: L [address] [drive] [firstsector] [number]
          L [program]
    address指定数据将要复制到的内存的地址.
    drive: 0=A, 1=B, 2=C.. 等等.
    firstsector: 起始的扇区(从0开始)
    number: 指定要复制的扇区数.
    不能用L命令来load MBR, 或者其他不属于主分区和逻辑驱动器里的扇区.
    当使用命令L 100 2 0 1来查看硬盘的第一个分区(MBR)时, 看到的是C盘的引导记录.

21: Move: M [range] [address]
    把range里指定的数据复制到address里.

22: Name: N [pathname] [arglist]
    当你想debug一个文件时, 可以用N指令, 然后使用L指令.
    还一种用法是和W指令结合, 将数据写入文件.

23: Register: R [register]
    仅输入R救回显示所有8086寄存器的内容和下一条指令.
    若输入R后加上某个寄存器名, 则debug会显示该寄存器的内容, 并允许你修改它.
    可以使用R后加上F来修改标志寄存器的内容.

24: Trace: T [=address] [number]
    若仅输入T, 则会只执行由CS:IP指向的一条指令(一般情况是这样的).
    若要执行多个指令就要指定address和number.

25: Proceed: P [=address] [number]
    基本和T一样, 但对于CALL, LOOP, REP, INT指令会一次性执行完,

26: Write: W [address] [drive] [firstsector] [number]
    W指令要慎用, 正确使用会非常方便的在硬盘创建文件, 但错误使用会出问题.
    W经常和N结合使用, 来生成一个程序.

 

 

 

有错误,问题,意见都可以提出来.

转载注明出处, 多谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值