调试工具DEBUG和第一个汇编程序

更新时间:2023-05-13 18:10:01 阅读量: 实用文档 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

本次实验让大家掌握DEBUG工具使用和汇编程序的编译,课堂上需完成“实验任务”。因为牵涉到首次使用这些工具,所以大家请课前先熟悉这些工具(按照“实验一 参考.pdf”和FTP上的资料)。当然课堂上还会简单介绍。若还有问题,可以网上搜索相关设置或相互讨论或给我邮件。若是Win7/Win8 64位系统,请参照“win7 X64 下使用debug.docx”,FTP上有相应工具下载。

注意:EDIT.EXE、MASM.EXE、LINK.EXE、DEBUG.EXE 需放在同一目录下(即mount c d:/指定的d:/)。推荐使用Notepad++编辑.asm源文件,会对不同关键字显示颜色。

由于教材讲汇编部分不够具体透彻,汇编部分可以参考FTP上的“汇编语言_第2版.pdf”。

实验一a 调试工具DEBUG的使用

1.1 实验目的

(1)学习如何在Windows的命令模式下启动DEBUG。 (2)掌握DEBUG的常用基本命令。

(3)学习如何使用DEBUG查看CPU和内存以及进行跟踪调试。

1.2 实验设备及软件环境

装有DOS系统及MASM的微机一台。

1.3 预备知识

1 什么是DEBUG?

Debug是DOS、Windows都提供的实模式(8086方式)程序的调试工具。使用它,可以查看CPU各种寄存器的内容、内存的情况和在机器码级跟踪程序的运行。

2 常用的Debug命令及其含义

3 启动DEBUG

(1)打开Windows命令窗口

选择“开始”→“运行”→输入“cmd”命令 (2)启动DEBUG

在命令窗口中启动DEBUG,将显示连接符“-”,这时可输入各种DEBUG命令。 (3)关于使用命令的几点说明:

在提示符“-”下才能输入命令,在按“回车”键后,该命令才开始执行; 命令是单个字母,命令和参数的大小写可混合输入

可用F1、F2、F3、Ins、Del、→等编辑键来编辑本行命令 当命令出现语法错误时,将在出错位置显示“^Error” 在DEBUG中使用的数都是以十六进制来表示的

1.4 实验内容

1 R命令

作用:查看、改变CPU寄存器的内容

(1)显示所有寄存器之中的内容:输入R

我们重点关注AX、BX、CX、DX、CS及IP寄存器的内容,其他寄存器SP、BP、SI、DI、

ES、SS及标志寄存器先不予理会。此外,并列出了CS:IP所指向的内存单元处所存放的机器码,并将它翻译为汇编指令。

(2)改变寄存器中的内容:输入R AX

在提示符“:”后输入1111,即可将AX的值设置为1111。在输入R命令,查看修改后的寄存器值。

练习:

(1)用R命令修改IP的值,并查看此时CS:IP的指向,存放的机器码以及对用的汇编指令;

(2)用R命令修改CS的值,并查看此时CS:IP的指向,存放的机器码以及对用的汇编指令;

2 D命令

作用:查看指定范围内的内存中的内容 (1)直接输入D命令

DEBUG将输出3部分内容,查看执行结果。 说明:

左边是每行的起始地址,用“XXXX:YYYY”表示,其中XXXX表示内存单元的段地

址,YYYY表示内存单元的偏移量;

中间以十六进制的形式显示从指定地址开始的128个内存单元的内容,每行显示

16个字节的内容;

右边显示每个内存单元中的数据对应的可显示的ASCII码字符,若没有对应可显示

的ASCII码字符,DEBUG用“.”来代替。

(2)执行带参数的D命令

若执行带参数的命令D,DEBUG将显示指定地址范围的内容。带参数的方式有三种。 方式一:D 起始位置

DEBUG从起始位置开始显示128个字节的内容。 输入命令:D 1AF5:100 方式二:D 起始位置 结束位置

DEBUG从起始位置开始一直显示到结束位置。 输入命令:D DS:100 11F 方式三:D 起始位置 L长度

DEBUG命令从起始位置开始显示指定长度内容。 输入命令:D DS:100 L10

使用带参数的D命令后,接着使用D命令,可列出后续的128个内存单元的内容。 练习:

(1)使用D命令,查看内存10000H处的内容; (2)使用D命令,查看1000:0~1000:9中的内容

(3)采用三种不同的段地址和偏移地址查看同一物理地址10000H中的内容

3 E命令

格式:E 起始地址 字节值表

或 E 起始地址

作用:用值表中的值替换从“起始地址”开始的内存单元中的内容

例1:将内存1000:0~1000:9单元中的内容分别写为0、1、2、3、4、5、6、7、8、9,

可用“E 起始地址 数据 数据 数据 数据 数据 ”的格式来进行。 步骤:

① 用D命令查看1000:0~1000:f单元的内容:D 1000:0 f

② 用E命令修改从1000:0开始的10个单元中的内容:E 1000:0 0 1 2 3 4 5 6 7 8 9 ③ 用D命令查看1000:0~1000:f单元中内容的变化:D 1000:0 f

例2:用E命令向内存中写入字符。从内存1000:0开始写入:数值1,字符“a”,数值2,

字符“b”,数值3,字符“c”。 步骤:

① 用D命令查看1000:0处的内容:D 1000:0 ② 用E命令输入:E 1000:0 1 ‘a’ 2 ‘b’ 3 ‘c’

③ 用D命令查看1000:0~1000:f单元中内容的变化:D 1000:0 f

例3:用E命令向内存中写入字符串。从内存1000:0开始写入:数值1,字符串“a+b”,

数值2,字符串“c++”,数值3,字符“IBM”。 步骤:

① 用D命令查看1000:0处的内容:D 1000:0 ② 用E命令输入:E 1000:0 1 ‘a+b’ 2 ‘c++’ 3 ‘IBM’

③ 用D命令查看1000:0~1000:f单元中内容的变化:D 1000:0

例4 用E命令以提问的方式来逐个地修改从某一地址开始的内存单元中的内容。

以从1000:10单元开始为例。 步骤:

① 用D命令查看1000:10处的内容:D 1000:10 ② 用E命令输入:E 1000:10,按Enter键

③ DEBUG将显示起始地址1000:0010以及第一个单元(即1000:0010单元)的原始内容:00.,然后光标停在“.”的后面,提示输入想要写入的数据,此时有两种选择:其一输入数据,完后按空格键,即用输入的数据改写当前的内存单元;其二不输入数据,直接按空格键,则表示不对当前内存单元进行改写 ④ 当前单元处理完成后(不论是改写或者没有改写,只要按了空格键,就表示处理完成),DEBUG将显示下一个内存单元的原始内容,并提示进行修改,可以用同样的方法进行处理

⑤ 所有希望改写的内存单元改写完毕后,按ENTER键,E命令结束 ⑥ 用D命令查看1000:10单元中内容的变化:D 1000:10

4 U命令

格式:U[范围]

作用:反汇编,即显示机器码所对应的汇编指令 命令执行完后,DEBUG显示的输出内容包括3个部分:每一条机器指令的地址、机器指令、

机器指令所对应的汇编指令。

若命令中不写“范围”参数,则把从CS:100开始的20H个字节内容反汇编成汇

编指令,并显示出来; 若命令中只有“起始地址”,则把从该“起始地址”开始的20H个字节内容反汇编

成汇编指令;

若命令中只有“起始地址”和“终止地址”,则把从“起始地址”到“终止地址”

之间的字节内容反汇编成汇编指令。

例1:执行命令 U 100,查看执行结果

例2:执行命令 U 100 10C,查看执行结果。表示对从CS:100到10B的内存单元进行反汇编。

例3:用E命令向内存中写入机器码,用U命令查看内存中机器码的含义。 机器码 对应的汇编指令 b8 01 00 mov ax,0001 b9 02 00 mov cx,0002 01 c8 add ax,cx

① 用E命令输入E 1000:0 b8 01 00 b9 02 00 01 c8 ② 用D命令查看1000:0单元内容:D 1000:0

③ 用U命令查看1000:0单元中机器码的含义:U 1000:0

5 T命令

格式:T[=地址][指令数]

作用:跟踪执行,从起点(或当前点)执行若干条指令 若不写“地址”,则T命令从CS:IP处开始执行,“指令数”是要执行的指令数。 若只用T命令,则从CS:IP处执行一条指令。

例:简单地使用T命令,可以执行CS:IP指向的指令。 ① 首先用E命令向1000:0开始的内存单元中写入8个字节的机器码:E 1000:0 b8 01 00

② 用R命令查看CPU中寄存器的状态:R (可以看到CS=? IP=?,指向CS:IP) ③ 用R命令修改CS,IP中的内容,使CS:IP指向1000:0 ④ 使用T命令执行写入的指令

(执行T命令后,CPU执行CS:IP指向的指令,则1000:0处的指令b8 01 00即mov

ax,0001得到执行,指令执行完后,DEBUG显示输出CPU中寄存器的状态)

⑤ 用T命令继续执行后面的指令,注意每条指令执行后,CPU相关寄存器内容的变化。

6 A命令

作用:以汇编指令的形式向内存中写入指令

(1)简单地使用A命令,从一个预设的地址开始输入指令 例:输入A,写入指令:mov ax,1 mov bx,2 mov cx,3 add ax,bx add ax,cx

add ax,ax

(2)给出起始地址的A命令

例:A 1000:0,写入指令:mov ax,1 mov bx,2 mov cx,3 add ax,bx add ax,cx add ax,ax

1.5 实验任务

(1)使用DEBUG,将下面的程序段写入内存,逐条执行,观察每条指令执行完后,CPU中相关寄存器中内容的变化。

提示:可以用E命令和A命令以两种方式将指令写入内存。并注意用T命令执行时,CS:IP的指向。

机器码 汇编指令 B8 20 4e mov ax,4e20h 05 16 14 add ax,1416h Bb 00 20 mov bx,2000h 01 d8 add ax,bx 89 c3 mov bx,ax 01 d8 add ax,bx B8 1a 00 mov ax,001ah Bb 26 00 mov bx,0026h 00 d8 add al,bl 00 dc add ah,bl 00 c7 add bh.al B4 00 mov ah,0 00 d8 add al,bl 04 9c add al,9ch

(2)向内存从B8100H开始的单元中填写数据,如: -e b810:0000 01 02 03 04 05 05 06

注意:先填写不同的数据,观察产生的现象;再改变填写的的地址,观察产生的现象。 (3)使用DEBUG,讲下面的程序段写入内存,逐条执行,根据指令执行后的实际情况空。

Mov ax,ffff Mov ds,ax Mov ax,2000 Mov ss,ax Mov sp,0100

Mov ax,[0] Add ax,[2] Mov bx,[4]

Add bx,[6]

Push ax ;修改的内存单元的地址是

Push bx 修改的内存单元的地址是内容为Pop ax Pop bx

Push [4] 修改的内存单元的地址是内容为 Push [6] 内容为

实验一b 用DEBUG调试程序

一、实验目的

学习利用DEBUG调试程序的基本思想及方法

二、实验环境:

1. 硬件:PC微机

2. 软件:DOS系统、EDIT.EXE (Notepad++.exe更好用些,见FTP)、MASM.EXE、

LINK.EXE、DEBUG.EXE

三、实验内容

利用DEBUG调试程序,可以将一个可执行程序(如.EXE、.COM等)装入内存中,并接管对程序运行的控制权,通过采取如反汇编、断点运行、单步执行、寄存器内容修改等方法,对可执行程序进行跟踪、调试,以找出其中的设计错误,然后再对源程序进行相应修改,重新生成正确的可执行程序。 1. 准备被调试程序:

假定所有有关文件均在当前路径C:\MYTEST>下,按照实验一的步骤生成一个被调试的可执行 (以下是使用Notepad++编辑源文件,会对不同关键字显示颜色)

2.

进入DEBUG环境:(其中斜体部分由键盘输入。

)

其中,短线‘-’作为DEBUG环境的操作提示符,在此提示符下,可以输入各种DEBUG命令,对可执行程序TEST.EXE进行跟踪调试。 3. 主要调试命令:

1) 反汇编命令U:将存储器中的二进制数据翻译成较有意义的助记符形式,以帮助理

解。一般常用以下格式: a) -U↘:从当前IP处开始,对连续约32字节内容反汇编。如对TEST.EXE,刚装

入DEBUG时的IP=0000,则在输入U命令后有如下显示:

在上例中,12B7:0000表示CS:IP的内容(其中CS的值是动态值);B8B612代表该处存放的二进制数据,亦即指令MOV AX,12B6的机器代码;当连续约32字节的数据反汇编完后,重新回到DEBUG提示符“-”下,如果再键入U命令,则将继续对后面的内存区反

汇编。

特别应该注意的是,由于反汇编命令针对内存区的二进制数据,而被调试程序仅占内存区的某一部分,故反汇编出来的内容并非全是被调试程序的代码,如上例中的JMP 0063以后的部分,显然不是TEST.EXE的内容。另外还需注意,DEBUG默认使用十六进制。

b) –U 0123↘:从指定的IP=0123处开始,对连续约32字节内容反汇编。

c) –U 0123 0143↘:从指定的IP=0123处开始反汇编,直至指定的0143处结束。 2) 显示寄存器命令R:显示或修改寄存器的内容。一般常用以下形式:

a) -R↘:显示所有寄存器当前的内容及当前将执行的指令。如对TEST.EXE,在程

序运行之前,键入R命令:

在显示寄存器内容时,标志寄存器F(或程序状态字寄存器PSW)表示成各个分离的标志

b) -R AX↘:显示指定的AX寄存器当前的内容,并等待键入新值;如果不作修改,

可直接回车。如:

c) -R F↘:显示标志寄存器F各个标志位的内容,并等待键入新的标志位;如果不

作修改,可直接回车。如:

3)运行命令G:使程序在DEBUG控制下运行,一般有全程、断点运行两种方式。 a) -G↘:控制程序由当前IP处运行,直至程序结束。如果当前IP为初始值,其作

用则相当于直接在DOS下运行程序,一般用于快速观察程序的运行情况。 b) -G 0123↘:控制程序由当前IP处运行,直至指定的断点IP=0123H处,程序暂

停,显示各个寄存器的当前值及断点处指令,然后返回DEBUG提示符“-”下。如对TEST.EXE,若想观察字符串显示的入口参数是否设置好,则可以断点运行至000A处:

断点一般选取在需要观察的地方,当程序停下来后,可以根据各方面的情况(如寄存器、缓

冲区、标志等)来判断程序是否运行正确。

3) 单步命令T:控制程序运行一条指令后暂停,显示各个寄存器的当前值及断点处指

令,然后返回DEBUG提示符“-”下。如对TEST.EXE,若当前IP为初始值,则键入T命令后有如下显示:

单步命令一般用于需对程序运行作仔细分析的地方,如判断分支转移、观察运算结果等。若能综合运用断点及单步指令,则可大大提高DEBUG 调试的速度及效率。但应注意,当IP指针位于INT 21H一类指令处时,执行T命令将会使程序进入该功能调用子程序中,因此,这种情况下最好不用T命令,而用断点运行命令跳过该类功能调用指令。

4) 显示内存命令D:以十六进制及ASCII两种方式显示内存区的二进制数据,通常

用来观察数据段内的缓冲区内容。一般常用以下二种形式: a) -D↘:从0000单元开始,连续显示128个内存单元的内容,如果继续键入D命

令,则继续显示后128个单元内容。如对TEST.EXE,若想观察字符串显示时的字符串内容是否正确,则可在程序断点运行至000A处,键入D命令:

在上例中,128个单元分成8行,每行16个单元,每个单元的内容分别以十六进制形式和ASCII码形式显示。如果该单元的内容不是可显示字符,则在ASCII区内显示为“.”。

b) –D 0123 0143↘:从指定的0123单元开始显示,直至指定的0143单元结束。 5) 汇编命令A:用于在DEBUG环境下直接键入汇编语言语句、生成较简单的可执行

代码而不必经过完整的汇编语言编程步骤,或者用来在调试过程中临时修改某条指令。如:

当键入汇编命令A后,将从当前IP或指定地址处提示输入汇编语句,每输入一条语句,DEBUG将其汇编成机器码,并存入相应的存储单元中,然后地址自动增加,继续提示输入下一条语句;如果直接回车,则结束汇编命令。特别应注意的是,DEBUG默认使用十六进制,故在输入时不能使用H。

6) 装载命令L:用来将被调试程序重新装载进内存中,一般用于程序运行结束后需继

续调试程序时,或需从头开始调试程序时。如对TEST.EXE:

8)退出命令Q:键入此命令,即退出DEBUG状态,返回DOS。

4.实验任务:将内存数据段从2000H开始的连续100个字节的内容传送到附加段3000H开始的内存区域,在DEBUG下调试程序并查询运行的结果。 参照教材99页例

3.75

附教材99页例3.75

具体代码如下:

操作步骤如下:

编译得到mov100.exe后

debug mov100.exe -t

-t -t

-d ds:2000 -d es:3000 -g

-d ds:2000 -d es:3000

本文来源:https://www.bwwdw.com/article/rwge.html

Top