汇编实验五 利用跳转指令构造循环

一、实验目的

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

二、实验内容过程记录

任务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

程序的执行结果将是:

可以正常结束

将连接好的程序加载后单步运行。

下面是运行过程中看到的代码变化的截屏:

(特别注意程序未开始执行时s处和s2处对应的指令及机器码,以及程序执行到s0处时,s处对应的指令和机器码。)

1.指令:mov ax,0000

指令描述:把0值送入ax寄存器

2.指令:nop

指令描述:预留一字节空间,两个nop就是一个字的空

3.指令:mov di, offset s
指令描述:将s的偏移地址0008存入di中

4.指令:mov si, offset s2
指令描述:把s2的偏移地址0020存入si

5.指令: mov ax, cs:[si]
指令描述:将cs:[si]中的数据存入ax,si中存的是0020,而cs为076A,且076A:0020指向的是EBF6,所以将EBF6存入ax中,ah存放F6,al存放EB

6.指令:mov cs:[di], ax
指令描述:将ax中存放的EBF6放入cs:[di]中,此时cs为076A,di为0008,所以是将ax中的EBF6存入076A:0008中,覆盖刚刚预留的一个字的内存空间,并且EBF6对应的指令为jmp 0000,使用u命令即可看见对应的指令

7.指令:s0:jmp short s
指令描述:进行jmp转移指令,跳转到标号为s的地址,s对应的偏移地址为0008,所以会跳转到刚刚覆盖上的jmp 0000指令

8.指令:jmp 0000
指令描述:跳转到076A:0000的指令

9.指令:mov ax,4c00h

             int 21h
指令描述:进行程序返回

从这个程序中,我学到了

CPU 在执行 jmp 指令时并不需要转移的目的地址,而是通过位移来定位转移后指令的地址。这样做的好处是,方便程序段在内存中的浮动装配,使带转移的程序在内存中的不同位置都可以正确执行,因为跳转指令只涉及目的地址的偏移而不是地址。

其中,转移位移通过标号处的地址减去 jmp 指令后的第一个字节的地址得到,所以此时的位移可能为负数。在汇编语言中,转移的位移使用补码表示。

任务2- 循环程序的实现

在下面的数据段中,给出了全班3名同学OS、AL、SE、DB课程的成绩,请编程计算出平均成绩,写在 ? 处。要求用jcxz指令构造循环

datasg segment

  db '201658501101','ZhangSan',90,100,76,89,0

  db '201658501102','LiSi    ',97,82,79,88,0

  db '201658501103','WangWu  ',77,98,89,91,0

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

datasg ends

下面是程序流程图:

下面是程序,以及运行后的截图,程序中已经加入了必要的注释:

开始的时候使用了loop循环去实现本题:

然后又使用jcxz改了一下上面的代码,如下图:

经过对比,发现两者有一些相似之处:

运行结果:

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

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

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

下面是程序

运行结果如下:

三、实验总结

我从实验中学到了

1.跳转指令只涉及目的地址的偏移而不是地址。其中,转移位移通过标号处的地址减去 jmp 指令后的第一个字节的地址得到,所以此时的位移可能为负数。在汇编语言中,转移的位移使用补码表示。

2.80*25彩色字符模式显示缓冲区结构,内存地址B8000H~BFFFFH,编程中要加上0在最开头,不然就错了。0B8000H~0BFFFFH;向这个地址空间写入数据,写入的内容将 立即出现在显示器。

       3.显示器可以显示25行,每行80个字符(00 00),每个字符有256中属性。(背景色、前景色、闪烁、高亮等组合信息)

       4.一个字符在显示缓冲区要占两个字节(00 00),分别存放字符ascii和属性。一屏的内容在显示缓冲区占4000个字节。

    5.显示缓冲区分8页,显示第0页的内容就是0B8000H~B8F9F

产生的问题及我的解决方案:

开始看了很久任务一,感觉应该是不能正常返回的。后来仔细单步执行发现。解决任务一的关键是将标号 s2 处的指令 jmp short s1 赋值到标号 s 处,由于转移指令使用位移表示,真正赋值的内容是 EBF6 而非 jmp short s1。

任务二的时候 写完之后运行发现程序卡死了,单步执行发现程序进入了死循环,经过分析发现判定条件 jcxz ok 的位置出现了问题,应该是先判断所取的值是否为0然后在进行+1取下一个值的操作。

任务三开始没有头绪,查阅网上资料跟看书上知识明白了显存的模式以及原理

题目要在屏幕中间,就应该在第12行显示第一串字符,每行0~159个字符,11*160=1760(6E0H)刚好是第12行首地址;

我的感受:

CPU 在执行 jmp 指令时并不需要转移的目的地址,而是通过位移来定位转移后指令的地址。我觉得这样做的好处是,方便程序段在内存中的浮动装配,使带转移的程序在内存中的不同位置都可以正确执行。

jcxz指令的功能相当于 if(cx==0) jmp short 标号;

loop指令的功能相当于 cx--; if(cx!=0) jmp short 标号;

将一道题用两种指令来写发现它们是有很大的相似之处的,它们都是短转移,对IP修改范围都是-128~127,并且在对应的机器码中包含的是转移的位移,而不是目的地址。

汇编也是可以实现结构体的,另外汇编语言可以直接修改显存使屏幕上的每个点发生变化

由此体会汇编语言其实也是很强大的!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

❀桃李不言

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值