-
实验任务一
1.利用debug加载、跟踪程序
(1)先利用r命令来查看各个寄存器的值
(2)从cx中可知道程序的长度,用cx中的值减去20h(数据段和栈段已分配的空间)得到代码段的长度,用u命令精确反汇编
(3)先执行到000D之前,看看ds是否已成功指向数据段
(4)从上图可以看到ds已指向数据段,然后我们接着执行到程序返回前,即到001D之前,再查看一次数据段的内容
(5)从上图可以看到,数据段没有发生变化
2.书上的问题解答:
(1)程序返回前,data段中的数据为 23 01 56 04 89 07 BC 0A-EF 0D ED 0F BA 0C 87 09
(2)程序返回前,CS=076C,SS=076B,DS=076A
(3)设程序加载后,code段的段地址为X,则data段的段地址为X-2,stack段的段地址为X-1
-
实验任务二
1.利用debug加载、跟踪程序
(1)先利用r命令查看各个寄存器的值
(2)从上图的cx我们可以看到,cx的值与任务一的一样。虽然任务二只定义了两个字数据的数据段和两个字型数据当栈空间,但实际上在内存分配上还是给它们16个字节的空间,于是我用u命令精确反汇编一下
(3)再用g命令执行到000D以前,看看ds是否指向数据段data
(4)从上图看出ds已指向数据段data,再执行到程序返回前,看看数据段data的变化
(5)从上图看出,数据段没有变化
2.书上问题的解答:
(1)程序返回前,data段中的数据为 23 01 56 04
(2)程序返回前,CS=076C,SS=076B,DS=076A
(3)设程序加载后,code段的段地址为X,则code段的段地址为X-2,stack段的段地址为X-1
(4)对于如下定义的段,若段中的数据占N个字节,则程序加载后,该段实际占有的空间为(N/16+1)*16(即数据的分配是以16个字节为单位的)
name segment
:
name ends
-
实验任务三
1..利用debug加载、跟踪程序
(1)同样用r查看各个寄存器的值,并用u精确反汇编
(2)用g命令执行至000D之前,看看ds是否指向数据段data
(3)从上图可以看出,ds指向了数据段data,接着执行到程序返回前,再查看数据段data的值
(4)从上图可以看到,数据段中的值没有变化
2.书上问题的解答:
(1)程序返回前,data段中的数据为 23 01 56 04
(2)程序返回前,CS=076A,SS=076E,DS=076D
(3)设程序加载后,code段的段地址为X,则data段的段地址为X+3,stack段的段地址为X+4
-
实验任务四
1.以实验任务三为例,删除end后面的start,执行看结果,步骤与上面一致
(通过上面的截图,我们可以发现与任务三中的结果完全一致,也就是说,除去了end后面的start,程序仍然能正确执行)
2.再以任务二为例,删去end后面的start,再执行查看结果,步骤与上面一致
(上图注意:此时精确反汇编的不同,变成以cs为段地址,以20h为偏移地址)
(虽然执行的过程有所差异,但是执行后的结果是一致的,即去掉了end后面的start,也能正确执行)
3.书上问题解答:
(1)比较上面的过程与结果,我认为这三个程序去掉了end后面的start都能正确执行。唯一的不同点在于,虽然去掉了start,cs:ip的值会指向程序起始位置的段地址,但实际上随着程序的执行,最后总会将代码段执行完;而加上start之后,cs:ip的值一开始就直接指向了我们的代码段,更方便我们的操作。
-
实验任务五
1.填写的程序代码如下:
start: mov ax,a mov ss,ax ;利用段寄存器ss指向a段的起始位置 mov ax,b mov es,ax ;利用段寄存器es指向b段的起始位置 mov ax,c mov ds,ax ;利用段寄存器ds指向c段的起始位置 mov bx,0 mov cx,8 s: mov al,ss:[bx] mov [bx],al ;将a段数据复制到c段中 mov al,es:[bx] add [bx],al ;将b段数据与c段的数据相加,结果保存在c段中 inc bx ;由于定义的是字节数据,所以只需要将bx加一 loop s mov ax,4c00h int 21h
2.利用debug跟踪、执行
(1)先用r查看各个寄存器的值,再用u反汇编
(2)先执行到000A之前,可以查看a段和b段的数据,a段由ss段寄存器指向,b段由es段寄存器指向
(3)再执行到0022之前,看看c段中的结果
(4)从上图可以看到,实现了将a段和b段中数据的依次相加
3.补充:做完该实验才看到老师的tips,于是决定按照分段利用es的方法,再完成一次
(1)代码如下:
start: mov ax,c mov ds,ax ;利用段寄存器ds指向c段起始地址 mov ax,a mov es,ax ;先利用段寄存器es指向a段起始地址 mov bx,0 mov cx,8 s: mov al,es:[bx] mov [bx],al ;做一个将a段数据复制到c段中的循环 inc bx loop s mov ax,b mov es,ax ;再利用段寄存器es指向b段起始地址 mov bx,0 mov cx,8 s0: mov al,es:[bx] add [bx],al ;再做一个将b段数据加到c段中的循环 inc bx loop s0 mov ax,4c00h int 21h
(2)利用debug跟踪、执行
(先执行到000A之前,看看a段的数据)
(再执行到0018之前,看看c段的数据)
(接着执行到001D之前,查看b段的数据)
(最后执行到程序返回前,看看c段中的结果)
(从上图可以看到,实现了a、b段数据的依次相加)
-
实验任务六
1.填写的代码如下:
start: mov ax,a mov ds,ax ;利用段寄存器ds指向a段 mov ax,b mov ss,ax ;利用段寄存器ss指向b段,让b段作为栈空间 mov sp,16 ;初始化栈顶 mov bx,0 mov cx,8 s: push [bx] add bx,2 loop s mov ax,4c00h int 21h
2.利用debug跟踪、执行
(1)用r查看各个寄存器的值,再用u反汇编
(2)先执行到0005,查看a段数据
(3)最后执行到程序返回前,看看b段中的数据
(从上图可以看到,实现了将a段中的前8个字型数据逆序存储到b段中)
-
总结与体会
1.通过本次实验熟悉并掌握了编写、调试具有多个段的程序,收获非常大
2.我上网搜索了一下关于实验任务二中提到的 “段中数据大小与实际占用空间” 这部分的内容:
3.关于实验任务一、二、三中都提到的,code段、data段、stack段的段地址的关系:
对于任务一和二,data段定义用了16个字节(0~f),stack段定义用了16个字节(10~2f),所以段地址会与代码段相差2和1;而在任务三中,代码段占了32个字节,所以后面定义的data的段地址和stack的段地址会与代码段相差3和4。
4.关于实验任务五,在我一开始写的代码中,除了ds和es之外,我还运用了ss段寄存器,这样就只需要执行一次循环,最后也同样达到了目的。因为我觉得当ss不用来定义栈空间时,它就只是一个普通的段寄存器,所以一样可以派上用场。