1、debug 命令使用祥解 前段时间我在学习汇编语言,发现这语言不是太难学,他里面的算法思想和高级语言都是一样的,我在学这个之前学过c+ ,所以我才这样说的,学习一门语言固然重要,但是学会使用你所用的平台去调试也很重要,下面这个实验是我们现在正在上的接口原理实验,debug命令使用都是我们教员自己总结的,感觉很好,所以就发过来供大家分享。实验1DEBUG调试命令练习一、实验目的1、熟悉DEBUG调试程序的常用命令;2、掌握利用DEBUG命令查看和修改CPU中寄存器及内存单元内容的方法;3、学会汇编、反汇编、运行和调试简单程序段的方法。二、实验内容和步骤1、Debug程序的启动方法1:键入debu
2、g后回车只是装入Debug程序,并没指定要调试程序;方法2:相继装入Debug程序和要调试的程序格式: 路径debug filename屏幕上出现提示符“-”注意:filename必须是可执行文件,要带扩展名exe2、Debug程序的退出在提示符“-”后输入“Q”回车即可。3、D命令功能:显示数据段中指定单元或单元块的内容。【例1】D1000结果显示128(80H)个字节的内容,一行16个字节,共8行。其中每一行的第一列是数据段段寄存器DS的当前值,第二列是每一行的第一个字节在段中的偏移量,中间是16个单元的内容(十六进制),单元地址依次加1。最右边是该单元内容(十六进制形式的ASCII码)所
3、对应的字符。【例2】D DS:1000结果显示和上例相同,因此在没有定义具体的数据段时,可以省略DS。【例3】D 1234:1000结果显示数据段中以1234H为段地址、偏移量从1000H开始的128个单元的内容。该例定义了显示范围,显示结果的段地址不一定是段寄存器DS中的当前内容,而是一个指定的段地址。【例4】D 1234:1000100F结果显示数据段中以1234H为段地址、偏移量从1000H开始到100FH结束的16个单元的内容。该例不仅定义了具体的段地址,而且定义了显示的起始和结束地址,不一定显示128个字节。4、E命令功能:修改内存单元内容【例1】E 1000该命令的功能是从DS:1
4、000H处修改若干个数据。响应如下:1BD3:1000CD. 这里1BD3H是DS的当前值(每台计算机内容可能不一样),CDH是偏移量为1000H单元的原来内容。输入一个新的数据后,如果按空格键,将显示(修改)相邻高地址1001H单元的内容,输入新数据后再按空格键,将显示(修改)相邻高地址1002H单元的内容,以此类推。如果输入新的数据后回车,将不再提示修改后面的单元内容。【例2】E DS:1000功能和上例相同【例3】E 1234:1000功能是修改数据段中以1234H为段地址、偏移量从1000H开始的单元内容。5、命令U功能:从代码段中指定的位置对机器代码进行反汇编,得到相应的助记符形式的
5、指令。【例1】U 1000功能是从代码段中以CS寄存器的值为段地址,偏移量为1000H开始的地方执行反汇编,一次反汇编32个字节的机器代码。【例2】U若地址省略,如果是第一次使用U命令,则从CS、IP的当前地址处开始反汇编。如果不是第一次使用,则从上一个U命令的最后一条指令的下一单元开始反汇编32个字节。【例3】U CS:1000同上例【例4】U 1234:1000从指定的CS、IP地址开始反汇编【例5】U 1234:1000L9从指定的CS、IP地址开始反汇编,长度不是32个字节,而是9个字节。6、寄存器的显示和修改命令R【例1】R如果R后面什么都不带,这时R命令就用来显示所有寄存器内容,包
6、括标志寄存器中的8个状态标志位的状态,并在最后提示下一条将要执行的指令。【例2】RAX如果R后面跟上一个寄存器的名称,这时R命令就用来显示这个寄存器的内容并等待修改。如RAX,系统将响应显示出AX的内容并在下一行显示出冒号。如果在冒号后键入进值后回车,AX即修改为新值;如果不输入新值而直接回车,则不改变原值。【例3】RF功能是显示和修改标志位状态。注意8位状态标志位不是以0或l的形式显示的,而是用两个字母显示的,这样更直观。字母和状态对应关系如下表所示:标志名 置位 复位溢出Overflow(是/否) OV NV方向Direction(减量/增量) DN UP中断Interrupt(允许/屏蔽
7、) EI DI符号Sign(负/正) NG PL零Zero(是/否) ZR NZ辅助进位AuxiliaryCarry(是/否) AC NA奇偶Parity(偶/奇) PE PO进位Carry(是/否) CY NC系统响应显示当前8个状态标志位的状态,如果直接回车,将不改变标志位的状态。也可以键入其中一个或多个新的状态符,重新设置其状态。键入时可以不考虑标志位的顺序,中间也可以不加空格。7、运行命令G【例1】G=1000 1023功能是从代码段1000H处开始运行程序,到1023H处停止程序执行。【例2】G=1000此处没给出结束地址,则系统会自动在程序应该停止的地方结束。因此在我们编写的汇编语
8、言源程序中,就需要一个程序结束返回到操作系统的指令。【例3】G如G后不带任何参数,则从当前指令即从CS:IP指定的地址开始执行,并一直执行到该停止的地方结束。因为今天是练习DEBUG命令,并没有涉及到具体的程序,所以最好不要使用不带结束地址的G命令,否则会可能因为内存中没有程序结束相关指令而导致死机。8、单步执行命令T【例1】T=10003功能是从代码段偏移量为1000H的地方开始执行3条指令后停下来,并在执行每条指令后显示寄存器的当前内容、状态值和下一条将要执行的指令,IP值自动加1。【例2】T=1000当后面的步数省略时,则从指定地址默认执行1条指令后停下来,并在执行该指令后显示寄存器的当
9、前内容、状态值和下一条将要执行的指令,IP值自动加1。【例3】T功能是从CS、IP的当前值开始执行1条指令后停下来,IP值自动加1。另外,DEBUG还有如小汇编命令A、命名命令N、装入命令L、写命令W等很多命令,这里不再讲述。实验2编辑、汇编、连接、调试简单程序练习一、实验目的1、熟悉编辑汇编源程序的方法;2、掌握汇编程序Masm和链接程序Link的使用方法;3、进一步掌握用Debug调试具体程序、观察参数和运行结果的方法。二、实验内容与步骤1、输入和编辑汇编源程序进入E编辑程序所在目录,假设该程序同Debug程序一样,也在D盘的ASM目录中。D:ASM EDITLX1.ASM如EDIT 后面
10、可以不带文件名,这样它会新建一个文件,此时可以用菜单打开一个文件,或者编辑完毕保存时要提供文件名。如EDIT 后面带一个文件名,它将会打开这个文件。如果这个文件不存在,它就以这个文件名建立一个文件。显然这样更方便。进入编辑环境后输入以下程序:DATASEGMENTMSGDBThis is an example.$DATAENDSSTACKSEGMENTSTACKDW64DUP(?)STACKENDSCODESEGMENTASSUMECS:CODE,DS:DATA,SS:STACK START:MOVAX,DATAMOVDS,AX ;获得数据段的可寻址性MOVDX,OFFSET MSGMOVAH
11、,09H INT21H ;显示字符串MOVAH,4CHINT21H ;程序结束,返回操作系统CODEENDSENDSTART输入完毕后,存盘退出。注意:也可以使用别的编辑软件(如记事本),保存时一定要以ASM为扩展名。使用记事本时,第一次保存时使用的扩展名为txt。存盘的时候要与Masm和Link程序保存在同一个文件夹下(假设都在D:ASM文件夹下)。2、用汇编程序MASM对源程序进行汇编进入Masm.exe汇编程序所在目录,比如该程序也在D盘的ASM中。D:ASM MASMLX1LX1后面可以不跟扩展名ASM(汇编时默认是对ASM进行汇编)。系统响应如下(汇编程序版本不同,响应不太一样):M
12、icrosoft (R) Macro Assembler Version 5.00 Copyright (C) Microsoft Corp 1981-1985, 1987.All rights reserved.Object filename LX1.OBJ: ;生成的目标文件名默认为LX1.OBJ,回车键确认Source listingNUL.LST: LX1;输入列表文件名,如不需要可直接回车Cross-reference NUL.CRF: ;输入交叉索引文件名,如不需要可直接回车50502 + 385338Bytes symbol space free0WarningErrors 0S
13、evereErrors如编译通过,这时D盘的ASM中将会生成一个LX1.OBJ文件。如果编译时发现存在语法错误,系统将给出错误提示(警告性错误和致命性错误)。警告性错误并不影响OBJ文件的产生,如有致命性错误不可能生成对应的OBJ文件,这时必须再对程序进行修改、再汇编,直到没有错误为止。如果在文件名LX1后跟上一个分号,上述提示将省略。3、用链接程序LINK产生可执行文件进入Link.exe汇编程序所在目录,比如该程序也同样在D盘的ASM中。D:ASM LINKLX1后面可也以不跟后缀名.OBJ。系统响应如下:Microsoft (R) Segmented-Executable LinkerV
14、ersion 5.13Copyright (C) Microsoft Corp 1984-1991.All rights reserved.Run File LX1.exe:;生成的可执行文件名默认为LX1.EXE,按回车键确认List File NUL.MAP: ;输入映象文件名, 如不需要可直接回车Libraries .LIB: ;输入库文件名, 如不需要可直接回车如果链接成功,这时D盘的ASM中将会生成一个LX1.EXE文件。同样,如果在文件名后跟上一个分号,上述提示也将省略。4、执行程序因该程序的执行结果是在屏幕上输出一个字符串,可以直接运行程序,通过观察屏幕上是否正确输出该字符串来判
15、断程序是否正确。D:ASM LX1屏幕将会显示:This is an example.5、用DEBUG调试.EXE文件注意:如果程序的执行结果并没有在屏幕上显示,这时不能直接运行程序,只能通过在DEBUG中对它进行调试,通过观察相关内存单元的内容来判断程序是否正确。进入D汇编程序所在目录,比如该程序也在D盘的ASM中:D:ASM DEBUGLX1.EXE ;扩展名必须带上1)反汇编U1C03:0000B8041C MOV AX,1C041C03:00038ED8 MOV DS,AX1C03:0005BA0000 MOV DX,00001C03:0008B409 MOVAH,091C03:000
16、ACD21 INT 211C03:000CB44C MOVAH,4C1C03:000ECD21 INT 211C03:0010 注意:原来的源程序第一行的DATA此时变成了1C04(不同的机器可能不一样)。因此这条指令和后面的指令MOVDS,AX一起用来建立数据段的可寻址性。第一条指令获得系统分配给程序中数据段的段地址,第二条指令将该段地址送到段寄存器DS中。2)观察数据区D1C04:0 1F1C04:0000 54 68 69 73 20 69 73 20-61 6E 20 65 78 61 6D 70This is an examp1C04:0010 6C 65 2E 24 FF B7 4
17、8 36-FF B7 46 36 2A C0 50 E8 le.$.H6.F6*.P.大家看到,最右边是相应数据对应的字符,“54 68 69 73 20 69 73 20 61 6E 20 65 78 61 6D 70 6C 65 2E 24”分别是字符串“This is an example. $”中各字符的ASCII码。注意:因为此时上两条指令还没有执行,还没有将系统分配给程序使用的数据段段地址送到DS中,因此使用D命令时,须采用上述方法,而不能用D DS:01F形式。3)运行程序GThis is an example.Program terminated normally 前面一句话是
18、程序的执行结果,输出一个字符串。后一句话表明程序正常结束。出现这句话的原因就是程序中有一个返回DOS的功能号为4CH的功能调用。4)修改数据区,使程序运行时显示“This is a computer.”。E1C04:0009 computer.$ G = 0This is a computer.Program terminated normallyQC因两个字符串前9个字符相同,从第10个字符开始不一样。因此是采用“E0009”的命令形式。三、自主实验题1、编写计算Y=X2+50的汇编语言源程序,并保存为LX2.ASM文件。2、对LX2.ASM进行汇编和链接,直到形成LX2.EXE可执行文件。
19、3、用DEBUG调试和运行LX2.EXE文件,查看X和Y变量单元结果。多试几个数据,验证程序的正确性。实验3 DOS功能调用一、实验目的1、学习常用的系统功能调用的使用方法。2、掌握在屏幕上输出程序运行结果的方法。3、掌握给程序输入参数的方法。4、进一步掌握DEBUG调试程序的使用方法。二、实验内容及步骤1、在屏幕上显示一个字符【实验要求】编写程序,在屏幕上显示一个字符“A”并换行。【编程思路】单个字符输出,可以利用DOS功能调用的02号功能来实现。入口参数:将需显示字符的ASCII码送DL寄存器;功能号02H送AH寄存器。该程序是在显示“A”后再显示回车换行符号(含0A、0D两个字符)。因此
20、可以使用三次02H功能调用。【参考程序】STACK SEGMENTSTACKDW64DUP (?)STACK ENDSCODE SEGMENTASSUME CS:CODE,SS:STACKSTART:MOVDL,AMOVAH,02HINT21HMOVDL,0DHMOVAH,02HINT21HMOVDL,0A HMOVAH,02HINT21HMOVAH,4CHINT21HCODEENDSEND START注意:在使用一次INT 21H后,除了获得相应的结果外,也将包括AX在内的相关寄存器的内容清0。因此,如后面还需要使用INT 21H,即使调用功能一样,功能号也必须重新输入。2、在屏幕上显示一个
21、字符串【实验要求】编写程序,在屏幕上显示一个字符串“HOW DO YOU DO?”。【编程思路】如果要显示或打印一个字符串,可使用09号功能调用。入口参数:要显示的字符串要先在数据段中定义好,且以“$”为结束标志。使用时,要先将DS:DX指向该缓冲区。DS为该字符串所在数据段的段地址;DX为该字符串的第一个字符在数据段中的偏移量;【参考程序】STACK SEGMENTSTACKDW64DUP(?)STACK ENDSDATA SEGMENTBUFDB HOW DO YOU DO?$DATA ENDSCODE SEGMENTASSUMECS:CODE,DS:DATA,SS:STACKSTART:
22、MOVAX,DATAMOVDS,AXMOVDX,OFFSETBUFMOVAH,09HINT21HMOVAH,4CHINT21HCODEENDSEND START注意:当结果是多个字符但是通过逐个字符连续输出时,也可通过02H功能调用实现。如果要显示的结果不是字符串,而是一个数据,是不能直接用09H功能在显示器上显示的。此时要将该数据的各位转化为相应的ASCII码,才能通过02H号功能调用实现显示(转换方法见后面的“数码转换”实验)。如果屏幕上要显示的字符串中含有字符“$”,这时不能直接使用09号功能调用实现(因09H默认以“$”结束标志)。3、键入单个字符【实验要求】编写程序,等待用户选择。当
23、用户输入的是“Y”,在屏幕上显示“You agree it.”如果用户输入的是“N”,在屏幕上显示“You disagree it.”。如输入的不是“Y”也不是“N”,则在屏幕上显示“Please input again.”。【编程思路】程序在执行过程中如需要用户提供选择或输入一些可变数据,这时可以利用01H号功能,直接从键盘上接收一个字符。出口参数:键入字符的ASCII码将存放AL寄存器中,同时显示在屏幕上。【参考程序】STACK SEGMENT DW64DUP(?)STACK ENDSDATA SEGMENTBUF1DB Please input your choose:$BUF2DB Y
24、ou agree it.$BUF3DB You disagree it.$BUF4DB Please input again.$DATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA,SS:STACKSTART:MOVAX,DATAMOVDS,AXMOVDX,OFFSETBUF1MOVAH,09HINT21HMOVAH,01HINT21HCMPAL,YJZYESCMPAL,NJZNOMOVDX,OFFSETBUF4JMPDONENO: MOVDX,OFFSETBUF3JMPDONEYES:MOVDX,OFFSETBUF2DONE: MOVAH,09HINT21H
25、MOVAH,4CHINT21HCODEENDSEND START注意:调用时程序要等待用户按键,因此使用该功能时,最好先在屏幕上给出一定的信息,提示用户可以按键了,否则用户不好把握按键时机。提示符可以是一个字符,也可以是一个字符串。总之只要使人感到提示含义清楚就可以了。4、键入字符串【实验要求】编写程序,提示用户输入信息。用户从键盘输入一个字符串,并显示在屏幕上。【编程思路】利用DOS功能调用的0AH号功能,直接从键盘上接收一个字符串。入口参数:在内存中事先定义好缓冲区。给缓冲区格式为:第一个字节表示接收的最大字符数(1至255,不能为0);第二个字节保留,用做DOS功能调用后存放实际读入的字
26、符数(不包括回车符)。从第三字节开始存放输入的字符串。调用前要使DS:DX指向该缓冲区的首字节。输入的字符串长度要小于缓冲区的长度,否则,超过的缓冲区长度的输入字符将被视为无效。输入字符串时,以回车符(0DH)作为结束标志。【参考程序】STACK SEGMENTSTACKDW64DUP(?)STACK ENDSDATA SEGMENT BUF1DB Please input a string:$BUF2DB50BUF3DB?BUF4DB50DUP(0)DATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA,SS:STACKSTART:MOVAX,DATAMOVDS,AXMOVDX,OFFSETBUF1MOVAH,09HINT21HMOVDX,OFFSETBUF2MOVAH,0AHINT21HMOVDI,OFFSETBUF3MOVBL,DIMOVDI,OFFSETBUF4MOVBH,00HMOVAL,$MOVDI+BX,ALMOVDL,0AHMOVAH,02HINT21HMOVDL,0DHMOVAH,02HINT21HMOVDX,OFFSETBUF4MOVAH,09HINT21HMOVAH,4CHINT21H CODEENDSEND START