实验 5 编写、调试具备多个段的程序

1、实验目的

1. 理解和掌握将数据、代码、栈放入不一样段的程序的编写和调试编程

2. 理解具备多个段的汇编源程序对应的目标程序执行时,内存分配方式框架

 

2、实验准备

1. 结合第 6 章教材和课件,复习第 6 章内容spa

2.  复习第 3 章「栈」的知识debug

 

3、实验内容

实验任务(1)3d

下载课程公邮中的程序框架放入,masm.exe,link.exe同文件夹下,用DS BOX挂载到masm文件夹后调试

使用以前写好的process.bat文件简化编译,链接,执行操做。code

顺利执行,下面对ex5_1.exe debug。blog

 

使用r命令查看各寄存器的值,下面咱们要精确反汇编程序段,首先经过r命令能够看出cx=0042,内存

即这段程序所占的字节数是42h,但这还包括数据段和栈段,数据段有8个数据,16个字节,即io

10h,栈段也是16个字节,即10h。因此代码段长度为42-20=22h,CS:IP = 076C:0000,因此若要精确反汇编

,应该是u 0000 0021(注:代码段,栈段,数据段均是从0开始的)。成功反汇编代码段。

题目要求的是程序返回前,即 mov ax,4c00   int 21前,根据反汇编结果可知,因执行到CS:001d前,使用

g命令达到这一效果。

已经能够看出CPU执行程序,程序返回前,cs=076c,ss=076b,ds=076a.

接下来须要查看数据段,已知数据段长16个字节,使用d命令查看内存中的数据 d 0 f(注:代码段,栈段,数据段均是从0开始的)

能够看出,程序返回前的数据段并无改变(读数据时注意是小端法存储的)。

使用g命令执行完程序,程序加载后,能够看出DS = CS-2,SS=CS-1;

根据实验结果完成了书中填空。

实验任务(2)

前期步骤同(1)

同实验(1),首先经过r命令能够看出cx=0042,即这段程序所占的字节数是42h,但这还包括数据段和栈段,数据段有2个数据,4个字节,栈段也是2个字节。

因此代码段长度为42-8=34h,CS:IP = 076C:0000,因此若要精确反汇编

,应该是u 0000 0033(注:代码段,栈段,数据段均是从0开始的)。但这里我却并无作到成功反汇编,显然咱们所给反汇编范围大了

经过查看源代码,给出猜想,虽然栈段和数据段都只给出了4个字节,但从第13行代码看出

,这里设sp = 16,栈顶设为了16,也就是说这里的栈仍然是16个字节的,尽管没有填满,因此状况应该和

实验(1)是同样的,固然这只是个人猜想

精确反汇编的结果与实验(1)同样

题目要求的是程序返回前,即 mov ax,4c00   int 21前,根据反汇编结果可知,因执行到CS:001d前,使用

g命令达到这一效果。

已经能够看出CPU执行程序,程序返回前,cs=076c,ss=076b,ds=076a.

接下来须要查看数据段,已知数据段长4个字节,使用d命令查看内存中的数据 d 0 3(注:代码段,栈段,数据段均是从0开始的)

能够看出,程序返回前的数据段并无改变(读数据时注意是小端法存储的)。

使用g命令执行完程序,程序加载后,能够看出DS = CS-2,SS=CS-1;

这里的状况和实验(1)是同样的

考虑对于以下定义的段:

name segment

...

name ends

经过查阅资料得知

若是段中数据占N个字节,则程序加载后,该段实际占有的空间为 [(N+15)/16]*16。

数据段都是以16个字节对齐,不足16字节按16字节算,这也解释了对于实验任务(2)个人

疑问。

根据实验结果完成书中填空

实验任务(3)

与实验任务(1)(2)相同,前面的步骤在这里就省略截图分析了,直接从debug后开始

这里的精确反汇编又出现了问题,根据以前的实验总结,应该是CX = 44-10-10=24h,

因此应该是 u 0 23进行精确反汇编,但这里却仍是应该 u 0 21。缘由不得而知。

修改后精确反汇编

已经能够看出CPU执行程序,程序返回前,cs=076a,ss=076e,ds=076d.

接下来须要查看数据段,已知数据段长4个字节,使用d命令查看内存中的数据 d 0 3(注:代码段,栈段,数据段均是从0开始的)

能够看出,程序返回前的数据段并无改变(读数据时注意是小端法存储的)。

使用g命令执行完程序,程序加载后,能够看出DS = CS+3,SS=CS+4;

根据实验结果完成书中填空

实验任务(4)

若是将(1),(2),(3)题中的最后一条伪指令“end start”改成“end”(也就是说,不指明程序的入口个),则哪一个程序仍然能够正确执行?请说明缘由。

对三个程序内容进行修改编译链接执行后

对第一个程序的反汇编结果,能够发现该程序已经没有办法正确执行

程序2也是没法正确执行

程序3能够正确执行

由于若是没有end start就会默认以IP=0开始执行,而不是从start开始执行。

而实验内容(3)的data和stack都在code以后,因此IP原本就为0,能够正确执行。

 

实验任务(5)

(1) 汇编程序源代码

补全代码以下:

分析:编写code代码,将a段b段中的数据依次相加,将结果存在c段中。

bx用于偏移量,初始置显然为0,dx为求和寄存器初始值也是0,cx用于设置循环次数,这里有a,b中均有8个字

,因此循环次数也就是8次。

循环体部分:每次将a段中和b段中内容依次加到寄存器dx中,最后将结果存到c段中。

这里须要注意,循环体开头部分每次都要将用于求和的寄存器bx置为0,不然上次的结果会接着累加。

偏移量bx每次增长一次,大致步骤就是这样,具体细节在这里就不作过多的阐述。

(2)  在 debug 中调试程序截图,截图中包括以下信息:

① 在实现数据相加前,逻辑段 c 的 8 个字节

进入debug,而后查看寄存器,精确反汇编(CX-10h-10h-10h=29h),u 0 28

根据精确反汇编结果,执行到循环体外,使用d命令查看数据段内容,发现并无作到预期,

但查看栈段内容时,发现第二行到第四行显示的内存符合预期,缘由不得而知。

② 执行完实现加运算的代码后,逻辑段 c 的 8 个字节

使用g命令执行完成后,发现用d命令查看数据段内存内容仍然不符合预期,但栈段内存内容

符合,第四行确实是前两行相加的结果。

根据①和②的调试,证明了程序确实正确的实现数据相加。

 

实验任务(6)

(1) 汇编程序源代码

补全代码以下:

分析:编写code段中的代码,用push指令将a段中的前8个字型数据,逆序存储b段中。

须要逆序存储,天然的便想到了栈段,这里须要设一个栈段,须要将b段前8个字数据逆序存储,

8个字数据即16个字节,栈顶SP = 16 =10h,栈底为SS = SP+1.

这里只要设置8次循环,将a段中前8个字型数据push到栈中,即实现了题目要求。

(2)   debug 中调试程序截图,截图中包括以下信息:

进入debug,使用r命令进行查看,精确反汇编(CX-20h-10h=1fh)u 0 1e

成功精确反汇编。

① 在 push 操做执行前,查看逻辑段 b 8 个字单元信息截图

根据反汇编结果,使用g命令执行到push操做前,用d命令查看内存中内容,长度为a段的

32(20h)个字节加上b段16(10h)个字节,d ds:0 29.

能够看出b段8个字全是0.

② 执行 push 操做,而后再次查看逻辑段 b 8 个子单元信息截图

使用g命令执行完成后,用d命令查看,发现b的8个字单元为a段前8个字节的逆序.

 根据①和②的调试,验证程序确实正确的实现题目要求。

 

5、总结与体会

 1.经过这次实验理解和掌握将数据、代码、栈放入不一样段的程序的编写和调试

理解具备多个段的汇编源程序对应的目标程序执行时,内存分配方式。

2.咱们开始逐渐进入到汇编编程中,汇编也并非很枯燥的,在实验过程当中只有不断的探索尝试才能真正

体会汇编的乐趣。

相关文章
相关标签/搜索