当前位置:  技术问答>linux和unix

哪有好的debug教程或电子书?

    来源: 互联网  发布时间:2014-11-06

    本文导语:  ? | DEBUG主要命令     DEBUG是为汇编语言设计的一种高度工具,它通过单步、设置断点等方式为汇编语言程序员提供了非常有效的调试手段。 一、DEBUG程序的调用     在DOS的提示符...


|
DEBUG主要命令

    DEBUG是为汇编语言设计的一种高度工具,它通过单步、设置断点等方式为汇编语言程序员提供了非常有效的调试手段。
一、DEBUG程序的调用
    在DOS的提示符下,可键入命令:
        C:DEBUG [D:][PATH][FILENAME[.EXT]][PARM1][PARM2]
    其中,文件名是被调试文件的名字。如用户键入文件,则DEBUG将指定的文件装入存储器中,用户可对其进行调试。如果未键入文件名,则用户可以用当前存储器的内容工作,或者用DEBUG命令N和L把需要的文件装入存储器后再进行调试。命令中的D指定驱动器PATH为路径,PARM1和PARM2则为运行被调试文件时所需要的命令参数。
    在DEBUG程序调入后,将出现提示符,此时就可用DEBUG命令来调试程序。
二、DEBUG的主要命令
    1、显示存储单元的命令D(DUMP),格式为:
    _D[address]或_D[range]
    例如,按指定范围显示存储单元内容的方法为:
    -d100 120
18E4:0100 c7 06 04 02 38 01 c7 06-06 02 00 02 c7 06 08 02 G...8.G.....G...
18E$:0110 02 02 bb 04 02 e8 02 00-CD 20 50 51 56 57 8B 37 ..;..h..M PQVW.
        7
18E4:0120 8B
    其中0100至0120是DEBUG显示的单元内容,左边用十六进制表示每个字节,右边用ASCII字符表示每个字节,·表示不可显示的字符。这里没有指定段地址,D命令自动显示DS段的内容。如果只指定首地址,则显示从首地址开始的80个字节的内容。如果完全没有指定地址,则显示上一个D命令显示的最后一个单元后的内容。
2、修改存储单元内容的命令有两种。
    ·输入命令E(ENTER),有两种格式如下:第一种格式可以用给定的内容表来替代指定范围的存储单元内容。命令格式为:
    -E address [list]
例如,-E DS:100 F3'XYZ'8D
    其中F3,'X','Y','Z'和各占一个字节,该命令可以用这五个字节来替代存储单元DS:0100到0104的原先的内容。
    第二种格式则是采用逐个单元相继修改的方法。命令格式为:
    -E address
例如,-E DS:100
    则可能显示为:
        18E4:0100 89.-
    如果需要把该单元的内容修改为78,则用户可以直接键入78,再按“空格”键可接着显示下一个单元的内容,如下:
    18E4:0100 89.78 1B.-
    这样,用户可以不断修改相继单元的内容,直到用ENTER键结束该命令为止。
    ·填写命令F(FILL),其格式为:
    -F range list
例如:-F 4BA:0100 5 F3'XYZ'8D
    使04BA:0100~0104单元包含指定的五个字节的内容。如果list中的字节数超过指定的范围,则忽略超过的项;如果list的字节数小于指定的范围,则重复使用list填入,直到填满指定的所有单元为止。
3)检查和修改寄存器内容的命令R(register),它有三种格式如下:
    ·显示CPU内所有寄存器内容和标志位状态,其格式为:
        -R
例如,-r
    AX=0000 BX=0000 CX=010A DX=0000 SP=FFFE BP=0000 SI=0000 DI=0000
    DS=18E4 ES=18E4 SS=18E4 CS=18E4 IP=0100 NV UP DI PL NZ NA PO NC
    18E4:0100 C70604023801 MOV WORD PTR [0204],0138 DS:0204=0000
    ·显示和修改某个寄存器内容,其格式为:
    -R register name
例如,键入
    -R AX
    系统将响应如下:
    AX F1F4
    :
即AX寄存器的当前内容为F1F4,如不修改则按ENTER键,否则,可键入欲修改的内容,如:

    -R bx
    BX 0369
    :059F
则把BX寄存器的内容修改为059F。
    ·显示和修改标志位状态,命令格式为:
        -RF系统将响应,如:
        OV DN EI NG ZR AC PE CY-
    此时,如不修改其内容可按ENTER键,否则,可键入欲修改的内容,如:
        OV DN EI NG ZR AC PE CY-PONZDINV
    即可,可见键入的顺序可以是任意的。
4)运行命令G,其格式为:
    -G[=address1][address2[address3…]]
    其中,地址1指定了运行的起始地址,如不指定则从当前的CS:IP开始运行。后面的地址均为断点地址,当指令执行到断点时,就停止执行并显示当前所有寄存器及标志位的内容,和下一条将要执行的指令。
5)跟踪命令T(Trace),有两种格式:
    ·逐条指令跟踪
    -T [=address]
    从指定地址起执行一条指令后停下来,显示所有寄存器内容及标志位的值。如未指定地址则从当前的CS:IP开始执行。
    ·多条指令跟踪
    -T [=address][value]
    从指定地址起执行n条指令后停下来,n由value指定。
6)汇编命令A(Assemble),其格式为:
    -A[address]
    该命令允许键入汇编语言语句,并能把它们汇编成机器代码,相继地存放在从指定地址开始的存储区中。必须注意:DEBUG把键入的数字均看成十六进制数,所以如要键入十进制数,则其后应加以说明,如100D。
7)反汇编命令U(Unassemble)有两种格式。
    ·从指定地址开始,反汇编32个字节,其格式为:
    -U[address]
例如:
    -u100
    18E4:0100 C70604023801   MOV   WORD PTR[0204],0138
    18E4:0106 C70606020002   MOV   WORD PTR[0206],0200
    18E4:010C C70606020202   MOV   WORD PTR[0208],0202
    18E4:0112 BBO4O2                 MOV     BX,0204
    18E4:0115 E80200                 CALL 011A
    18E4:0118 CD20             INT   20
    18E4:011A 50                PUSH AX
    18E4:011B 51                PUSH CX
    18E4:011C 56                PUSH SI
    18E4:011D 57                PUSH DI
    18E4:011E 8B37 MOV SI,[BX]
如果地址被省略,则从上一个U命令的最后一条指令的下一个单元开始显示32个字节。
    ·对指定范围内的存储单元进行反汇编,格式为:
    -U[range]
例如:
    -u100 10c
    18E4:0100 C70604023801 MOV WORD PTR[0204],0138
    18E4:0106 C70606020002 MOV WORD PTR[0206],0200
    18E4:010C C70606020202 MOV WORD PTR[0208],0202
或
    -u100 112    
    18E4:0100 C70604023801 MOV WORD PTR[0204],0138
    18E4:0106 C70606020002 MOV WORD PTR[0206],0200
    18E4:010C C70606020202 MOV WORD PTR[0208],0202

    可见这两种格式是等效的。
8)命名命令N(Name),其格式为:
    -N filespecs [filespecs]
命令把两个文件标识符格式化在CS:5CH和CS:6CH的两个文件控制块中,以便在其后用L或W命令把文件装入存盘。filespecs的格式可以是:
[d:][path] filename[.ext]
例如,
    -N myprog
    -L
    -
可把文件myprog装入存储器。
9)装入命令(Load),有两种功能。
    ·把磁盘上指定扇区范围的内容装入到存储器从指定地址开始的区域中。其格式为:
    -L[address[drive sector sector]
    ·装入指定文件,其格式为:
    -L[address]
此命令装入已在CS:5CH中格式化了文件控制块所指定的文件。如未指定地址,则装入CS:0100开始的存储区中。
10)写命令W(Write),有两种功能。
    ·把数据写入磁盘的指定扇区。其格式为:
        -W address drive sector sector
    ·把数据写入指定的文件中。其格式为:
        -W[address]
此命令把指定的存储区中的数据写入由CS:5CH处的文件控制块所指定的文件中。如未指定地址则数据从CS:0100开始。要写入文件的字节数应先放入BX和CX中。
11)退出DEBUG命令Q(Quit),其格式为:
    -Q
它退出DEBUG,返回DOS。本命令并无存盘功能,如需存盘应先使用W命令。 

问 题 : 初 学 者 问 一 个 低 级 问 题 ,执 行 debug -a 后 ,如 果 有 一 行 输 入 错 误 ,如 何 更 改 这 一 行 ? 

回答:
    加 入 进 行 如 下 输 入 :
    D:PWIN95Desktop>debug
    -a
    2129:0100 mov ax, 200
    2129:0103 mov bx ,200
    2129:0106 mov cx, 200
    2129:0109
    此 时 , 发 现 mov bx, 200一 句 错 误 , 应 为 mov bx, 20, 可 以 敲 回 车 返 回 “ -” 状 态 , 然 后 输 入 :
    -a 103
    2129:0103 mov bx, 20
  如 果 多 或 者 少 若 干 行 , 不 必 重 新 输 入 , 可 以 用 M命 令 移 动 后 面 的 程 序 来 去 掉 或 者 增 加 程 序 空 间 。 




DEBUG.EXE指令说明

DEBUG [执行文件名] [执行该文件的外带参数] 
a [sta] 编写汇编语言程序的指令,sta为启始地址 
c sta end sta2  比较两个储存单元,sta为第一储存单元的启始地址,而end为第一储存单元结束地址,sta2为第二储存单元的启始地址 
c sta lnn sta2 比较两储存单元,sta为第一储存单元启始地址,而nn为欲比较的长度大小,sta2为第二储存单元启始地址 
d [sta] [end]  显示某指定范围储存单元至屏幕(sta:启始、end:结束) 
d [sta] [lnn]  显示某指范围块储存单元至屏幕(sta:启始、nn:长度) 
e [sta]  修改储存单元中某一个byte的资料,sta为地址 
e [sta] [data]  修改储存单元中某一个byte的资料,data为新资料 
g [end] 执行程序,直至结束地址(end)或程序结束时 
g=sta [end] 执行从启始(sta)直至结束(end)或程序结束时 
r [reg]  显示所有存储器內容或修改某指定存储器(reg)值 
t [num]  单步执行,num指定一次执行几步(预设1) 
t=sta [num] 单步执行,从sta起始,num指定执行几步(预设1) 
n filename 为目前正在编辑或除错的文件命名 
w [sta]  储存文件,写入cx个bytes的资料至n指定的文件名 
w sta dri sec num  将sta资料写入dri磁盘的第sec磁区共写num个磁区 
l [sta]  载入文件,读出n指定文件,档名的资料至sta地址中 
l sta dri sec num 读出dri磁盘的第sec磁区的资料至sta共读num个磁区 
q  离开debug,返回DOS 
u [sta] [end]  反汇编,从sta至end 
u [sta] [lnn]  反汇编,从sta,共反汇编nn个bytes 
m sta end sta2 将第一储存单元的数据搬至第二储存单元中 
m sta lnn sta2  将第一储存单元的数据搬至第二储存单元中 
f sta end data  将一段资料(data)存入某指定的储存单元区 
f sta lnn data  将nn个bytes的资料存入某指定的储存单元区 
s sta end data  搜寻data资料在指定地址內,data不限长度 
s sta lnn data 搜寻data资料在指定地址內,data不限长度 
h data data2  计算两个资料的和与差并显示在屏幕上 
i inport 由输入埠输入并显示一个byte 
o outport 由输出埠输出一个byte值 

下载更详细的debug使用指南(英文版)18k 

|

DEBUG的使用方法二

原作者:jjg@cadence.com (John Gianni)
译者:fengmarcal@163.net(marcal) 
新闻组:comp.lang.asm.x86


我有两个理由发表这些文章:
    1)给别人带来帮助:
       用去我的一点时间就可以使到很多的朋友节省时间。译者注:我翻译的水平不高。但翻译的目的是问了我们中国人也可以有多一点电脑高手,这样我们就可以早一点成为一个真正的强国。
    2)同时我也将获得收益
       一些关于FAT/directory/data-sector-lookup的知识我也需要帮助。译者注:我也一样希望高手指正我翻译有误的地方。



以下就是正文了,你可以尝试一下(如果你发现问题,那么写信告诉我)



如何除错和汇编你的第一个PC x86汇编语言程序呢?

 

以下这些简单的解释可以让一个汇编语言新手使用DEBUG: 


0)在使用时,如何快速获得debug的使用帮助呢。
1)让我们开始工作吧,例如:显示BIOS的日期。
2)在你的电脑的COMMANG.COM文件里搜寻“IBM”这几个字符。
3) 一位十六进制数的运算。
4) 检查 x86寄存器内容。
5)我们来编写我们的第一个用机械语言编写的程序-打印一个字符。
6) 我们现在用汇编语言指令来做和例5一样的事情。
7)现在,我们不但要编写一个汇编程序,而且我们还要把它存盘。
8) 现在,我们试一试查看一个已经编好的程序。
9)你可以用DEBUG的计算功能计算程序的长度。
10)另一种显示在屏幕上字符串的方法。
11)让我们试一试反复输出。
12)我们现在把两个程序连接起来。
13) 让我们逐步运行这个刚刚修补的程序。
14)如果一开始的命令不是跳转命令,那么可能就要用这种方法了.。 


--------------------------------------------------------------------------------


以下所有的命令都是可以运行在WIN9x的MS-DOS方式下的。
进入MS-DOS的方式有:
[开始][程序][MS-DOS方式]

[开始][运行][打开]COMMAND[确定]

或者你可以双击它:
C:WindowsCommand.com 


--------------------------------------------------------------------------------

0)在使用时,如何快速获得debug的使用帮助呢
以下PROMPT>表示目录提示符:一般为:C:WINDOWSCOMMANDPROMPT> DEBUG /?
怎样?出错了吧。显示如下
C:WINDOWS>DEBUG/?
Runs Debug, a program testing and editing tool.

DEBUG [[drive:][path]filename [testfile-parameters]]

[drive:][path]filename Specifies the file you want to test.
testfile-parameters Specifies command-line information required by
the file you want to test.

After Debug starts, type ? to display a list of debugging commands.
因为错了所以它给你显示一些提示。留意到最后一句了吗?


现在我们再来试一试:
PROMPT> DEBUG (注意, DEBUG程序的命令是在一条横线“-”后出现的。)
-? (下面的内容是按字母顺序排列的)
(注意:Note: Don't type the dash or comments -- just the ?)
显示如下,但是没有中文的哦,中文是我加上去的。 


汇编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
输入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
纪录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
-q (这是退出DEBUG回到DOS状态)This quits out of debug, returning to the DOS prompt)

Tested examples below walk the user thru the following debug examples:
在下面的例子里读者必须明白以下几条DEBUG命令。
-D 显示一定范围内存的内容Display the contents of an area of memory
-Q 退出DEBUG程序Quit the debug program
-S 搜寻Search for whatever
-H 十六进制的运算Hex arithmatic
-R 显示或者改变一个或者多个寄存器的内容Display or change the contents of one or more registers
-E 输入数据进入内存,在一个详细的地址里Enter data into memory, beginning at a specific location
-G 运行现在在内存里的程序。Go run the executable program in memory
-U 反汇编,把我们不认识的机械代码变为我们可以认识汇编语言符号Unassemble machine code into symbolic code
-T 描述一条指令的用法。Trace the contents of one instruction
-P 进行或者执行一个相关的指令Proceed, or execute a set of related instructions
-A 编译,把汇编命令变为机械代码Assemble symbolic instructions into machine code
-N 命名一个程序Name a program
-W 把一个已经命名的程序写进磁盘Write the named program onto disk
-L 把程序装载进内存Load the named program back into memory


返回目录 


--------------------------------------------------------------------------------

  


1)让我们开始工作吧,例如:显示BIOS的日期
(以下PROMPT>表示目录提示符:一般为:C:WINDOWSCOMMAND)

PROMPT> DEBUG 
-D FFFF:0006 L 8 (显示 FFFFh, 偏移地址 6h, 长度 8 bytes)
 在作者的电脑上这里显示为 "1/10/96."
 译者的电脑显示“ FFFF:0000 37 2F-30 36 2F 30 30 00 7/06/00.”相信作者的电脑里也是用这种格式显示的。这里显示出来的是使用者BIOS的日期,有兴趣的话可以重新开机看看,注意开机时的显示。
-Q (退出DEBUG) 

思考:当只按DEBUG的时候,编辑的是什么?为什么可以找到BIOS的日期?(译者这里也不是很清楚所以请大家知道的也留言给斑竹,改正。译者认为可能是内存的真实物理地址。)


返回目录 


--------------------------------------------------------------------------------


2)在你的电脑的COMMANG.COM文件里搜寻“IBM”这几个字符
下面的“C:Win95”是根据每不电脑不同的。像译者的电脑里就是“C:WINDOWS”

PROMPT> DEBUG C:Win95Command.com
-S 0 L FFFF "IBM"(从0开始搜寻"IBM",搜寻FFFFh多个单元格)
-Q (退出DEBUG) 

以下是译者做的: 

C:WINDOWS>DEBUG C:WINDOWSCOMMAND.COM
-S 0 L FFFF "IBM"
-S 0 L FFFF "COMMAND"
12A7:008D
12A7:04F7
12A7:3870
12A7:38BE
12A7:38DD
-S 0 L FFFF "PATH"
12A7:38AD
12A7:CCB7
12A7:CF55
-S 0 L FFFF "COMSPEC"
12A7:38D4
12A7:3A4D
12A7:CCC4
-Q

C:WINDOWS>

(注意:搜寻是要区分大小写的)
(你可以看到上面是没有找到“IBM”的, 可以试一试"PATH" , "COMSPEC" , "COMMAND")
(注意: 这种方法用在查找加密资料和已被删除的资料等方面时是十分有用的)


返回目录 


--------------------------------------------------------------------------------


3) 一位十六进制数的运算:

PROMPT> DEBUG
-H 9 1 (加减两个十六进制的数, 9h+1h=Ah & 9h-1h=8h)
结果是显示: 000A 0008
-Q (退出DEBUG) 

C:WINDOWS>debug
-h 9 1
000A 0008
-q
C:WINDOWS>


返回目录 


--------------------------------------------------------------------------------


4) 检查x86寄存器内容

PROMPT> DEBUG
-R (显示x86寄存器内容)
-Q (退出DEBUG) 

C:WINDOWS>debug
-R
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=127C ES=127C SS=127C CS=127C IP=0100 NV UP EI PL NZ NA PO NC
127C:0100 043C ADD AL,3C
-Q


下面是对寄存器的简单介绍: 


数据存储器
在本类中,一般讲的AH就是AX的前八位,AL就是AX的后八位,后面的以此类推。
AX Accumulator;作为累加器,所以它是算术运算的主要寄存器。另外所有的I/O指令都使用这一寄存器与外部设备传送信息。
BX Base register;可以作为通用寄存器使用,此外在计算存储器地址时,它经常用作基地址寄存器。
CX Counting register;可以作为通用寄存器使用,此外在循环(LOOP)和串处理指令中作隐含的计数器。
DX Data register;可以作为通用寄存器使用,一般在作双字长运算时,把DX和AX组合在一起存放一个双字长数,DX用来存放高位字。此外,对某些I/O操作,DX可用来存放I/O的端口地址。 

指针及变址寄存器
BP Base pointers register    ;机制指针寄存器
SI Source index register     ;堆栈指针寄存器
DI Destiny index register    ;目的变址寄存器
SP Battery pointer register  ;堆栈指针寄存器


段寄存器
CS Code segment register     ;代码段寄存器,存放正在运行的程序指令
DS Data segment register     ;数据段寄存器,存放当前运行程序所用的数据
SS Battery segment register  ;堆栈段寄存器,定义了堆栈所在区域
ES Extra segment register    ;附加段寄存器,存放附加的数据,是一个辅助性的数据区,



控制寄存器
IP Next instruction pointer register;指令指针寄存器,它用来存放代码段中的偏移地址,在程序运行的过程中,它始终指向下一条指令的首地址,它与CS寄存器联用确定下一条指令的物理地址
F Flag register;标志寄存器 “NV UP EI PL NZ NA PO NC”就是了,也有人称之为PSW  Program Status Wold程序状态寄存器 


(这里有一点必须讲明白的现在在,其实从奔腾开始这些寄存器(除了所有段寄存器,标志寄存器 )都是32位的。并且加多了两个16位段寄存器FS,GS。dos下面看到这些寄存器是16位的。要看32位寄存器可以使用soft-ice。对于FS,GS的作用我也不是很清楚,希望有高手指点,谢谢。) 

返回目录 


--------------------------------------------------------------------------------


5)我们来编写我们的第一个用机械语言编写的程序-打印一个字符
(这里用机械语言的主要原因是考虑到有一些用户不懂汇编命令,现在就要让他有一个认识计算机程序实质是一些数字) 


PROMPT> DEBUG
-E 100 (在偏移地址为100的地方输入机械指令程序)
B402 (在AX寄存器的前八位存入02)
B241 (在DX寄存器的后八位存入41h,41h就是大写A的ASCII码,身边有ASCII表的朋友可以对着表改改数字试一试)
CD21 (当AH=02时这是DOS显示输出的中断号)
CD20 (退出DOS)
-G (程序运行,并在屏幕上显示出“A”)
程序运行完以后你将看到"Program terminated normally"(程序正常结束了).
-U 100 (我们把它反汇编,就是把机械命令变为汇编语言指令) 
107F:0100 B402 MOV AH,02
    :0102 B2 MOV DL,41
    :0104 CD21 INT 21 
    :0106 CD20 INT 20 
    (下面会有一堆无用的东西)
(对了,你的段地址可能与我的段地址CS=107F不同哦)
-R (让我们来看看寄存器的值; IP==100h, AX==0000h, DX==0000h)
   好极了,我们看到电脑又做好了准备下一次运行程序了。
-T (执行第一步操作... IP=>102h, AX=>0200h,指令指针寄存器指向下一条命令,AX的值被改变。
-T (执行第二步操作... IP=>104h, , DX=>0041h,指令指针寄存器指向下一条命令,DX的值被改变。
-P (继续执行 INT 21,IP=>106h, AX=>02h,)
-P (继续执行INT 20)
-Q (退出DEBUG)
(注意:你必须小心使用"T".因为如果你在程序完结以后继续执行这条命令,因为我们无法预知下面的指令是什么,所以我们也无法预知它可能带来的后果)
C:WINDOWS>DEBUG
-E 100
127C:0100 B4.B4 02.02 B2.B2 41.41 CD.CD 21.21 CD.CD 20.20
-G
A
Program terminated normally
-U 100
127C:0100 B402 MOV AH,02
127C:0102 B241 MOV DL,41
127C:0104 CD21 INT 21
127C:0106 CD20 INT 20
127C:0108 C706F1E30900 MOV WORD PTR [E3F1],0009
127C:010E EB59 JMP 0169
127C:0110 57 PUSH DI
127C:0111 BFF1E3 MOV DI,E3F1
127C:0114 8BDF MOV BX,DI
127C:0116 06 PUSH ES
127C:0117 0E PUSH CS
127C:0118 07 POP ES
127C:0119 32D2 XOR DL,DL
127C:011B EB34 JMP 0151
127C:011D 006B12 ADD [BP+DI+12],CH
-R
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=127C ES=127C SS=127C CS=127C IP=0100 NV UP EI PL NZ NA PO NC
127C:0100 B402 MOV AH,02
-T

AX=0200 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=127C ES=127C SS=127C CS=127C IP=0102 NV UP EI PL NZ NA PO NC
127C:0102 B241 MOV DL,41
-T

AX=0200 BX=0000 CX=0000 DX=0041 SP=FFEE BP=0000 SI=0000 DI=0000
DS=127C ES=127C SS=127C CS=127C IP=0104 NV UP EI PL NZ NA PO NC
127C:0104 CD21 INT 21
-P
A
AX=0241 BX=0000 CX=0000 DX=0041 SP=FFEE BP=0000 SI=0000 DI=0000
DS=127C ES=127C SS=127C CS=127C IP=0106 NV UP EI PL NZ NA PO NC
127C:0106 CD20 INT 20
-P

Program terminated normally
-Q

C:WINDOWS>  

返回目录 


--------------------------------------------------------------------------------

6) 我们现在用汇编语言指令来做和例5一样的事情

  PROMPT> DEBUG
-A 100             (在偏移地址为100的地方输入汇编语言程序)
 MOV AH,02  (选用DOS的02号功能调用,显示输出)
 MOV DL,       (在DX寄存器的后八位存入41h,41h就是大写A的ASCII码,身边有ASCII表的朋友可以对着表改改数字试一试)
 INT 21            (当AH=02时这是DOS显示输出的中断号,显示"A")
 INT 20            (退出DOS)
                 (结束汇编语言编程状态,回到DEBUG命令状态)
-G =100           (运行程序,其实可以不要“=100”因为一般默认启始位置是100)
-Q                    (退出DEBUG)

  

C:WINDOWS>DEBUG
-A 100
127C:0100 MOV AH,02
127C:0102 MOV DL,41
127C:0104 INT 21
127C:0106 INT 20
127C:0108
-G
A
Program terminated normally
-Q

返回目录


--------------------------------------------------------------------------------

7) 现在,我们不但要编写一个汇编程序,而且我们还要把它存盘
 (下面这个程序就要比原来的程序复杂一点了-显示输出:"ABC")

  

PROMPT> DEBUG(运行DEBUG程序;系统默认启始IP寄存器值为100h)
-A 100              (用汇编语言编写一个程序,启始地址是100h)
 MOV AH,02    (选择DOS的02号功能调用, 显示输出)
 MOV DL,        (在DX寄存器的后八位存入41h,41h就是大写A的ASCII码)
INT 21              (当AH=02时这是DOS显示输出的中断号,显示"A")
 MOV DL,42     (在DX寄存器的后八位存入41h,41h就是大写B的ASCII码)
 INT 21             (当AH=02时这是DOS显示输出的中断号,显示"B")
 MOV DL,43    (在DX寄存器的后八位存入41h,41h就是大写C的ASCII码)
 INT 21            (当AH=02时这是DOS显示输出的中断号,显示"C")
 INT 20           (程序结束,退出DEBUG)
                      (结束汇编命令输入,回到DEBUG命令输入)
-R BX            (查看寄存器BX的值)
:0000             (设置BX为0000h,这是程序的结尾地址是BX:CX)
                                      (注意,只要BX = 0000, 文件的大小就小于  DIR printabc.com
       这里将会报告这个文件的大小是16字节 (10h 字节).
PROMPT> printabc.com
        会马上在屏幕上打印出"ABC"


C:WINDOWS>DEBUG
-A 100
127C:0100 MOV AH,02
127C:0102 MOV DL,41
127C:0104 INT 21
127C:0106 MOV DL,42
127C:0108 INT 21
127C:010A MOV DL,43
127C:010C INT 21
127C:010E INT 20
127C:0110
-R
AX=0000  BX=0000  CX=0000  DX=0000  SP=FFEE  BP=0000  SI=0000  DI=0000
DS=127C  ES=127C  SS=127C  CS=127C  IP=0100   NV UP EI PL NZ NA PO NC
127C:0100 B402          MOV     AH,02
-R BX
BX 0000
:
-R CX
CX 0000
:0010
-N PRINTABC.COM
-W
Writing 00010 bytes
-Q
C:WINDOWS>DIR PRINTABC.COM
Volume in drive C has no label
 Volume Serial Number is 28FB-70BA
 Directory of C:WINDOWS
PRINTABC COM            16  03-21-01  11:02 PRINTABC.COM
       1 file(s)             16 bytes
         0 dir(s)     557,711,360 bytes free
C:WINDOWS>PRINTABC
ABC
C:WINDOWS>

  这里可以有人告诉我,为什么要存入是BX:CX代表程序长度吗?(写信给译者,谢谢)

返回目录


--------------------------------------------------------------------------------

8) 现在,我们试一试查看一个已经编好的程序:

  PROMPT> DEBUG(运行DEBUG程序在CS:IP = CS:0100h)
-N printabc.com          (告诉电脑你想装载的程序名)
-L                               (装载那个名字的程序进入内存)
-U 100 L 10               (从偏移地址100开始反汇编16位字节)
-R                              (现在看看寄存器里面的内容)
                  注意:DEBUG本身是没有自动纪录文件大小的。
-G                                              (运行被命名的程序,打印"ABC")
                你将看到"ABC",然后是"Program terminated normally")

C:WINDOWS>DEBUG
-N PRINTABC.COM
-L
-U 100 L 10
12A4:0100 B402          MOV     AH,02
12A4:0102 B241          MOV     DL,41
12A4:0104 CD21          INT     21
12A4:0106 B242          MOV     DL,42
12A4:0108 CD21          INT     21
12A4:010A B243          MOV     DL,43
12A4:010C CD21          INT     21
12A4:010E CD20          INT     20
-R
AX=0000  BX=0000  CX=0010  DX=0000  SP=FFFE  BP=0000  SI=0000  DI=0000
DS=12A4  ES=12A4  SS=12A4  CS=12A4  IP=0100   NV UP EI PL NZ NA PO NC
12A4:0100 B402          MOV     AH,02
-G
ABC
Program terminated normally

返回目录


--------------------------------------------------------------------------------

9)你可以用DEBUG的计算功能计算程序的长度。

  一开始的时候你的程序初始地址是在0100h:
                                      107F:0100  MOV AH,02    DEBUG
-E 200       (从偏移地址200开始。输入"Hello,World")
4865  (输入48h (H)和65h (e))
6C6C  (输入6Ch (l)和6Ch (l))
6F2C  (输入6Fh (o)和2Ch (,))
576F  (输入57h (W)和6Fh (o))
726C  (输入72h (r)和6Ch (l))
6424  (输入64h (d)和24h ($))
             ("Hello,World" 已经输入完毕)
-D 200       (显示你刚刚输入的内容:
                    48 65 6C 6C 6F 2C 57 6F-72 6C 64 24 ... HELLO,WORLD$...)
-A 100       (用汇编语言写一个新程序在IP-100h处开始)
 MOV AH,09   (选择DOS的09号功能调用,显示字符串)
 MOV DX,0200 (把输出地址(200h),放进寄存器)
 INT 21      (执行DOS功能调用,显示"Hello,World")
 INT 20      (退出程序回到DOS状态)
             (结束汇编语言输入,回到DEBUG输入状态)
-G           (从 CS:IP开始运行程序, 就是从107F:0100h开始执行程序)  

现在,我们可以把这个程序保存进一硬盘

-D 100     (纪录:程序的起始点在100h)
-D 200       (纪录:程序数据单元的结束点是在020Bh)
-H 20B 100   (运算 20Bh-100h=10Bh;程序长度267字节)
-R BX        (检查BX寄存器的值)
:0000        (设置BX为0000h,程序的长度是BX:CX,实际上你可以把和CX写到一起,即实际长度为:0000010Bh,这样些的目的是使你可以计算更大的程序的长度)
-R CX        (设置CX 为010Bh, 这就是这个程序的长度了)
:010B        (现在你可以把这个108字节的程序写入硬盘了)
-N printhw.com (将要写入硬盘的程序命名)
-W           (把这10Bh 即267个字节写入文件)
-Q           (退出DEBUG)
PROMPT> DIR printhw.com
        将会汇报程序的长度是267字节(10Bh字节).
PROMPT> printhw.com   
       运行这个程序,这将会在屏幕上显示出"Hello,World" :

  C:WINDOWS>DEBUG
-E 200
127C:0200  2C.48   D5.65   BA.6C   FF.6C   FF.6F   B8.2C   00.57   AE.6F
127C:0208  CD.72   2F.6C   3C.64   00.24   C3.
-D 200
127C:0200  48 65 6C 6C 6F 2C 57 6F-72 6C 64 24 C3 A0 ED E3   Hello,World$
127C:0210  0A C0 74 09 56 57 E8 84-21 5F 5E 73 0A B9 04 01   ..t.VW..!_^s
127C:0220  FC 56 57 F3 A4 5F 5E C3-50 56 33 C9 33 DB AC E8   .VW.._^.PV3.
127C:0230  C3 23 74 19 3C 0D 74 15-F6 C7 20 75 06 3A 06 1E   .#t.DIR PRINTHW.COM
 Volume in drive C has no label
Volume Serial Number is 28FB-70BA
 Directory of C:WINDOWS
PRINTHW  COM           267  03-22-01  11:53 PRINTHW.COM
         1 file(s)            267 bytes
         0 dir(s)     555,089,920 bytes free

返回目录


--------------------------------------------------------------------------------

11)让我们试一试反复输出:

PROMPT> DEBUG
-A 100       (用汇编语言写一个新的程序,起始地址是100h)
 JMP 125     (从102h接跳到125h)
             (结束输入汇编命令。译者注:这里是为了例12做准备)
-E 102  'Hello World' 0d 0a '$'   (把字符串输入内存)
-A 125       (从125h开始继续编写我们的汇编语言程序)
 MOV DX,0102 (把字符串的首地址(102h)放入DX寄存器)
 MOV CX,0005 (指定这条指令将被显示5次)
 MOV AH,09   (选择DOS的09号功能调用, 显示字符串)
 INT 21     (执行DOS的功能调用, 显示"Hello, World")
 DEC CX      (每次运行到这里CX都减去1)
JCXZ 0134   (如果计数器CX=0,那么跳到地址0134h)
 JMP 012D    (其他情况下,即CX≠O时跳到012Dh)
 INT 20      (程序退出DOS状态)
             (结束汇编语言程序输入,回到DEBUG)
-U 100       (从地址100h 开始反汇编)
-U           (继续执行反汇编指令,直至你看到INT 20)
-H 0136 100  (运算程序长度为36h)
-U 100 L 36  ( 从100h反汇编到136h ,来确认你的计算)
-R BX        (查看寄存器BX的值)
:0000        (设置BX为0000h)
-R CX        (把CX 设置为36h, 这就是程序长度36字节)
:0036        (现在你可以把这36字节写入文件了)
-N printhw5.com(命名我,我们要写入的文件名)
-W           (把这36字节的内容写进新文件)
-G           (运行程序,在屏幕上显示”Hello-World “)
-Q           (退出DEBUG)
PROMPT> DIR printhw5.com
       将会汇报文件大小为54字节,换算为十六进制就是36h字节
PROMPT> printhw5.com  
        将在屏幕上显示五次"Hello World"

返回目录


--------------------------------------------------------------------------------

12)我们现在把两个程序连接起来。 

        我们现在把printhw.com做为修补程序 写进printhw5.com, 新版本的printhw5 将先执行原来的printhw.com再执行原来的printhw5.com

PROMPT> COPY printhw5.com printhw5.bak
    首先,备份printhw5.com,以后可以用于比较
PROMPT> DIR printhw5.com
        现在,查看到得仍然是以前的54字节(36h 字节)
PROMPT> DEBUG printhw5.com
-R                (现在查看仍然是BX:CX=0000 0036h bytes)
-U 100         (查看到最后的是 EB 23 (JMP 0125))
-H 100 36    (最后的指令是在 100h+36h=136h)
-H 136 1      (下一个可用的存储器位置是136h+1h=137h)
                    现在你拥有足够的资料,去修补那个程序
-E 110                    (把"Hello,World"输入内存)
4865      (输入48h (H)和65h (e))
6C6C     (输入6Ch (l)和6Ch (l))
6F2C     (输入6Fh (o)和2Ch (,))
576F      (输入57h (W)和6Fh (o))
726C      (输入72h (r)和6Ch (l))
6424       (输入64h (d)和24h ($))
                               (停止输入"Hello,World")
-D 110                    (显示更才输入内存的数据:
                     48 65 6C 6C 6F 2C 57 6F-72 6C 64 24 ...HELLO,WORLD$...)
-A 100                    (在IP地址的(100h)开始夺取原来的程序的控制权,原来这里是”JMP 125”)
 JMP 137                (代替原来运行的程序首先运行我们现在的修补程序)
                               (结束汇编命令输入,回到DEBUG命令输入)
-A 137                    (在下面的可用通奸编译这个修补程序)
 MOV AH,09         (选择DOS的09号功能调用,显示输出)
 MOV DX,110       (把我们要输出的字段的首地址(110h)给DX寄存器)
 INT 21                  (执行DOS 的功能调用,显示"Hello,World")
 JMP 0125              (这里用跳转到原程序来代替退出到DOS命令(INT 20))
                               (结束汇编命令输入,回到DEBUG命令输入)

  -U 125       (确认一下源程序没有被我们误改了,如果无改了就马上退出DEBUG重新来过)
-U 100 L 1   (确认已经使程序跳转到我们的修补程序地址137h)
-D 110 L C   (确认数据区已经有了我们想要的数据)
-U 137       (确认我们的新程序已经输入了)

  现在我们可以把这个小程序存入硬盘了:
                    (注意:在现在整个程序的最后一条命令"JMP 0125" 的后面一条的地址是0140h)
-H 0140h 100 (计算140h-100h=40h; 答案是我们现在有一个长度为64字节的小程序)
-RBX         (检查BX寄存器的值是否为”0”)
:            (如果BX是0000h那么就不需要改动啦)
-RCX         (要把CX改为40h。这是我们的程序的长度)
:40          (现在你可以把这0000:0040h个字节的小程序放入硬盘啦)
-W           (覆盖我们的原程序)
-G           (尝试运行我们的新程序)
-Q           (退出DEBUG回到DOS)

  PROMPT> DIR printhw5.com
        现在你再看就发现文章大小不再是54字节, 变成了64字节.
PROMPT> printhw5.com
        现在是首先在屏幕上打印 "Hello,World"一次,然后再打印"Hello,World" 5 次(译者注:这里其实可以在编程的时候换一换内容试一试.

返回目录


--------------------------------------------------------------------------------

13) 让我们逐步运行这个刚刚修补的程序:

PROMPT> DEBUG printhw5.com
-R  (第1步:地址0100h内容是 EB35 "JMP 0137")
-T  (第2步:地址0137h内容是B409 "MOV AH,09")
-T  (第3步:地址0139h内容是BA1001  "MOV DX,0110")
-T  (第4步:地址0139h内容是CD21 "INT 21")
-P  (运行第5:"Hello,World"地址013Eh内容是EBE5 "JMP 0125")
-T  (到这里控制权已经回到了原程序)
    如果你想的话,你可以一步一步的执行完全部程序;方法就是一直按”T”,直至到达下一个功能调用运行完成后。到那时按一个"P"就可以继续按"T".

返回目录


--------------------------------------------------------------------------------

14)如果一开始的命令不是跳转命令,那么可能就要用这种方法了:

例如:如果我们想叫程序printhw 先打印”ABC”,就要获取控制权了。然后打印”ABC”的程序把控制权给回原来的printhw. 

在这个事例里 ,printhw在100h的地址有两字节的程序;
不能象上面那样简单的替代(一个JMP代替另一个JMP)就完事。
解决办法就是使用NOP命令。


PROMPT> DIR printhw.com
        将汇报程序的长度为267字节(10Bh 字节).

PROMPT> DEBUG printhw.com
-R                   (IP=100h 并且printhw's 的文件大小=BX:CX=0000:010Bh)
-U 100           (第一条指令B4 09 (MOV AH,09)是两个字节的)
                                      (第二条命令是三个字节的  BA 00 02 (MOV DX,0200))
-H 100 10B   (最后一条printhw的指令是在100h+10Bh=20Bh)
                                      (DOS的INT 21功能调用是在105h开始的)
                                      现在你有足够的资料输入你的程序了!
-A 100          (要在printhw 的IP开始位置就夺取程序的控制权)
 JMP 20B     (跳到20Bh增加一个程序)
 NOP            (用空指令填充直至你去到下一条完整的指令)
NOP             (你可以用它来覆盖你不想只执行的原程序命令 ,而不改变原来的地址。但是在这里我们只需要两个NOP)
                译者注:为了使大家更加明白所以我将各条命令对应的机械命令的长度写在下面
                           B409          MOV     AH,09
                          BA0002        MOV     DX,0200
                          E90301        JMP     020B
                                                    90            NOP
             这样我们就很清楚的看到JMP 020B的长度比MOV AH,09多了1个字节,但是MOV  DX,0200有是3个字节,而NOP是空指令,是不执行任何操作的,它只是占1个字节。所以我们现在把前两条指令用一个JMP 020B和两个NOP代替。后面再加上去。
                       (结束汇编命令回到DEBUG命令输入)
-U 100            (看一看前面我们做了些什么)
                                        (注意DOS INT 21中断任然是在 IP=105h的地方开始)
-A 20B            (现在把我们的原程序写在后面)
 MOV AH,02  (选择DOS 的 2号功能调用, 字符显示输出)
 MOV DL,41   (在DL寄存器存入”A”的ASCII码41h)
 INT 21            (执行DOS 的功能调用,显示字符"A")
 MOV DL,42   (在DL寄存器存入”B”的ASCII码42h)
 INT 21           (执行DOS 的功能调用,显示字符"B")
 MOV DL,43   (在DL寄存器存入”C”的ASCII码43h)
 INT 21            (执行DOS 的功能调用,显示字符"C")
 MOV AH,09   (现在重新输入原来在100h的程序指令)
 MOV DX,0200      (现在要打扫寄存器了,还原原来的200h的值)
 JMP 105                 (跳到INT 21指令的位置105h)
                                (请注意一下你这里最后的地址是0221h)
-H 221 100              (计算221h-100h=121h 就是289字节的程序)
-R CX                      (把CX的值设为121h, 这就设定了程序的新长度)
:0121                        (现在用121h (也就是289字节)覆盖原值)
-W                            (把这289个字节写回原程序)
-Q                            (退出DEBUG)

  PROMPT> DIR printhw.com
        现在在看就会是新程序的长度289字节而不是,267字节)
现在在屏幕上先出现"ABC"再出现"Hello,World"

返回目录

 

 


|
http://wlbookwl.myrice.com/jckasm.htm
看看吧,右边有个Debug大全.

--------给分呦!------

|
破CMOS密码
在DOS下
c:>debug
_o 70 10
_o 71 11
_q
ctrl+alt+del
按del

    
 
 

您可能感兴趣的文章:

 
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • syslog(LOG_DEBUG, "Debug message appears"); 产生的调试信息在哪里看啊?
  • Makefile,如何传递宏定义DEBUG?以便于程序编译或者跳过程序中#ifdef DEBUG中间的代码段?
  • warning: Missing the separate debug info file: /usr/lib/debug/.build-id/ac/2eeb2
  • 怎样用debug对硬盘进行低级格式化?
  • driver debug問題?
  • G++有什么选项能让程序执行#if debug #endif中间的代码呀???
  • 有个debug问题
  • PHP_Debug
  • PHP调试工具 PHP debug tools
  • 用debug如何格式化1.44M的软盘?
  • 请问载linux下如何调试汇编程序,有没有像debug的程序。
  • linux怎么发布release和debug版本?
  • linux中有类似于debug的程序吗?
  • 有关make all; make clobber; make depend; make debug 的区别?
  • g++有debug和release版本吗?
  • linux中使用codeblocks编译C++程序debug可以执行和Release调用出错
  • insight可以 debug shared library吗?
  • JS中的log对象获取以及debug的写法介绍
  • PHP 应用跟踪诊断程序 PHP Debug
  • Wp-Debug


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3