首页
社区
课程
招聘
“没有风”的汇编实验报告专题(更新至10)
发表于: 2007-10-23 09:15 78400

“没有风”的汇编实验报告专题(更新至10)

2007-10-23 09:15
78400

///////////////////////////////////////////////////////////////////////////////////////////
北极星2003 注: 把多个实验报告合为一个专题
实验1:1楼
实验2:10/11楼
实验3:无
实验4:18楼
实验5:23/24楼
实验6:29楼
实验7:34楼
实验8:40楼
实验9:42楼
///////////////////////////////////////////////////////////////////////////////////////////

实验1        查看CPU和内存,用机器指令和汇编指令编程
1.预备知识:DEBUG的使用
        在以后所有的实验中,都将用到DEBUG程序,首先学习一下它的用法。
(1)什么是DEBUG
                DEBUG是DOS、WINDOWS都提供的实模式(8086方式)程序的调试工具。使用它,可以查看CPU各种寄存器中的内容,内存的情况和在机器码跟踪程序的运行。
(2)我们用到的DEBUG功能
        用DEBUG的R命令查看、改变CPU寄存器的内容:
        用DEBUG的D命令查看内存中的内容:
        用DEBUG的E命令改写内存中的内容:
        用DEBUG的U命令将内存中的机器指令翻译成汇编指令:
        用DEBUG的T命令执行一条机器指令:
        用DEBUG的A命令以汇编指令的格式在内存中写入一条机器指令:
DEBUG命令比较多,共有20多个,但上述6个命令是和汇编语言学习密切相关的。在以后的实验中,我们还会用到一个P命令。
(3)进入DEBUG
        DEBUG是在DOS方式下使用的程序。我们在进入DEBUG前,应先进入到DOS方式。用以下方式可以进入DOS:
        ①重启计算机后,进入DOS方式,此时我们进入的是实模式的DOS。
        ②在WINDOWS中进入DOS方式,此时进入的是虚拟8086模式的DOS。
(4)用R命令查看、改变CPU寄存器的内容
        我们已知道了AX、BX、CX、DX、SS、IP这6个寄存器,现在看一下它们之中的内容,如图2.1所示。其他寄存器SP、BP、SI、DI、DS、ES、SS、FLAGS(标志寄存器)        等先不予理会。

图2.31 使用R命令查看CPU中各个寄存器中的内容

注意CS和IP的值,CS=0CA2,IP=0100,也就是说,0CA2=0100处的指令为CPU当前要读取、执行的指令。在所有的寄存器的下方,DEBUG还列出了CS:IP所指向的内存单元处的所存放的机器码,并将它翻译为汇编指令。可以看到,CS:IP所指向的内存单元为0CA2:0100此处存放的机器码为027548,对应的汇编指令为ADD DH,[DI+48](这条指令的含义我们还不知道,先不必探究)。
DEBUG输出的右下角还有一个信息:“DS:0048=0”,以后会进行说明,这里同样不必深究。
还可以用R命令来改变寄存器中的内容,如图2.32所示。

图2.32        用R命令修改寄存器AX中的内容
若要修改一个寄存器中的值,比如AX中的值,可以用R命令后加寄存器名来进行,输入“R AX”后按ENTER键,将出现“:”作为输出提示,在后面输入要写入的数据后按ENTER键,即完成了对AX中内容的修改。若想查看一下修改的结果,可再用R命令查看,如图2.33所示。

图2.33 用R命令修改CS和IP中的内容
在图2.33中,一进入DEBUG,用R命令查看,CS:IP指向0B39:0100,此处存放的机器码为40,对应的汇编指令是INC AX.
接着,用R命令将CS修改为FF00,则CS:IP指向FF00:0200,此处存储的机器码为51,对应的汇编指令是PUSH CX。
(5)用DEBUG的R命令查看内存中的内容
        用DEBUG的D命令,可以查看内存中的内容,D命令的格式较多。我们这里只介绍在以本次实验中用到的格式。
        如果想知道内存10000H处的内容,可以用“D 段地址:偏移地址”的格式来查看,如图2.34所示。

                        图2.34        用D命令查看内存1000:0处的内容

        使用“D 段地址:偏移地址”的格式,DEBUG将列出从指定的内存单元开始的128个内存单元的内容,图2.34中,在使用D 1000:0后,DEBUG列出了1000:0~1000:7F中的内容。
        使用D命令,DEBUG将输出3部分内容,如图2.34所示。
        中间是部分从指定地址开始的128个内存单元的内容,用十六进制的格式输出,每行的输出从16的整数倍的地址开始,最多输出16个单元的内容。从图中,我们可以知道,内存1000:0的内容是61:内存1000:10~1000:1F中的内容全部在第一行:内存1000:10中的内容是6D,内存1000:1处的内容是61:内存1000:10~1000:1F中的内容全部在第二行。注意在每行的中间有一个“-”,它将每行的输出分为两部分,这样便于查看。比如,要想从图中找出,1000:6B单元中内容,可以从1000:60找到行,“-”前面是1000:60~1000:67的8个单元,后面是1000:68~1000:6F的8个单元,这样我们就可以从1000:68单元向后数3个单元找到1000:6B单元,可以看到,1000:6B中的内容为67H。
        左边是每行的起始地址。
        右边是每个内存单元中的数据对应的可以显示的ASCII码字符。比如内存单元1000:0、1000:1、1000:2中存放的数据是72H、64H、73H,它对应的ASCII字符分别是”r”、”d”、”s”;内存单元1000:36中的数据是0AH,它没有对应可显示的ASCII字符,DEBUG应用”.”来代替。
注意:我们看到的内存中的内容,在不同的计算机中是不一样的;也可能每次用DEBUG看到的内容都不相同,因为我们用DEBUG看到的都是原来就在内存中的内容,这些内容受随时都有可能心迹的系统环境的影响。当然,我们也可以改变内存,寄存器中的内容。
        使用D 1000:9查看1000:9处的内容,DEBUG将怎样输出呢?如图2.35所示。

                                图2.35 查看1000:9处的内容

        DEBUG从1000:9开始显示,一直到1000:88,一共是128个字节。第一行中的1000:0~1000:8单元中的内容不显示。
        在一进入DEUBG后,用D命令直接查看,将列出DEBUG预设的地址的内容,如图2.36。
        在使用“D 段地址:偏移地址”之后,接着使用D命令,可以列出后续的内容,如图2.37所示。
               
图2.36        列出DEBUG预设的地址处的内容
图2.37        列出后续的内容
       
        也可以指定D命令的查看范围,此时采用“D 段地址:起始偏移地址 结尾偏移地址“的格式。比如要看1000:0~1000:9中的内容,可以用”D 1000:0 9“实现。如图2.38所示。
       
图2.38        查看1000:0~1000:9单元中的内容
       
        如果我们就想查看内存单元10000H中的内容,可用图2.39中的任何一种方法看到,因为图中的所有“段地址:偏移地址“都表示了10000H这一物理地址。

图2.39        用三种不同的段地址和偏移地址查看同一个物理地址中的内容

(6)用DEBUG的E命令改写内存中的内容
        可以用E命令改写内存中的内容,比如,要将内容1000:0~1000:9单元中的内容分别写为0、1、2、3、4、5、6、7、8、9,可以用它“E 起始地址 数据 数据 数据。。。“的格式来进行,如图2.40所示。

图2.40 用E命令修改从1000:0开始的10个单元的内容

        图2.40中,先用D命令查看1000:0~1000:F单元的内容,再用E命令修改从1000:0开始的10个单元的内容,最后用D命令查看1000:0~1000:F中的内容的变化。
        也可以采用提高的方式来一个一个地改写内存中的内容,如图2.41所示。

图2.41        用E命令修改从1000:0开始的4个单元

        如图2.41中,可以用E命令提高的方式来逐个地修改从某一地址开始的内存单元中的内容,以从1000:10单元开始为例,步骤如下:
        ①输入E 1000:10,按ENTER键。
        ②DEBUG显示起始地址1000:0010,和第一单元(即1000:0010单元)的原始内容:6D,然后光标停在“。“的后面提示输入想要写入数据,此时可以有两个选择:其一为输入数据(我们输入的是D),然后按空格键,则不对当前内存单元进行改写。
        ③当前单元处理完成后(不论是改写或没有改写,只要按了空格键,就表示处理完成),DEBUG将接着显示一个内存单元的原始内容,并提示读者进行修改,读者可以用同样的方法处理。
        可以用E命令向内存中写入字符,比如:用E命令从内存1000:0开始 写入:数值1、字符‘a’、数值3、字符‘c’,可采用图2.42中所示的方法进行:
        从图中2.42中可以看出,DEBUG对E命令的执行结果是,向1000:0、1000:2、1000:4单元中写入数值1,2,3,向1000:1、1000:3、1000:5单元中写入字符”a”,”b”,”c”的ASCII码值:61H,62H,63H。
        也可以用E命令向内存中写入字符串,比如:用E命令从内存1000:0开始写入:数值1、字符串”a+b”、数值2、字符串”c++”、数值3、字符串”IBM”.如图2.43所示。

图2.42        用E命令向内存中写入字符

(7)用E命令向内存中写入机器码,用U命令查看内存中机器码的含义,用T命令执行内存中的机器码。

        如何向内存中写入机器码呢?我们知道,机器码了是数据,当然可以用E命令将机器码写入内存。比如要从内存1000:0单元开始写入这样一段机器码:
        机器码                对应的汇编指令
        B8 01 00                MOV AX,0001
        B9 02 00                MOV CX,0002
        01C8                ADD AX,CX

可用如图2.44中所示的方式进行。

图2.44        用E命令将机器码写入内存

如何查看我们写入的或内存中原有的机器码所对应的汇编指令呢?可以用U命令进行。比如可以用U命令将从1000:0开始的内存单元中的内容翻译为汇编指令,并显示出来。如图2.45所示。

        图2.45中,首先用E命令向从10000:0开始的内存单元中写入了8个字节的机器码:然后用D命令查看内存1000:0~1000:1F数据(从数据的角度看一下我们写入的内容):最后用U命令查看从1000:0开始内存单元中的机器指令和它们所对应的汇编指令。

                U命令的显示输出分为3部分:第一条机器指令的地址、机器指令所对应的汇编指令。我们可以看到:
1000:0处存放的是我们写入的机器码B80100所组成的机器指令,对应的汇编指令是MOV AX,1:
1000:3处存放的是我们写入的机器码B80C00所组成的机器指令、对应的汇编指令是ADD CX,2:
1000:6处存放的是我们写入的机器码01C8所组成的机器指令、对应的汇编指令是ADD AX,CX:
1000:8处存放 的是内存中的机器码是034942所组成的机器指令、对应的汇编指令是ADD CX,[BX+DI+42].

图2.45        用U命令将内存单元中的内容翻译为汇编指令显示

由此,我们可以再次看到内存中的数据和代码没有任何区别,关键在于如何解释。
如何执行我们写入的机器指令?使用DEBUG的T命令可以执行一条或多条指令,简单使用T命令,可以执行CS:IP指向的指令。如图2.46所示。

图2.46        使用T命令执行CS:IP指向的指令

图2.46中,首先用E命令向从1000:0开始的内存单元中写入了8个字节的机器码:然后R命令查看CPU中寄存器的状,可以看到CS=0B39H,IP=0100H,指向内存0B39:0100若要用T从控制CPU执行我们写到1000:0的指令,必须先让CS:IP指向1000:0;用R命令修改CS、IP中的内容,使CS:IP指向1000:0
完成上面的步骤后,就可以使用T命令来执行我们写入的指令了(此时,CS:IP指向我们的指令所在的内存单元)。执行T命令后,CPU执行CS:IP指向的指令,则1000:0处的指令B8 01 00(MOV AX,0001)得到执行,指令执行后,DEBUG显示输出CPU中寄存器的状态。
注意,指令执行后,AX中的内容被改写为1,IP改变为IP+3(因为MOV AX,0001的指令长度为3个单元),CS:IP指向下一条指令。
接着图2.46,我们可以继续使用T命令执行下面的指令。如图2.47所示。

图2.47 用T命令继续执行

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

(8)用DEBUG的A命令以汇编指令的形式在内存中写入机器指令,直接以汇编指令的形式写入指令。为此,DEBUG提供了A命令。A命令的使用方法如图2.48所示。

                        图2.48 用A命令向从1000:0开始的内存单元中写入指令

        图2.48中,首先用A命令,以汇编语言向从1000:0开始的内存单元中写入了几条指令,然后用D命令查看A命令的执行结果,可以看到,在使用A命令写入指令时,我们输入的是汇编指令,DEBUG将这些汇编指令翻译为对应的机器指令,将它们的机器码写入内存。
        在使用A命令写入汇编指令时,在给出的起始地址后面直接按ENTER键表示操作结束。
        如图2.49中,简单地用A命令,从一个预设的地址开始输入指令。

图2.49        从一个预设的地址开始输入指令

               

                               
本次实验中需要用到的命令
        查看、修改CPU中寄存器的内容:R命令
        查看内存中的内容:D命令
        修改内存中的内容:E命令(可以写入数据、指令、在内存中,它们实际上没有区别)
        将内存中的内容解释为机器指令和对应的汇编指令:U命令
        执行CS:IP指向的内存单元处的指令:T命令
        以汇编指令的形式向内存中写入指令:A命令

        在预备知识中,详细讲解了DEBGU基本功能和用法,在汇编语言的学习中,DEBGU是一个经常用到的工具,在预备知识中,应该一边看书,一边在机器上操作。

        前面提到,我们的原则是:以后甤的,以后再说,所以在这里只讲了一些在本次实验需要用到的命令的相关使用方法,以后根据需要,我们会讲解其它的用法。
       
2.实验任务
(1)使用DEBGU,将下面的程序段写入内存,逐条执行,观察每条指令执行后,CPU中相关寄存器中的内容的变化。

        机器码                        汇编指令
        B8 20 40                MOV AX,4E20H
        05 16 14                ADD AX,1416H
        BB 00 20                MOV BX,2000H
        01 DB                        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                        AD AH,AL
64 00                        MOV AH,0
00 D8                        ADD AL,BL
04 9C                        ADD AL,9CH

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

(2)将下面的3条指令写入从2000:0开始的内存单元中,利用这3条指令计算2的8次方。
        MOV AX,1
        ADD AX,AX
        JMP        2000:0003

(3)查看内存中的内容
        PC机主板中的ROM中写有一个生产日期,在内存FFF00H~FFFFFH的某几个单元中,请找到这个生产日期并试图改变它。
        提示:如果读者对实验的结果不理解,请仔细阅读第1章的1.15节。

(4)向内存从B8100H开始的单元中填写数据,如:
        -E        B810:0000 01 01 02 02 03 03 04 04 
        请读者:先填写不同的数据,观察产生的现象:再改变填写的地址,观察产生的现象。
        提示:如果读者对实验结果不理解,请仔细阅读第1章中的1.15节。

总结:经过这次实验,我学到了许多宝贵的知识,现列举如下:
1.        学会了使用R命令查看CPU中的各个寄存器的内容
2.        学会了使用R命令修改各个寄存器中的内容
3.        学会了使用D命令查看某寄存器中的内容
4.        学会了使用D命令来列出DEBUG预设的地址及其后续地址内容
5.        学会了使用多种不同的段地址和偏移地址查看同一物理地址中的内容的方法
6.        学会了使用E命令修改从某地址开始的存储单元的内容
7.        学会了使用E命令向内存中写入字符、字符串、机器码的方法
8.        学会了使用U命令将内存单元中的内容翻译为汇编指令显示的方法
9.        学会了使用T命令执行CS:IP指向的指令的方法
10.学会了使用A命令向某地址开始的单元写入指令的方法
11.学会了使用A命令向一个预设的地址输入指令的方法
12.学会了向内存中输入一段指令并执行以及观察相应寄存器的内容的变化的方法
13.学会了使用3条指令计算2的N次方的方法
14.学会了使用通过查看ROM中数据来了解自己主板的生产日期的方法
15.更深入的了解了8086将各类存储器看作一个逻辑存储器的概念
16.更深入的了解了8086机内存地址空间分配原理。
这次实验,使我受益非常大。以上是我在做实验后的一点总结心得。


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 7
支持
分享
最新回复 (81)
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
good good study
day day up
2007-10-23 09:43
0
雪    币: 218
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
NaX
3
good good study
day day up
2007-10-23 10:05
0
雪    币: 247
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
『Win32/Win64编程』
2007-10-23 10:40
0
雪    币: 424
活跃值: (1874)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
5
貌似我学汇编以来从来都没写过DOS程序,更没用过DEBUG了
过度一下就够了
2007-10-23 10:42
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
支持!!
高手在成为高手以前,是痛并快乐着的.
2007-10-24 17:56
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
支持!!!!!!!
有点初学的味道
2007-10-25 12:28
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
支持!!!!!!!
学习了
2007-10-25 12:29
0
雪    币: 486
活跃值: (13)
能力值: ( LV9,RANK:430 )
在线值:
发帖
回帖
粉丝
10
实验2        用机器指令和汇编指令编程
1.        预备知识:DEBUG的使用
前面实验中,讲了DEBUG一些主要命令的用法,这里,我们再补充一些关于DEBUG的知识。

(1)        关于D命令

从上次实验中,我们知道,D命令是查看内存单元的命令,可以用:
D 段地址:偏移地址的格式查看指定的内存单元的内容,上次实验中,D命令后面的段地址和偏移地址都是直接给出的。

现在,我们知道段地址是放在段寄存器中的,在D命令后面直接给出段地址,是DEBUG提供的一种直观的操作方式。D命令是由DEBUG执行的,DEBUG在执行“D 1000:0”这样的命令时,也会先将段地址1000送入段寄存器中。

DEBUG是靠什么来执行D命令的?当然是一段程序。

谁来执行这段程序?当然是CPU。

所以,DEBUG在其处理D命令的程序段中,必须有将段地址送入段寄存器中的代码。

段寄存器有4个:CS、DS、SS、ES,将段地址送入哪个段寄存器呢?

首先不能是CS,因为CS:IP必须指向DEBUG处理D命令的代码,也不能是SS,因为SS:SP要指向栈顶。这样只剩下DS和ES可以选择,放在哪里呢?我们知道,访问内存的指令如“MOV AX,[0]”等一般都默认段地址在DS中,所以DEBUG在执行如:“D 段地址:偏移地址”这种D命令时,将段地址送入DS中比较方便。

D命令也提供了一种符合CPU机理的格式:“D 段寄存器:偏移地址”,以段寄存器中的数据为段地址SA,列出从SA:偏移地址开始的内存区间中的数据。以下是4个例子:

①-R DS
 :1000
-D DS:0                                ;查看从1000:0开始的内存区间中的内容
②-R DS
  :1000
 -D DS:10 18   ;查看从1000:10~1000:18中的内容
③-D CS:0                                ;查看当前代码段中的指令代码
④-D SS:0                                ;查看当前栈段中的内容

(2)        在E、A、U命令中使用段寄存器

在E、A、U这些可以带有内存单元地址的命令中,也可以同D命令一样,用段寄存器表示内存单元的段地址。以下是3个例子:

①-R DS
 :1000
 -E DS:0 11 22 33 44 55 6   ;在从1000:0开始的内存区间中写入数据
②-U CS:0                ;以汇编指令的形式,显示当前代码段中的代码,0代码的偏移地址
③-R DS
 :1000
 -A DS:0  ;以汇编指令的形式,向从1000:0开始的内存单元中写入指令

(3)        下一条指令执行了吗?

在DEBUG中,用A命令写一段程序:

MOV AX,2000
MOV SS,AX
MOV SP,10                                ;安排2000:0~2000:F为栈空间,初始化栈顶。

MOV AX,3123
PUSH  AX
MOV AX,3366
PUSH AX                                ;在栈中压入两个数据

仔细看一下图3.18中单步执行的结果,读者发现了什么问题?

在用T命令单步执行MOV AX,2000后,显示出当前CPU各个寄存器的状态和下一步要执行的指令:MOV SS,AX;

在用T命令单步执行MOV SS,AX后,显示出当前CPU各个寄存器的状态和下一步要执行的指令。。。。。,在这里我们发现了一个问题:MOV SS,AX的下一条指令应该是MOV SP,10,怎么变成了MOV AX,3123H

MOV SP,10到哪里去了?它被执行了吗?

我们再仔细观察,发现:

在程序执行前,AX=0000,SS=0B39,SP=FFEE
在用T命令单步执行MOV AX,2000后,AX=2000;SS=0B39;SP=FFEE
在用T命令单步执行MOV SS,AX后,AX=2000;SS=2000;SP=0010

注意,在用T命令单步执行MOV SS,AX前,SS=0B39,SP=FFEE,而执行后SS=2000,SP=0010,SS变为2000是正常的,这正是MOV SS,AX的执行结果。可是SP变为0010是怎么回事?在这期间,能够将SP设为0010的只有指令MOV SP,10,看来,MOV SP,10一定是得到了执行。

那么,MOV SP,10是在什么时候被执行的呢?当然是在MOV SS,AX之后,因为它就是MOV SS,AX的下一条指令。显然,在用T命令执行MOV SS,AX的时候,它的下一条指令MOV SP,10也紧接着被执行了。

整理一下我们分析的结果:在用T命令执行MOV SS,AX的时候,它的下一条指令MOV SP,10也紧接着执行了。一般情况下,用T命令执行一条指令后,会停止继续执行,显示出当前CPU各个寄存器的状态和下一步要执行的指令,但T命令执行MOV SS,AX的时候,没有做到这一点。

不单是MOV SS,AX,对于如:MOV SS,BX,MOV SS,[0],POP SS等指令都会发生上面的情况,这些指令有哪些共性呢?它们都是修改栈段寄存器SS的指令。

为什么会这样呢?要想彻底说清楚这里面来龙去脉,在这里还为时过早,因为这涉及到我们在以后的课程中要深入研究的内容:中断机制,它是我们后半部分课程中的一个主题。现在我们只要知道这一点就可以了:DEBUG的T命令在执行修改寄存器SS的指令时,一条指令也紧接着被执行。

2        实验任务

(1)        使用DEBUG,将上面的程序段写入内存,逐条执行,根据指令执行后的实际运行情况填空。

MOV AX,FFFF
MOV DS,AX
MOV AX,2200
MOV SS,AX
MOV SP,0100
MOV AX,[0]          AX=5BEAH
ADD AX,[2]   AX=5CCAH
MOV BX,[4]   BX=30FCH
ADD BX,[6]   BX=6022H
PUSH AX          SP=00FEH,修改的是字单元2200:00FE
PUSH BX          SP=00FCH,修改的是字单元2200:00FC
POP AX                  SP=00FEH,AX=6022H       
POP BX                  SP=0100H,BX=5CCAH
PUSH [4]                  SP=00FEH,修改的是字单元2200:00FE,内容是30F0H
PUSH [6]                  SP=00FCH,修改的是字单元2200:00FC,内容是2F32H

(2)        仔细观察图3.19中的实验过程,然后分析:为什么2000:0~2000:F中的内容会发生改变?

可能要再便有些实验才能发现其中的规律。如果读者在这里就正确回答了这个问题,那么要恭喜读者,因为读者有很好的惜玉怜香。大多数的读者对这个问题还是比较迷惑的,不过不要紧,因为随着课程的进行,这个问题的答案将逐渐变得显而易见。

                                图3.19用DEBUG进行实验的示例
2007-10-28 22:48
0
雪    币: 486
活跃值: (13)
能力值: ( LV9,RANK:430 )
在线值:
发帖
回帖
粉丝
11
总结:经过这次实验我学到了许多有用的东西:分别是:
   1.我掌握了使用D、U、E、A命令中可以直接使用段寄存器作为表示段地址                 2。我明白了在使用T命令执行修改SS段寄存器的指令时,它会紧接着执行后面的一条指令,即是说执行一次T命令将会连续执行两条指令。
                不过有一点不明白的就是,为什么在定义一个堆栈段的时候,堆栈的内容会发生变化,难道是因为系统自动对它进行初始化了吗?有人可以告诉我吗?我的QQ是420716701.
2007-10-28 23:04
0
雪    币: 218
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
NaX
12
支持一下。。。。。
2007-10-29 08:50
0
雪    币: 1852
活跃值: (504)
能力值: (RANK:1010 )
在线值:
发帖
回帖
粉丝
13
善于总结是很好的学习习惯!
2007-10-29 19:23
0
雪    币: 266
活跃值: (52)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
14
Windows时代,为什么还用DEBUG?
2007-10-30 12:26
0
雪    币: 486
活跃值: (13)
能力值: ( LV9,RANK:430 )
在线值:
发帖
回帖
粉丝
15
因为它简单啊,学起来容易上手啊,而且有成就感。
2007-10-30 19:06
0
雪    币: 218
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
NaX
16
早点转32位汇编吧,你会更有成就感
2007-10-30 21:55
0
雪    币: 486
活跃值: (13)
能力值: ( LV9,RANK:430 )
在线值:
发帖
回帖
粉丝
17
32位我也想转啊,可是一转的话我就要学很多API了,其实16位和32位汇编的基础都是相通的。何必分得那么清楚呢。我现在学习16位,我并没有放弃32位啊,只是一个过渡而已,现在就转32位,我可不想抢跑。
2007-10-31 18:32
0
雪    币: 486
活跃值: (13)
能力值: ( LV9,RANK:430 )
在线值:
发帖
回帖
粉丝
18
实验4        [BX]和loop的使用
(1)        编程,向内存0:200~0:23F依次传送数据0~63(3FH).  
                        ;----------------------------------------------
                        ;ex5-1.asm
                        ;-----------------------------------------------
                        ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                        assume cs:code                        ;;
                        code segment                        ;;
                                mov ax,20h                          ;;
                             mov ds,ax                          ;;
                                mov bx,0                          ;;
                        mov ax,0                        ;;
                                mov cx,0ffh                        ;;
                          s: mov [bx],ax                        ;;
                           inc bx                                ;;
                        inc ax                                ;;
                            loop s                                ;;
                              mov ax,4c00h                        ;;
                             int 21h                                ;;
                        code ends                                ;;
                        end                                                ;;
                        ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(2)        编程,向内存0:200~0:23F依次传送数据0~63(3FH),程序中只能使用9条指令,9条指令中包括“MOV AX,4C00H”和“INT 21H”。
                ;-------------------------------------------
                ;ex5-2.asm
                ;-------------------------------------------
                ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                assume cs:code                                ;
                code segment                                        ;
                        mov ax,20h                                ;
                    mov ds,ax                                ;
                     mov bx,0                                        ;
                    mov cx,0ffh                                ;
                s: mov [bx],bx                                ;
                    inc bx                                        ;
                    loop s                                        ;
                    mov ax,4c00h                                ;
                    int 21h                                        ;
                code ends                                        ;
                end                                                        ;
                ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(3)        下面的程序的功能是将“MOV AX,4C00H”之前的指令复制到内存0:200处,补全程序。上机调试,跟踪运行结果。
;------------------------------------------------
;;ex5-3.asm
;------------------------------------------------
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
assume cs:code                                ;;;;;
code segment                                ;;;;;
        mov ax,code                        ;;;;;
        mov ds,ax                        ;;;;;
        mov ax,0020h                        ;;;;;
        mov es,ax                        ;;;;;
        mov bx,0                                ;;;;;
        mov cx,18h                        ;;;;;
  s:mov al,[bx]                        ;;;;;
        mov es:[bx],al                        ;;;;;
        inc bx                                ;;;;;
        loop s                                ;;;;;
        mov ax,4c00h                        ;;;;;
        int 21h                                ;;;;;
code ends                                        ;;;;;
end                                                ;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                                                        1.把EX5-3.EXE加载入内存中
$debug ex5-3.exe
-r
AX=0000 BX=0000 CX=001D DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=13C7 ES=13C7 SS=13D7 CS=13D7 IP=0000  NV UP EI PL NZ NA PO NC
13D7:0000 B8D713                 MOV AX,13D7
-u
13D7:0000 B8D713                MOV         AX,13D7
13D7:0003         8ED8                MOV         DS,AX
13D7:0005 B82000                MOV         AX,0020       
13D7:0008 8EC0                        MOV         ES,AX
13D7:000A BB0000                MOV         BX,0000
13D7:000D B91800                MOV         CX,0018
13D7:0010 8A07                        MOV         AL,[BX]
13D7:0012 26                        ES:
13D7:0013 8807                        MOV         [BX],AL
13D7:0015 43                        INC         BX
13D7:0016 E2F8                        LOOP        21
13D7:0018 B8004C                MOV         AX,4C00
13D7:001D 00FF                        ADD        BH,BH
13D7:001F 50                        PUSH        AX

                                                2.把0:200的内容反汇编结果如下:
13D7:000D B91800                MOV         CX,0018
13D7:0010 8A07                        MOV         AL,[BX]
13D7:0012 26                        ES:
13D7:0013 8807                        MOV         [BX],AL
13D7:0015 43                        INC         BX
13D7:0016 E2F8                  LOOP         0010
13D7:0018 B8004C        MOV         AX,4C00
13D7:001B CD21                     INT                21
13D7:001D 00FF                   ADD            BH,BH
13D7:001F 50                        PUSH          AX
-u 0:200
0000:0200 46                        INC                SI
0000:0201 07                        POP                ES
0000:0202 07                        ADC        [BP+SI],AL
0000:0204 0A04                          OR                AL,[SI]
0000:0206 1002                          ADC        [BP+SI],AL
0000:0208 3A00                         CMP        AL,[BX+SI]
0000:020A A30354                        MOV        [5403],AX
0000:020D 00A3036E        ADD         [BP+DI+6E03],AH               
0000:0301 00A30388        ADD        [BP+DI+8803],AH
0000:0305 00A303A2        ADD        [BP+DI+A203],AH
0000:0309 00A303FF        ADD        [BP+DI+FF03],AH
0000:0303 0310                  ADD        DX,[BX+SI]
0000:030F 02A90810        ADD         CH,[BX+DI+1008]
-

                                                        3.运行程序至正常结束
13D7:001D 00FF                           ADD        BH,BH
13D7:001F 50                                PUSH          AX
-u 0:200
0000:0200 46                                INC                SI
0000:0201 07                                POP                ES
0000:0202 07                                ADC        [BP+SI],AL
0000:0204 0A04                            OR                AL,[SI]
0000:0206 1002                           ADC        [BP+SI],AL
0000:0208 3A00                           CMP        AL,[BX+SI]
0000:020A A30354                MOV        [5403],AX
0000:020D 00A3036E                ADD         [BP+DI+6E03],AH               
0000:0301 00A30388                ADD        [BP+DI+8803],AH
0000:0305 00A303A2                ADD        [BP+DI+A203],AH
0000:0309 00A303FF                ADD        [BP+DI+FF03],AH
0000:0303 0310                           ADD        DX,[BX+SI]
0000:030F 02A90810                ADD         CH,[BX+DI+1008]
-g 1d

Program terminated normally
-

                                        4.再次将0:200的内容反汇编结果如下:
0000:0301 00A30388                ADD        [BP+DI+8803],AH
0000:0305 00A303A2                ADD        [BP+DI+A203],AH
0000:0309 00A303FF                ADD        [BP+DI+FF03],AH
0000:0303 0310                           ADD        DX,[BX+SI]
0000:030F 02A90810                ADD         CH,[BX+DI+1008]
-g 1d

Program terminated normally
-u 0:200
0000:0200 B8D713           MOV        AX,13D7
0000:0203 8ED8                        MOV        DS,AX
0000:0205 B82000                MOV        AX,0020
0000:0208 8EC0                        MOV        ES,AX
0000:020A BB0000                 MOV        BX,0000
0000:020D B91800                 MOV        CX,0018
0000:0210 8A07                        MOV        AL,[BX]
0000:0212 26                        ES:               
0000:0213 8807                        MOV        [BX],AL
0000:0215 41                         INC                BX
0000:0216         E2F8                LOOP         0210
0000:021B CD21                        INT                21
0000:021D 0AC4                        OR                AL,AH
0000:021F 5E                        POP                SI

对比图1和图4,我们可以看出mov ax,4c00h前的指令序列已经被复制到了0:200处

实验总结:经过这次实验,我掌握了如何将一段内存的数据复制到另一段内存中去,以及如何将程序自身的指令序列复制到另一段内存中去.掌握了如何优化程序来将内存的内容复制到另一段内存去。
这次实验,花费我大量的时间和心血,终于完成了。
2007-11-6 21:30
0
雪    币: 29233
活跃值: (7754)
能力值: ( LV15,RANK:3306 )
在线值:
发帖
回帖
粉丝
19
好习惯。。。
2007-11-7 07:15
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
呵呵...厉害
2007-11-7 17:44
0
雪    币: 424
活跃值: (3353)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
21
好!!!!!
2007-11-7 18:48
0
雪    币: 226
活跃值: (15)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
22
传统的教育
2007-11-7 18:54
0
雪    币: 486
活跃值: (13)
能力值: ( LV9,RANK:430 )
在线值:
发帖
回帖
粉丝
23
实验5  编写、调试具有多个段的程序

(1)        将下面的程序编译连接,用debug加载、跟踪,然后回答问题:
     ;----------------------------------------------------------
                        ;ex5a1.asm
                        ;------------------------------------------------------------
                        ;AUTHOR:IT007
                        ;DATE:2007/11/11
                        ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                        assume cs:code,ds:data,ss:stack
          data                  segment
                                                dw        0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
                        data                 ends
                        stack                segment
                                                dw                0,0,0,0,0,0,0,0
                        stack                ends
                       
                        code                segment
                        start:                mov                ax,stack
                                                mov                ss,ax
                                                mov                sp,16
                                                mov                ax,data
                                                mov                ds,ax
                                                push                ds:[0]
                                                push                ds:[2]
                                                pop                ds:[2]
                                                pop                ds:[0]
                                                mov                ax,4c00h
                                                int                 21h
                        code                ends
                        end                        start
①cpu执行程序,程序返回前,data段中的数据为多少?
  答:  0123h,0456h,0789h,0abch,0defh,0fedh,0cabh,0987h

②CPU执行程序,程序返回前,cs=13D5,ss=13D4,ds=13D3.
③设程序加载后,code段的段地址为x,则data段的段地址为x-12h,stack段的段地址为x-2h.

(2)        将下面的程序编译连接,用debug加载、跟踪,然后回答问题:
                    ;----------------------------------------------------------
                        ;ex5a2.asm
                        ;------------------------------------------------------------
                        ;AUTHOR:IT007
                        ;DATE:2007/11/11
                        ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                        assume                cs:code,ds:data,ss:stack
                        data                segment
                                        dw        0123h,0456h
                        data                ends
                        stack        segment
                                        dw 0,0
                        stack        ends
                       
                        code        segment
                        start:        mov                ax,stack
                                        mov                ss,ax
                                        mov                sp,16
                                        mov                ax,data
                                        push                ds:[0]
                                        mov                ax,4c00h
                                        int                21h
                        code        ends
                        end                start
①cpu执行程序,程序返回前,data段中的数据为多少?
        答:23 01 56 04

②cpu执行程序,程序返回前,  cs=13D5,ss=13D4,ds=13D3
.
③设程序加载后,code段的段地址为x,则data段的段地址为x-12h,stack段的段地址为x-2h.       

④对于如下定义的段:
                        name        segment
                        ………
                        name        ends
        如果段中的数据占n个字节,则程序加载后,该段实际占有的空间为n个字节.

(3)        将下面的程序编译连接,用debug加载、跟踪,然后回答问题:
                   ;----------------------------------------------------------
                        ;ex5a3.asm
                        ;------------------------------------------------------------
                        ;AUTHOR:IT007
                        ;DATE:2007/11/11
                        ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                        assume        cs:code,ds:data,ss:stack
                        code        segment
                        start:        mov                ax,stack
                                        mov                ss,ax
                                        mov                sp,16
                                        mov                ax,data
                                        push                ds:[0]
                                        push                ds:[2]
                                        pop                ds:[2]
                                        pop                ds:[0]
                                        mov                ax,4c00h
                                        int                21h
                        code        ends
                        data                segment
                                        dw        0123h,0456h
                        data                ends
                        stack        segment
                                        dw        0,0
                        stack        ends
                        end                start
①cpu执行程序,程序返回前,data段中的数据为多少?
        答:23 01 56 04
②cpu执行程序,程序返回前,cs=13D3H,ss=13D7H,ds=13D6H.
③设程序加载后,code段的段地址为x,则段的段地址为x-10h,stack段的段地址为x-10h。

(4)        如果将1、2、3题中的最后一条伪指令”end start”改为”end”(也就是说,不指明程序的入口),则哪个程序仍然可以正确执行?请说明原因。
答:第3个程序可以正常运行,因为在前两个程序都未指定程序的入口,
    而程序的前面一部分为数据,即非程序,当程序被加载入内存时,CS:
    IP指 向这些数据,即把这些数据当作指令来执行,这样可能会引发
    意想 不到的后果, 严重的甚至可能导致死机。而第3个程序CS:
    IP指向程序的第一条指令,因 为数据段定义在程序的末尾,因而程
    序可以正常执行。

(5)        程序如下,编写code段中的代码,将a段和b段中的数据依次相加,将结果存到c段中。
         ;----------------------------------------------------------
                        ;ex5a5.asm
                        ;------------------------------------------------------------
                        ;AUTHOR:IT007
                        ;DATE:2007/11/11
                        ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
           assuem        cs:code,ds:a,es:b
                        a        segment
                                db        1,2,3,4,5,6,7,8
                       a        ends

                        b        segment
                                db        1,2,3,4,5,6,7,8
                        b        ends

                        c        segment
                                db        0,0,0,0,0,0,0,0
                        c        ends

                        code        segment
                                start:
                                        ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                                        ;以下为我添加的代码
                                        ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;       
                mov     ax,a               
                mov     ds,ax
                mov     ax,b
                mov     es,ax
                                        mov                 bx,0
                mov     di,0
                mov     cx,8
                                        mov                 ax,0
            s:  mov     al,[bx]
                add     al,es:[bx]
                mov                 [bx+32],al
                inc     bx
                loop    s
                                        mov                   ax,4c00h
                                        int        21h
                        code        ends
                        end                start

(6)        程序如下,编写code段中的代码,用push指令将a段中word数据,逆序存储到b段中。
                        ;----------------------------------------------------------
                        ;ex5a6.asm
                        ;------------------------------------------------------------
                        ;AUTHOR:IT007
                        ;DATE:2007/11/11
                        ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                        assume        cs:code
                        a        segment
                                dw        1,2,3,4,5,6,7,8
                        a        ends
                        b        segment
                                dw        0,0,0,0,0,0,0,0
                        b        ends
                        code        segment
                                start:
                        ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                        ;以下为我添加的代码
                        ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                                        mov     ax,a
                mov     ds,ax

                mov     ax,b
                mov     ss,ax
                mov     sp,10h

                mov     bx,0
                mov     cx,8
            s:
                push    [bx]
                add     bx,2
                loop    s

                mov     ax,4c00h
                int     21h
                       
                        code        ends
                        end                start

总结:经过实验5,我掌握了以下知识:
①我学会了如何将一个段和附加寄存器关联,并将之设置为附加数据段
②我学会了如何使用END伪指令设置IP为一个程序的入口的偏移地址
③我学会了如何程序的数据的段并不是一定要放在程序的前面,它也可以放在程序的末尾,只是这时程序的IP即为程序的入口的偏移地址。
 ④我学会了如何依次将两个数组的元素相加,并把结果依次存储到另一个数组中去。
 ⑤我学会了如何使用MOV指令将一个字节单元的内存传送到8位寄存器中去。
 ⑥我学会了如何使用ADD指令将一个字节型单元的内容加到一个8位寄存器中去。
 ⑦我学会了如何读取附加段字节型单元的内容到一个8位寄存器中去。
 ⑧我学会了如何使用循环(至少执行一次的循环)。
 ⑨我学会了如何使用PUSH指令将一个数组的元素逆序COPY到一个堆栈(或说为数组应该也没什么大碍吧)中去。
 
心得:在这次实验当中,可以说作为一个初学者该犯的错误我都犯了,比如:试图将一个字型单元的内容读取到一个堆栈中去(这明显是不支持的嘛,PUSH指令怎么说也是一个字操作指令:),还有就是试图使用字操作指令进行字节操作(这明显是不能实现的嘛:),不过只要想相应的寄存器改为8位寄存器就支持了,还有就是忘了在程序的最后加上返回系统的指令(一个程序运行结束之后如果不返回调用它的程序,或操作系统或DEBUG,那么它该去哪里呢?我不知道,也许会发生意想不到的事情吧:)。
这次实验最大的收获就是终于掌握了独立编写一个汇编程序的能力,能解决一些日常遇到的小问题,如将一个数组逆序,将一个数组的元素COPY到另一个数组中去。在使用PUSH指令的过程中也让我更加深刻理解了堆栈的运行机制。
2007-11-11 22:52
0
雪    币: 486
活跃值: (13)
能力值: ( LV9,RANK:430 )
在线值:
发帖
回帖
粉丝
24
总结:经过实验5,我掌握了以下知识:
①我学会了如何将一个段和附加寄存器关联,并将之设置为附加数据段
②我学会了如何使用END伪指令设置IP为一个程序的入口的偏移地址
③我学会了如何程序的数据的段并不是一定要放在程序的前面,它也可以放在程序的末尾,只是这时程序的IP即为程序的入口的偏移地址。
 ④我学会了如何依次将两个数组的元素相加,并把结果依次存储到另一个数组中去。
 ⑤我学会了如何使用MOV指令将一个字节单元的内存传送到8位寄存器中去。
 ⑥我学会了如何使用ADD指令将一个字节型单元的内容加到一个8位寄存器中去。
 ⑦我学会了如何读取附加段字节型单元的内容到一个8位寄存器中去。
 ⑧我学会了如何使用循环(至少执行一次的循环)。
 ⑨我学会了如何使用PUSH指令将一个数组的元素逆序COPY到一个堆栈(或说为数组应该也没什么大碍吧)中去。
 
心得:在这次实验当中,可以说作为一个初学者该犯的错误我都犯了,比如:试图将一个字型单元的内容读取到一个堆栈中去(这明显是不支持的嘛,PUSH指令怎么说也是一个字操作指令:),还有就是试图使用字操作指令进行字节操作(这明显是不能实现的嘛:),不过只要想相应的寄存器改为8位寄存器就支持了,还有就是忘了在程序的最后加上返回系统的指令(一个程序运行结束之后如果不返回调用它的程序,或操作系统或DEBUG,那么它该去哪里呢?我不知道,也许会发生意想不到的事情吧:)。
这次实验最大的收获就是终于掌握了独立编写一个汇编程序的能力,能解决一些日常遇到的小问题,如将一个数组逆序,将一个数组的元素COPY到另一个数组中去。在使用PUSH指令的过程中也让我更加深刻理解了堆栈的运行机制。
2007-11-11 22:56
0
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
25
学习~~~
2007-11-11 22:59
0
游客
登录 | 注册 方可回帖
返回
//