循环程序设计_第1页
循环程序设计_第2页
循环程序设计_第3页
循环程序设计_第4页
循环程序设计_第5页
已阅读5页,还剩38页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第第5章章 循环循环程序设计程序设计5.1 简单循环简单循环程序程序5.2 多重循环程序多重循环程序5.1 简单循环简单循环程序程序 在汇编语言中,实现循环的指令有两种,一种是LOOP指令,它适用于循环次数已知的情况,用CX 寄存器保存循环次数;另一种是JMP指令,它根据当前的条件判断可以跳转到不同的地方继续执行程序,适用于根据循环条件执行循环的情况。 例例5.1 判断一个数是否为素数。在数据段中存有一个字数据m,判 断m是否是素数并输出判断的结果。 题目分析:判定数m是否为素数,用m除以i,i从2到m-1,如果所有余数都不为0,则m 为素数,若任何一步中的余数为0,都可以立即中止循环,而断定

2、m 不是素数。 data segment m dw 4 mess1 db It is a prime!,13,10,$ mess2 db It is not a prime!,13,10,$ data ends stack segment dw 100h stack ends code segment main proc far assume cs:code,ds:data,ss:stack start: push ds sub ax,ax push ax mov ax,data mov ds,ax mov ax,stack mov ss,ax mov cx,2 decd: lea si,m

3、mov ax,ds:si cwd div cx cmp dx,0 jz break inc cx cmp cx,si jl decd yes: lea dx,mess1 jmp disp break: lea dx,mess2 disp: mov ah,09 int 21h exit: mov ax,4c00h int 21h main endp code ends end start 在汇编程序中,要注意,各个指令的默认条件。如本题中,指令div cx执行之前,要先把数据m存入寄存器ax,因为DIV cx 指令的执行为:(dx,ax)/(cx),商(ax),余数(dx),所以,div指令执行

4、之前先进行符号扩展。同时注意,div指令执行之后,ax寄存器的内容不再是m了,而变成了除法得到的商,所以,下一次的循环体执行时,不仅让除数cx增加1,还要注意恢复ax的值,重新存入m的值。因此,循环体从decd: lea si,m mov ax,ds:si cwd div cx 开始,而不是仅仅从cwd div cx开始。 例例5.2 在未排序的数组中查找并删除某数。在附加段中存放一个未排序的字数组list,第一个字中存放数组长度。从键盘输入一个数字,放在ax寄存器中,在数组list中查找是否存在该数字。如果存在,则把它从数组中删除,否则,输出未找到该数的信息 题目分析:先从键盘输入一个数字字

5、符,转化为数字存入ax中。然后,依次与数组list中的各个数字比较,查找是否存在该数,如果存在,则把数组中后面的元素依次向左移动一个位置,实现删除该数的目的,同时修改数组长度。若查找的数字正好位于数组末尾,则直接修改数组长度。 查找的过程,利用比较指令即可;删除的部分,利用循环指令把didi+2。查找结束时di 指针指向的就是要删除的元素的位置,也即实现didi+2的di初始值 data segment list dw 10,2,34,0,1,56,90,32,-8,0,12 data ends stack segment dw 100h stack ends code segment mai

6、n proc far assume cs:code,es:data,ss:stack start: push ds sub ax,ax push ax mov ax,data mov es,ax mov ds,ax mov ax,stack mov ss,ax mov ah,01 int 21h sub al,30h cbw lea di,list cld push di mov cx,es:di cmpdig: add di,2 cmp ax,es:di je delt loop cmpdig pop di jmp short exit delt: jcxz dec_cnt next: mo

7、v bx,es:di+2 mov es:di,bx add di,2 loop next dec_cnt: pop di dec word ptr es:di exit: ret 例5.3 在一个已经排序的数组中插入一个数据,使数组保持原有的排序顺序。假定数组的首地址和末地址分别存放在arrhd和arrend中,数组元素均为正数。 题目分析:数组的首末地址已知,所以可以确定数组的长度。本题要插入一个数据n,先确定插入位置si,然后把位于si右边的数据向右移动一个位置,腾出插入位置,最后把n放置在si的位置即可 关键是确定插入位置si,从数组的尾部向头部查找,逐字取出元素值k与n比较,如果kn,

8、继续向头部查找,同时把si位置的元素向右移动一个位置,腾出位置等待插入数据;否则,即k=n,元素值k的下一个位置si+2就是插入位置,把数据n插入si+2位置就可以了。 注意边界情况。如果n大于所有元素,则直接插入arrend的下一个位置;如果n小于所有元素,则算法从尾部一直比较查找到首部,同时所有元素都向右移动了一个位置,所以把n插入arrhd的位置,关键是循环的结束条件,为了统一使用一个循环条件,可以在arrhd的左边位置arrhd-2插入一个负数-1,这样n一定大于-1,可以及时结束循环 data segment arrhd dw 3,5,7,8,12,14,23,56 arrend d

9、w 62 n dw 1 data ends code segment main proc far assume cs:code,ds:data start: push ds sub ax,ax push ax mov ax,data mov ds,ax mov ax,n mov arrhd - 2 ,0ffffh mov si,0 compare: cmp arrendsi,ax jle insert mov bx,arrendsi mov arrendsi+2,bx sub si,2 jmp short compare insert: mov arrendsi+2,ax exit: mov

10、ax,4c00h int 21h main endp code ends end start 例例5.4 计算数据Y中1的个数并存入存储单元中 题目分析:先测试数据本身是否为0,若为0,直接结束;若不为0,则先判断最高位是否为1,若为1(sf=1),在计数器加1,若不为1(sf=0),则准备下一次测试:数据逻辑左移1位,把次高位左移到最高位,再判断最高位是否为1 data segment Y dw 1001011000110101B count dw ? data ends code segment main proc far assume cs:code,ds:data start: pus

11、h ds sub ax,ax push ax mov ax,data mov ds,ax mov ax,y mov cx,0 repeat: test ax,0ffffh jz exit jns shift inc cx shift: shl ax,1 jmp repeat 例例5.5 求n!,并把运算结果存入存储单元题目分析:n! = n* (n-1)*(n-2)* *2 *1。利用LOOP指令的特性,每执行一次,计数器CX自动减少1,当CX值为0时停止,所以,初始值(CX)n,(AX)=1,执行循环体(DX,AX)(AX)*(CX) data segment n dw 5 result d

12、w ? data ends stack segment dw 100h stack ends code segment main proc far assume cs:code,ds:data,ss:stack start: push ds sub ax,ax push ax mov ax,data mov ds,ax mov ax,stack mov ss,ax mov cx,n mov ax,1 cwd L1: mul cx loop L1 mov result,ax mov result+2,dx exit: ret 例例5.6 数据段中有一个字数组M,求数组中绝对值最大的元素,把绝对值

13、最大的数存放在存储单元max中 ,并把位置存入max+2存储单元中。 题目分析:由于绝对值都是非负数,所以,先把最大值cx初始化为0。然后判断各个元素的正负,对于正数,直接与cx进行比较大小;对于负数,先取相反数,然后与cx进行大小比较。求得最大值后,再把当前的最大值的位置si-2存入存储单元中 dataseg segment M dw 0,2,-5,9,6,3,-18,-4,1,-7 max dw ?,? dataseg ends prognam segment main proc far assume cs:prognam,ds:dataseg start: push ds sub ax,

14、ax push ax mov ax,dataseg mov ds,ax mov al,11 mov cx,0 lea si,M next: dec al jz exit mov bl,si mov bh,si+1 test bh,80h jz BJ neg bx BJ: add si,2 cmp cx,bx jnb next xchg cx,bx push si sub si,2 mov dx,si mov max+2,dx pop si jmp next exit: mov max,cx ret main endp prognam ends end start5.2 多重循环多重循环程序程序

15、 例例5.7 冒泡法排序,把数组中的元素按照从小到大的顺序排序。数组的长度存放在n单元中。 题目分析:冒泡排序的思想,对相邻的两个数进行比较,把较小的元素向左移动,较大的元素向右移动。经过第一趟的n-1次比较,最大的元素排到了最右边。第二趟的比较,从第一个比较到n-1个,共比较n-2次。共进行n-1趟比较 data segment a dw 2,34,0,1,56,90,0,-8,0,12 n dw 10 data ends code segment main proc far assume cs:code,ds:data start: push ds sub ax,ax push ax mo

16、v ax,data mov ds,ax mov cx,n dec cx loop1: mov di,cx mov bx,0 loop2: mov ax,abx cmp ax,abx+2 jle continue xchg ax,abx+2 mov abx,ax continue: add bx,2 loop loop2 mov cx,di loop loop1 exit: mov ax,4c00h int 21h main endp code ends end start 例例5.8 已知数据段中有两个长度为8的字数组X和Y,其元素值分别为X1,X2,X10;Y1,Y2, ,Y10。变成实现如

17、下计算并把结果存入数组Z Z1=X1+Y1 Z2=X2+Y2 Z3=X3-Y3 Z4=X4-Y4 Z5=X5 - Y5 Z6=X6+Y6 Z7=X7-Y7 Z8=X8-Y8 Z9=X9+Y9 Z10=X10+Y10 题目分析:本题进行10次计算,可以用循环次数已知的循环指令loop实现。但是每次执行的循环体有加减两种运算,为了区别每次执行加法还是减法运算,可以设置标志位,根据标志位是1还是0确定减法还是加法运算。 本题要进行10次加减运算,所以设置10个标志位,这种标志位叫做逻辑尺。根据本题的运算,设置的逻辑尺为0011011100B。从右边低位开始执行相应的操作,用逻辑右移指令把最右边的低位移入CF,根据CF的值确定执行的操作 data segment X dw 2,34,0, 1, 56,90,0, -8, 0, 12 Y dw 9,23,43,-2,0, 1, 14,87,-45, -3 Z dw 10 dup(?) logicrul dw 0011011100B data ends code segment main proc

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论