汇编语言实验五

时间:2022-07-01 12:47:41

 

  • 实验任务一

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不用来定义栈空间时,它就只是一个普通的段寄存器,所以一样可以派上用场。