电气知识|循环程序的设计

   更新日期:2017-03-26     来源:建材之家    作者:安防之家    浏览:57    评论:0    
核心提示:循环程序可以有两种结构形式,如图所示。一种是DO_WHILE结构形式;另一种是DO_UNTIL结构形式。 例5.1  设内存BUFF开始的单元中依次存放着30个8位无符号数,求它们的和并放在SUM单元中,试编写程序。 分析:这是一个求累加的程序。程序如下: MOV  SI,BUFF  ;设地址指针 MOV CX,30    ;设计数初值 X

2017款较新中空玻璃设备已推进河北市场

推荐简介:感谢石家庄杨总和赵总对博因数控的支持与认可采购中空玻璃设备一套(1800内外合生产线,丁基胶涂布机,全自动中空玻璃封胶线,还有辅助设备铝条切割锯,砂带磨边机设备)由于客户订货周期较短,博因人也是在保证设备质量的前提下加班加点生产并连夜发货,下图为中空玻璃生产线发货照片山东博因数控机械有限公司  电话:***联系人:巩经理手机:***优质的产品, 良好的服务,为广大用户创造更大的价值★博因数控承......
安防之家讯:循环程序可以有两种结构形式,如图所示。一种是DO_WHILE结构形式;另一种是DO_UNTIL结构形式。

例5.1设内存BUFF开始的单元中依次存放着30个8位无符号数,求它们的和并放在SUM单元中,试编写程序。

分析:这是一个求累加的程序。程序如下:

MOVSI,BUFF;设地址指针

MOV CX,30;设计数初值

XOR AX,AX ;设累加器初值

AGAIN: ADD AL,[SI]

ADC AH,0

INCSI

DEC CX

JNZAGAIN ;循环累加

MOV SUM,AX

例5.2在给定个数的16位数串中,找出大于零、等于零和小于零的个数,并紧跟着原串存放。

分析:这是一个统计问题,须设定三个计数器分别统计三种情况下的结果。程序如下:

DATA SEGMENT

BUFF DWX1,X2,X3,……,Xn

COUNTEQU$-BUFF ;此时,COUNT的值为BUFF所占的字节数

PLUSEDB ?

ZERO DB ?

MINUS DB ?

DATA ENDS

CODE SEGMENT

ASSUME CS:CODE,DS:DATA

ASSUME ES:DATA,SS:STACK

BEGIN: MOV AX,DATA

MOV DS,AX

MOV CX,COUNT

SHR CX,1 ;相当于除2,正好为BUFF中的数据个数

MOV DX,0;设定计数器初值

MOV AX,0;设定计数器初值

LEABX,BUFF

AGAIN: CMPWORD PTR[BX],0

JAEPLU;大于等于0,则转PIU

INCAH ;<0,则统计

JMPNEXT

PLU: JZZER ;=0,则转ZER

INCDL;>0,则统计

JMPNEXT

ZER:INCDH;=0,则统计

NEXT:INCBX

INCBX

LOOP AGAIN

MOV PLUS,DL

MOV ZERO,DH

MOV MINUS,AH

MOV AX,4C00H

INT21H

CODEENDS

END BEGIN

例5.3 在ADDR单元中存放着16位数Y的地址,试编写一程序,把Y中1的个数存入COUNT单元中。

分析:这是一个循环统计的工作。采用DO—WHILE结构,做16次循环,每次将最高位移入CF中进行测试,先判断结果是否为0,若为0,则结束;否则统计计数后循环重复。

程序如下:

DATA SEGMENT

ADDR DWNUMBER

NUMBER DWY

COUNTDW?

DATAENDS

PROGRAM SEGMENT

MAINPROC FAR

ASSUME CS:PROGRAM,DS:DATA

START: PUSH DS

MOV AX,0

PUSH AX

MOV AX,DATA

MOV DS,AX

MOV CX,0 ;计数器初值=0

MOV BX,ADDR

MOV AX,[BX] ;取Y送AX

REPEAT: TEST AX,0FFFFH;检测是否为全0

JZEXIT ;是,则转EXIT

JNSSHIFT;最高位是0,则转SHIFT

INCCX ;最高位是1,则统计计数

SHIFT:SHLAX,1 ;处理下一位

JMPREPEAT

EXIT:MOV COUNT,CX

RET

MAINENDP

PROGRAM ENDS

END START

在实际应用中,有些问题较复杂,一重循环不够,必须使用多重循环实现,这些循环是一层套一层的,通常称为循环嵌套。

例5.4 在DS所决定的数据段,从偏移地址BUFFER开始顺序存放100个无符号16位数,现要编写程序将这100个字数据从大到小排序。

分析:排序的方法有很多,在这里,我们采用冒泡法。

程序如下:

LEADI,BUFFER ;DI作为指针,指向要排序的数据

MOV BL,99 ;循环控制初值

NEXT0:MOV SI,DI

MOV CL,BL

NEXT3:MOV AX,[SI];取一个数

ADD SI,2

CMP AX,[SI];与下一个数进行比较

JNCNEXT5;大于等于时转移

MOV DX,[SI];否则,两数交换

MOV [SI-2],DX

MOV [SI],AX

NEXT5:DEC CL ;控制进行交换的次数

JNZNEXT3

DEC BL ;修改交换的次数

JNZNEXT0

HLT

例5.5试编制一个程序,把BX寄存器中的二进制数以十六进制的形式显示在屏幕上。

解析:根据题目要求应将BX中的内容从左到右每4位一组显示出来,共显示4个十六进制数位。如果显示的数位是0~9,则把4位二进制数加上30H,转换成相应的ASCII码30H~39H;如果是A~F,则应加上37H(30H+7),转换成ASCII码41H~46H。显示字符可以使用DOS功能调用来实现。下图是程序框图。



以binihex.asm为文件名,建立源程序如下:

; binihex.Asm

prognam segment ; 定义代码段

main proc far

assume cs:prognam 

start:; 程序从此处开始执行 

; 为正常返回DOS而设置堆栈

pushds 

sub ax,ax 

pushax 

; 下面是程序的主要部分

movch,4 ; 4组二进制数

rotate:

movcl,4; 每组4个二进制位

rolbx,cl; 把bx循环左移4位

moval,bl; 暂存bl到al中

andal,0fh; 仅保留al的低4位

addal,30h ; 转换成ASCII码

cmpal,3ah ; 要显示的数大于9 ?

jl printit ; 如果数在0~9之间则显示

addal,7h; 数在A~F之间则调整

printit:

movdl,al; 把要显示字符的ASCII码送dl

movah,2 ; 功能号2送ah

int21h ; DOS功能调用

decch; (ch)-1

jnzrotate; 4组都处理完?否,循环处理下一组

ret; 返回DOS

main endp; 主程序main结束

prognamends; 代码段结束

endstart; 结束汇编

例5.6 从键盘接收十进制数并存入 BX

prognam segment

main proc far

assume cs:prognam 

start:

push ds

subax,ax

push ax

mov bx, 0

newchar:

mov ah, 1;键盘输入

int 21h

sub al, 30h

jl exit;<0退出

cmp al, 9

jg exit;>9退出

cbw



例5.7 从键盘接收十六进制数并存入 BX



codesegment 

assume cs:code, ds:data 



start:

mov ax,4c00h

int 21h; 返回DOS

codeends

endstart



例5.8 将正数N插入一个已整序的字数组的正确位置。该数组的首地址和末地址分别为ARRAY_HEAD和ARRAY_END,其中所有数均为正数且已按递增的次序排列。



; 定义数据段

datarea segment

xdw?

array_headdw23,37,49,52,65,78,99

array_enddw105

n dw32 

datarea ends

; 定义代码段

prognam segment

mainprocfar; 主程序部分 assume cs:prognam,ds:datarea

start: ; 程序从此处开始执行

pushds

subax,ax 

pushax

movax,datarea

movds,ax

; 程序的主要部分

movax,n

movarray_head-2,0ffffh; -1送array_head-2单元

movsi,0

compare:

cmparray_end[si],ax

jleinsert

movbx,array_end[si]

movarray_end[si+2],bx

subsi,2

jmpshort compare

insert:

movarray_end[si+2],ax

ret

mainendp; 主程序main结束

prognam ends

endstart

例5.9设有数组X (,…,) 和Y (,…,) ,编程计算数组Z (,…,) ,其中:







; 定义数据段

datarea segment 

x dwx1,x2,x3,x4,x5,x6.x7,x8,x9,x10

ydwy1,y2,y3,y4,y5,y6,y7,y8,y9,y10

zdwz1,z2,z3,z4,z5,z6,z7,z8,z9,z10

logic_rule dw00dch

datarea ends

; 定义代码段

prognam segment

mainprocfar

assume cs:prognam,ds:datarea

start: 

pushds 

subax, ax 

pushax 

movax, datarea 

movds, ax 

movbx, 0

movcx, 10

movdx, logic_rule

next: 

movax, x[bx]

shrdx, 1

jcsubtract

addax, y[bx]

jmpshort result

subtract:

subax, y[bx]

result:

movz[bx], ax

addbx, 2

loopnext

ret

mainendp 

prognamends

endstart

这种设置逻辑尺的方法是很常用的。例如,在矩阵运算中,为了跳过操作数为0的计算,经常采用这种方法。又如,把一组数据存入存储器时,如果其中数值为0的元素很多,也可用这种方法设立一个每位表示一个下标的逻辑尺(这样的逻辑尺可能占有几个字,由数组的长度确定。),0元素就可不占有存储单元了。每个标志只占一位,如果要表示的特征数更多,则每个标志可占有几位,而在处理方法上是完全相同的。设立标志位的方法除了如逻辑尺那样可静态地预置外,还可以在程序中动态地修改标志位的值,以达到控制的目的,下例将说明这种方法。

例5.10 试编制一程序:从键盘输入一行字符,要求第一个键入的字符必须是空格符,如不是,则退出程序;如是,则开始接收键入的字符并顺序存放在首地址为BUFFER的缓冲区中(空格符不存入),直到接收到第二个空格符时退出程序。

这一程序要求接收的字符从空格符开始又以空格符结束,因此程序中必须区分所接收的字符是否是第一个字符。为此,设立作为标志的存储单元FLAG。一开始将其置为0,接收第一个字符后可将其置1。整个程序的框图如图所示。



;定义数据段

datareasegment

buffer db 80 dup(?)

flag db ?

datareaends

;定义代码段

prognamsegment 

main proc far

assume cs:prognam,ds:datarea

start:

push ds

subax,ax

push ax

movax,datarea

movds,ax

leabx,buffer

movflag,0

next: 

movah,01

int21h

test flag,01h

jnz/jnefollow

cmpal,20h

jnz/jneexit

movflag,1

jmpnext

follow: 

cmpal,20h

jz/jeexit

mov[bx],al

incbx

jmpnext

exit: 

ret 

mainendp 

prognam ends 

endstart 



例5.11 有一个首地址为A的N字数组,请编制程序使该数组中的数按照从小到大的次序整序。

解析:这里采用起泡排序算法实现数组整序。从第一个数开始依次对相邻两个数Ki和Ki+1进行比较,若Ki≤Ki+1,Ki的位置不动,Ki+1继续和Ki+2比较;若Ki>Ki+1,则两者交换位置,Ki+1(交换前的Ki)继续和Ki+2比较。

(气泡算法,多重循环) 32,85,16,15, 8



; 定义数据段

dsegsegment

n equ5 ; 数组中数的个数

a dwn dup(?)

dseg ends

; 定义代码段

csegsegment

mainprocfar

assume cs:cseg, ds:dseg

start:

movax,dseg

movds,ax

movcx,n

deccx; 设置count1

loop1:

movdi,cx ; 保存count1

movsi, 0; 初始化si

loop2:

movax,a[si]

cmpax,a[si+2]; Ki与Ki+1比较

jlecontinue ; 如果Ki≤Ki+1,不交换

xchg ax,a[si+2]

mova[si],ax ; 如果Ki>Ki+1,交换

continue:

addsi,2; 修改地址

looploop2 ; 内循环

movcx,di ; 恢复count1

looploop1 ; 外循环

movax,4c00h

int21h

mainendp

csegends

endstart

安防之家专注于各种家居的安防,监控,防盗,安防监控,安防器材,安防设备的新闻资讯和O2O电商导购服务,敬请登陆安防之家:http://anfang.jc68.com/
小程序码
 
打赏
 
更多>文章标签:监控
更多>同类安防监控资讯
0相关评论

推荐图文更多...
点击排行更多...
安防监控商机更多...
安防监控圈更多...
最新视频更多...
推荐产品更多...
水泥之家 | 橱柜之家 | 机械之家 | 水电之家 | 五金之家 | 家电之家 | 饰品头条 | 墙布头条 | 家纺头条 | 塑料头条 | 老姚之家 | 灯饰之家 | 电气之家 | 全景头条 | 陶瓷之家 | 照明之家 | 防水之家 | 防盗之家 | 博一建材 | 卫浴之家 | 区快洞察 | 漳州建材 | 泉州建材 | 三明建材 | 莆田建材 | 合肥建材 | 宣城建材 | 池州建材 | 亳州建材 | 六安建材 | 巢湖建材 | 宿州建材 | 阜阳建材 | 滁州建材 | 黄山建材 | 安庆建材 | 铜陵建材 | 淮北建材 | 马鞍山建材 |
建材 | 双碳之家 | 企业之家 | 移动社区 | 关于我们  |  联系方式  |  使用协议  |  版权隐私  |  网站地图 | 排名推广 | 广告服务 | 积分换礼 | RSS订阅 | sitemap | 粤ICP备14017808号
(c)2015-2017 BO-YI.COM SYSTEM All Rights Reserved
Powered by 安防之家