一、实验目的

  • 能分析各种跳转指令构成的程序的运行原理
  • 会用跳转指令构造循环解决应用问题
  • 体验显示缓冲区的要求

二、实验内容过程记录

任务1-奇怪的程序?(教材实验8)

人工分析下面的程序,然后再在Debug程序中单步执行,观察每一步完成后的结果,并解释出现的现象。

程序如下:

assume cs:codesg
codesg segment
   mov ax,4c00h
   int 21h
   start: mov ax, 0
   s: nop
   nop
   mov di, offset s
   mov si, offset s2
   mov ax, cs:[si]
   mov cs:[di], ax
   s0:jmp short s
   s1:mov ax, 0
   int 21h
   mov ax, 0
   s2:jmp short s1
   nop
codesg ends
end start

将连接好的程序通过Debug加载后单步运行。下面是运行过程中的截屏:
程序加载后,u命令查看指令如下:

assembly4-1-1

t命令单步执行:

assembly4-1-2
assembly4-1-3

在s0:jmp short s之前的步骤,都是正常的。

但是跳转到s处后,并没有执行预期的jmp short s1,而是执行jmp 0000,跳转到开头,u命令查看内存中的指令:

assembly4-1-5
assembly4-1-4

此时发现,s处的指令奇怪的变成了jmp 0000。

经过分析后得知:jmp跳转指令的机器指令是表示了一个地址的位移量,并不包含目的地址,s2处的指令代码为F6EB,它表示的含义是ip向后移动8个地址长度;所以在s处的指令经过修改之后,变成F6EB了,它原本的ip为后移8个位置,所以从它0008的位置后移8个地址就是0000,翻译成汇编指令就是jmp 0000 了。所以以后复制跳转指令时要格外注意。

任务2-植入程序的程序

编程序,将beg_copy到end_copy的代码复制到0:200H处

assume cs:codeseg

codeseg segment

start:

...

beg_copy:

mov ax, 0

add ax, ax

wait

end_copy: nop

 

codeseg ends

end start

 

源程序:

assume cs:codesg
codesg segment
start:mov ax,cs
   mov ds,ax  ;将程序段的地址赋值到ds中
   mov ax,0
   mov si,offset beg_copy ;获取beg_copy的地址
   mov es,ax
   mov di,200h
   mov bx,offset end_copy ;获取end_copy的地址
 
   copy:cmp si,bx  ;对地址进行对比
   jnb stop  ;当复制到结尾时停止
   mov al,ds:[si] ;将数据按位复制
   mov es:[di],al
   inc si
   inc di
   jmp copy
   stop: mov ax,4c00h
   int 21h
   beg_copy:
   mov ax,0
   add ax,ax
   wait
   end_copy:nop
codesg ends
end start

直接运行可执行文件,如下图:
进入debug程序,用U命令查0:200H处的代码:

assembly4-2

 

任务3 - 循环程序的实现

在下面的数据段中,给出了全班3名同学OS、AL、SE、DB课程的成绩,请编程计算出平均成绩,写在 ? 处。

要求写两个版本的程序:(1)用jcxz指令构造循环;(2)用cmp指令、jxxx系列指令配合构造循环。

datasg segment

db '201558501111','MMTJAB  ',90,100,76,89,?

db '201558501112','ZhangAP ',97,82,79,88,?

db '201558501113','ShaoXL  ',77,98,89,91,?

db 4 ;这是课程门数,将要用于作除数,偏移量为75

datasg ends

下面是程序,以及运行后的截图:

  • 源程序:
assume cs:codesg,ds:datasg
 
datasg segment
   db '201558501111','MMTJAB  ',90,100,76,89,0
   db '201558501112','ZhangAP ',97,82,79,88,0
   db '201558501113','ShaoXL  ',77,98,89,91,0
   db 4
datasg ends
 
codesg segment
   start:mov ax, datasg
      mov ds, ax
      mov cx,3  ;共处理3组数据
      mov bp,20 ;基址
 
    s0:mov dx, cx ;外层循环将cx保存到dx中
      mov cx,4  ;每行累加4个数
      mov ax,0  ;累加中间寄存器
      mov si,0  ;偏移地址
 
     s:mov bx,0
      mov bl,ds:[si+bp]
      add ax, bx;每个数都加到ax中
      inc si
      sub cx,1
      jcxz a
      jmp short s
 
    a:div byte ptr ds:[75]
      mov ds:[bp+si],al
      mov cx,dx
      add bp,25
      sub cx,1
      jcxz stop
      jmp short s0
 
   stop:mov ax,4c00h
      int 21h
 
codesg ends
end start

 

(2)

源程序:

assume cs:codesg,ds:datasg
datasg segment
db '201558501111','MMTJAB ',90,100,76,89,0
db '201558501112','ZhangAP ',97,82,79,88,0
db '201558501113','ShaoXL ',77,98,89,91,0
db 4
datasg ends
 
codesg segment
   start:mov ax, datasg
      mov ds, ax
      mov bp,20 ;基址
      mov dx,1
 
   s0:
      mov ax,0 ;累加中间寄存器
      mov si,0 ;偏移地址
      mov di,1
 
    s:mov bx,0
      mov bl,ds:[si+bp]
      add ax, bx;每个数都加到ax中
      inc si
      inc di
      mov cx,4 ;每行累加4个数
      cmp cx,di
      jnb s
 
      div byte ptr ds:[75]
      mov ds:[bp+si],al
      mov cx,3 ;共3行
      add bp,25
      inc dx
      cmp cx,dx
      jnb s0
 
    mov ax,4c00h
    int 21h
 
codesg ends
end start

运行截图:
 
assembly4-3
 

任务4 - 向显存中传入字符(即实验9

编程序,在屏幕的中间分别显示绿色、绿底红色、白底蓝色的字符串 'YantaiUniversity'

提示:要计算出“屏幕的中间”对应的内存单元,然后将字符以及对应的属性字节写入到内存中。

下面是程序,以及运行结果

源程序:

assume cs:codesg,ds:datasg
datasg segment
    w db 'YantaiUniversity'
datasg ends
 
codesg segment
   start:mov ax,datasg
      mov ds,ax
      mov bx,0B800h   ;显存的段地址
      mov es,bx   ;附加段指向显存段地址
      mov si,0
      mov di, 780H+80-16    ;屏幕第12行中间
      mov cx,16  ;共循环16 
    s:
      mov al,w[si] ;依次读取数组中的数
      mov es:[di],al ;写入显存
      inc di ;显存地址后移
      mov al, 02H   ;属性字节,由此控制显示效果
      mov es:[di],al ;属性写入每个字符的后面
      inc si
      inc di
      loop s
       
      mov si,0
       
      mov cx,16
      mov di, 820H+80-16    ;屏幕第13行中间
   s1:
      mov al,w[si]
      mov es:[di],al
      inc di
      mov al, 24H   ;属性字节,由此控制显示效果
      mov es:[di],al
      inc si
      inc di
      loop s1
       
      mov si,0
       
      mov cx,16
      mov di, 8C0H+80-16    ;屏幕第14行中间
   s2:
      mov al,w[si]
      mov es:[di],al
      inc di
      mov al, 71H   ;属性字节,由此控制显示效果
      mov es:[di],al
      inc si
      inc di
     loop s2
       
  mov ax,4c00h
  int 21h
 
codesg ends
end start

 

运行截图:
 
assembly4-5
 

三、实验总结

O(事实):本次实验主要练习了,跳转指令的灵活使用方法,以及多种寻址方式的灵活使用。

R(感受):汇编语言用起来的确很强大,可以修改自己想要修改的内存内容,跳转指令是很灵活的,需要注意jmp指令中的机器码,表示的是偏移地址量。

I(思考):多种寻址方式以及多种程序控制方式,使得汇编语言可以实现各种各样的我们想要实现的功能

D(决定):以后要更加深入的学习汇编语言,深入了解其运作的机制。

点击此处下载实验报告:
  Download


人与人之间是平等的,自由的。