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

下载本文档

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

文档简介

循环和分支程序设计书第1页,共104页,2023年,2月20日,星期四5.1概述5.1.1汇编语言程序设计的一般步骤5.1.2流程图返回本章首页第2页,共104页,2023年,2月20日,星期四5.1.1汇编语言程序设计的一般步骤返回本节第3页,共104页,2023年,2月20日,星期四汇编语言程序设计一般有以下几个步骤:(1)分析题意,确定算法;分析和理解题意,找出合理的算法及适当的数据结构;(2)根据算法画出程序流程图;(3)根据流程图编制程序;(4)上机调试程序;

任何程序必须经过调试才能检查出你的设计思想是否正确,以及你的程序是否符合你的设计思想。调试时可用工具——DEBUG进行调试。

程序结构有:顺序、循环、分支、和子程序四种数据结构。(5)运行程序;第4页,共104页,2023年,2月20日,星期四5.1.2流程图1.流程图的概念 流程图是由特定的几何图形、指向线、文字说明来表示数据处理的步骤,形象描述逻辑控制结构以及数据流程的示意图。流程图具有简洁、明了、直观的特点。2.流程图符号表示(1)起止框:表示程序的开始和结束。起止框第5页,共104页,2023年,2月20日,星期四(2)判断框(3)处理框

(4)调用框

第6页,共104页,2023年,2月20日,星期四(5)指向线(6)连接框

返回本节第7页,共104页,2023年,2月20日,星期四

5.2顺序程序设计下面举例说明顺序程序的设计。例5.1数组中存放若干个字节元素。将两个数组对应元素相加,运算结果存放在第三个数组相应结果单元中。本例每个数组有1个元素,每个元素占1字节长。(1)E:\MASM>EDITC100.ASMDATASEGMENTDATA1DB1;被加数

DATA2DB5;加数

DATA3DB0;和初值DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATA第8页,共104页,2023年,2月20日,星期四START:MOVAX,DATAMOVDS,AXMOVSI,0CLC;清进位标志

MOVAL,DATA1[SI]ADCAL,DATA2[SI];字节相加

MOVDATA3[SI],AL

;---------------------输出显示部分------------------MOVBX,OFFSETDATA3MOVDL,[BX]ADDDL,30HMOVAH,2INT21H

;----------------------返回DOS------------------MOVAX,4C00HINT21HCODEENDSENDSTART第9页,共104页,2023年,2月20日,星期四(2)E:\MASM>MASMC100.ASM(3)E:\MASM>LINKC100(4)E:\MASM>C100<ENTER>6(5)E:\MASM>DEBUGC100.EXE第10页,共104页,2023年,2月20日,星期四5.2顺序程序设计【例5.2】试编写一程序计算以下表达式的值。w=(v-(x*y+z-540))/x

式中x、y、z、v均为有符号字数据。设x、y、z、v的值存放在字变量X、Y、Z、V中,结果存放在双字变量W之中,程序的流程图如图5.1所示。返回本章首页第11页,共104页,2023年,2月20日,星期四图5.1顺序运算程序流程图第12页,共104页,2023年,2月20日,星期四源程序如下:DATA SEGMENTX DW 200Y DW 100Z DW 3000V DW 10000W DW 2DUP(?)DATA ENDSSTACK SEGMENTSTACK DB200DUP(0)STACK ENDSCODE SEGMENT ASSUMEDS:DATA,CS:CODE,SS:STACK第13页,共104页,2023年,2月20日,星期四START: MOV AX,DATA MOV DS,AX ;DATA→AX MOV AX,X IMULY ;(X)*(Y)→DX:AX MOV CX,AX MOV BX,DX ;(DX:AX)→(BX:CX)

MOV AX,Z CWD;(Z)符号扩展

ADD CX,AX ADC BX,DX;(BX:CX)+(DX:AX)→(BX:CX)

SUB CX,540 SBB BX,0 ;(BX:CX)-540→(BX:CX)

MOV AX,V第14页,共104页,2023年,2月20日,星期四

CWD ;(V)符号扩展

SUB AX,CXSBBDX,BX;(DX:AX)-(BX:CX)→(DX:AX) IDIV X ;(DX:AX)/X MOVW,AX ;商→W MOVW+2,DX ;余数DX→W+2 MOVAH,4CH INT 21HCODE ENDS ;退出DOS状态

END START第15页,共104页,2023年,2月20日,星期四5.3分支程序设计5.3.1用条件转移指令实现程序分支5.3.2用跳转表实现多路分支返回本章首页第16页,共104页,2023年,2月20日,星期四1、分支程序的结构形式:

分支程序结构可以有两种形式:

一个是二路分支:IF—THEN—ELSE形式;

一个是多路分支:CASE形式;常用的语句:

5.3.1用条件转移指令实现程序分支JZ结果为零JNZ结果不为零JS/结果为负JNS结果为正JL小于JLE小于等于JG大于JGE大于等于第17页,共104页,2023年,2月20日,星期四在某一种确定条件下,只能执行多个分之中一个分支。

例5.3已知X=80,X值在数据段中定义,编写程序:若X>50则

Z=X+Y,否则Z=X-Y,结果存入Z。X,Y,Z均为字数据。

DATA

SEGMENT

XDW80;数据段中DATA

ENDSCODE

SEGMENT

ASSUMEDS:DATA,SS:STACK,CS:CODESTART: MOV AX,DATA

MOV DS,AX

MOVAX,XCMPAX,50JGHIGHSUBAX,YJMPEXITHIGH:ADDAX,YEXIT:MOVZ,AX

MOV AH,4CH INT 21H

CODEENDS END START

第18页,共104页,2023年,2月20日,星期四【例5.4】编写计算下面函数值的程序:

1 X>0Y=0 X=0-1 X<0设输入数据为X、输出数据Y,且皆为字节变量。程序流程图如图5.2所示。第19页,共104页,2023年,2月20日,星期四流程图如下:

图5.2分支运算程序流程图第20页,共104页,2023年,2月20日,星期四【例5.4】编写计算函数值的程序:程序如下:DATA

SEGMENT

X

DB

-10

Y

DB?DATA

ENDSSTACK

SEGMENTSTACK

DB

200DUP(0)STACK

ENDSCODE

SEGMENT

ASSUMEDS:DATA,SS:STACK,CS:CODESTART: MOV AX,DATA第21页,共104页,2023年,2月20日,星期四

MOV DS,AX

MOVAL,X CMP AX,0 ;与0进行比较

JGE A1 ;X≥0转A1 MOV Y,-1 ;X<0时,-1→Y JMP EXITA1:JG

A2 ;X>0转A2 MOV Y,0 ;X=0时,0→Y JMP EXITA2:MOV Y,1 ;X>0,1→YEXIT:MOV AH,4CH INT 21HCODEENDS END START第22页,共104页,2023年,2月20日,星期四【例5.5】求最值

【例5.5】试编一程序,求三个带符号字数据中的最大值,并将最大值存入MAX字单元中。 设三个带符号数分别在三个字变量X、Y、Z中存储。程序流程图如图5.5所示第23页,共104页,2023年,2月20日,星期四

例5.5程序流程图

第24页,共104页,2023年,2月20日,星期四

MOV AX,XCMP AX,Y;X>Y?

JG L1MOVAX,Y ;Y>Z?

CMPAX,ZJG

EXITL2:MOV

AX,ZJMP EXITL1:CMPAX,Z ;X>Z?

JLE L2EXIT:MOV

MAX,AX

MOV

AH,4CH INT

21H第25页,共104页,2023年,2月20日,星期四程序如下:STACKSEGMENTSTACK DB200DUP(0)STACK ENDSDATA SEGMENT

X

DW

30

Y

DW

20

Z DW

10

MAX

DW?DATA ENDS第26页,共104页,2023年,2月20日,星期四CODE SEGMENT

ASSUMEDS:DATA,SS:STACK,CS:CODESTART:MOV AX,DATA MOV DS,AX MOV AX,X CMP

AX,Y ;X>Y?

JG

L1 MOV

AX,Y ;Y>Z?

CMP

AX,Z JG

EXITL2:MOV

AX,Z JMP EXIT

第27页,共104页,2023年,2月20日,星期四L1: CMP

AX,Z ;X>Z?

JLE L2EXIT: MOV

MAX,AX

MOV

AH,4CH INT

21HCODE

ENDS END

START返回本节第28页,共104页,2023年,2月20日,星期四2、多路分支程序设计方法.

程序分支一般用条件转移命令来产生,连续用条件转移命令使程序产生多个分支。第29页,共104页,2023年,2月20日,星期四例5.6在DI寄存器中,数组中的第一个单元存放着数组长度,在AX中有一个无符号数,要求在数组中查找(AX),如找到则使CF=0,并在SI中给出该元素在数组中的偏移地址;如未找到则使CF=1.方法:顺序折半法.

(1)折半查找法先取有序数组的中间元素与查找值比较,如相等则查找成功;(2)如查找值大于中间元素,则再取高半部的中间元素与查找值相比较;(3)如查找值小于中间元素,则再取低半部的中间元素与查找值比较;如此重复,直到查找成功或最终未找到该数为止。

第30页,共104页,2023年,2月20日,星期四例5.6在附加段中,有一个按从小到大顺序排列的无符号数组,其首地址存放在DI寄存器中,数组中的第一个单元存放着数组长度,在AX中有一个无符号数,要求在数组中查找(AX),如找到,则使CF=0,并在SI中给出该元素在数组中的偏移地址,如未找到,则使CF=1。在一个长度为N的有序数据组R中,查找元素K的折半查找算法:⑴初始化被查找数组的首尾下标,low1,highn;⑵若low>high,则查找失败,置CF=1,退出程序。

否则,计算中点:mid(low+high)/2;⑶K与中点元素r[mid]比较,若k=r[mid],则查找成功,退出程序;若k<r[mid],则转步骤(4);highmid-1,转若k>r[mid],则转步骤(5);lowmid+1,转⑷低半部查找(lower),highmid-1,返回步骤(2),继续查找⑸高半部查找(higher),lowmid+1,返回步骤(3),继续查找第31页,共104页,2023年,2月20日,星期四流程图如下:第32页,共104页,2023年,2月20日,星期四DsegsegmentLow_idxdw?;低地址元素的下标.High_idxdw?;高地址元素的下标.Dsegends.第33页,共104页,2023年,2月20日,星期四B_searchprocnearMovax,55;查找元素“55”(ax)Cmpax,es:[di+2];(ax)第一个元素,比较.Jachk_last;(ax)>第一个元素,则到chk_lastLeasi,es:[di+2];(ax)≤第一个元素,则第一个元素SJeexit;(ax)=第一个元素,则退出.Stc;(ax)≠第一个元素,则CF=1,未找Jmpexit;退出.Chk_last:Movsi,es:[di];元素个数S.Shlsi,1;长度*2=到最后元素(下标)的字节数

Addsi,di;形成最后元素的地址

Cmpax,es:[si];比较,<最后元素,则转searchJbsearch;(AX)=最后元素,则EXITJeexit;

Stc;

Jmpexit第34页,共104页,2023年,2月20日,星期四Search:(low_idx)Movlow_idx,1;最低元素下标=1Movbx,es:[di];元素个数(bx)

Movhigh_idxbx;最高元素下标(high_idx=元素个数)Movbx,di;保存数组的起始地址(bx)mid:movcx,low_idxmovdx,high_idx;low>high_idxcmpcx,dx;若low>high,则转no_match,置cjano_match:int[(low+high)/2]cx(中间)addcx,dx;

shrcx,1;中间元素下标(si)

movsi,cx;

shlsi,1;将下标值*2形成元素偏移地址

compare:;数组基地址BX+元素偏移量元素地cmpax,es:[bx+si];址[bx+si].(ax)与中间元素[bx+si]比较jeexit;若相等则退出jahigher;若(ax)>(mid)则转high第35页,共104页,2023年,2月20日,星期四ax<中间元素:;若(ax)<(mid),则deccx;1、中间元素下标值:(cx)(cx)-movhigh_idx,cx;2、且(cx)high_idxjmpmid;3、转mid,将中间元素变为高地址higher:;若(ax)>(mid)inccx;1、中间元素下标值:(cx)(cx)+movlow_idx,cx;2、low_idx(cx)将中间元素变为低地址元素jmpmid.;3、转mid,计算中间元素No_match:Stc;未找到,置cf=1Exit:Popds;弹出dsRetB_searchendp

程序首先把查找值与数组的第一个元素和最后一个元素相比较,如果找到或该数小于第一个元素或大于最后一个元素,则结束查找,否则从SEARCH开始折半查找。

第36页,共104页,2023年,2月20日,星期四

SEARCH①从SEARCH开始,首先把数组长度作为数组中间元素下标,把它从数组的第一个单元中取出来,并使它成为偶数,然后再把下标加到DI中以形成数组的中间元素的地址并开始比较查找;②如果比较相等则转至ALL_DONE结束查找;③否则要确定下一步的查找是在数组的低半部还是高半部中进行。它们要做的工作是:①首先检查下标是否等于2,如果等于2则说明整个查找失败,应把CF置1并转至ALL_DONE结束查找;②其次,把下标除以2,以便做进一步的折半查找,然后使下标形成偶数值;③如果要在低半部查找,则从当前的地址(DI)中减去下标值(si)以形成新的查找地址;④如果要在高半部查找,则把下标值加到当前地址值中。

以上过程重复进行直到下标值减到2或者查找值找到为止。

第37页,共104页,2023年,2月20日,星期四Dsegsegment定义数据段

Starteddw?存放数组的首地址DsegendsCsegsegment代码段BsearchprocfarAssumecs:cseg,ds:dsegPushdsPushaxMovax,dsegMovds,axPopax;将已存入ax中的数弹出

Cmpax,es:[di+2];(ax)≤第一个元素吗?

Jachklast;到CHKLAST开始比较大于第38页,共104页,2023年,2月20日,星期四

取偏移地址leasi,es:[di+2];到≤时,则取地址存入sijeexit;=退出,CF=0不置位

stc;<置CF=1,未找到转EXITjmpexitchklast:movsi,es:[di];取第一单元中数组长度

shlsi,1;长度*2=最后元素下标

addsi,d;形成最后元素地址

cmpax,es:[si];比较

jbsearch;<,则开始查找

jeexit;=为最后一个元素,退出

stc;>最后元素,置CF=1,退出jmpexitsearch:movstarad,di;将起始地址存入startadmovsi,es:[di];取长度(si)evenr:testsi,1;是偶数则第0位为1jzaddI;当ZF=1时

则为全0,为偶数

第39页,共104页,2023年,2月20日,星期四incsi;为奇数+1形成偶数addiadddi,si;形成查找元素的地址compare:cmpax,es:[di];比较(ax)=?es:[di]jealldone:=则转alldonejahigher;ax>则到高半部

cmpsi,2;si=2jneidxok;不为2则继续查找nomatch:stc;CF=1,未找到

jealldoneidxok:shrsi,1;(si)/2=’si’逻辑右移0testsi,1;为偶数吗?

jesubidx;是

incsi;否则加1subidx:subdi,si;再低半部,di-si形成

jmpshartcompare;元素地址higher:cmpsi,2;在高半部

第40页,共104页,2023年,2月20日,星期四

jenomatch;未找到,置CF=1shrsi,2;(si)/2(si)jmpshortevenisi;转eveni,将di+s高半部alldone:movsi,dmovdi,startaddr元素的位置Sexit:popds偏移位置

retbsearchendpcsegendsend如果数组如下:ListDw12、11、22、33、44、55、66、77、88、99、111、222、333.

要求查找的数为(ax)=55。数组长度为12,第一次比较的是数组的第6个元素66;因55<66,所以第二次用低半部折半查找,比较的是第3个元素33;因55>33.所以第三次用高半部折半查找,比较的是第五个元素55.这样经过三次比较后,因查找成功而退出程序。如果要查找的数是(ax)=57.

第41页,共104页,2023年,2月20日,星期四则第二次比较的仍是第六个元素66;因57<66,第二次用低半部折半查找,比较的是第三个元素33;因57>33,所以第三次用低半部折半查找,比较的是第五个元素55;因55<57,第四次用高半部折半查找,比较的又是第六个元素66;因57<66,在转低半部查找时,因(si)=2而以查找失败退出程序。这个例子用CMP或TEST指令以及条件转移指令产生两个或多个程序分支。

第42页,共104页,2023年,2月20日,星期四5.3.2用跳转表实现多路分支在实现CASE结构时还可以使用跳跃表法使程序能根据不同的条件转移到多个程序分支去。【例5.7】设某程序有8路分支,试根据给定的N值(1~8),将程序的执行转移到其中的一路分支。 程序流程如图5.7所示。第43页,共104页,2023年,2月20日,星期四第44页,共104页,2023年,2月20日,星期四程序如下:DATA SEGMENTTAB DW

P1,P2,P3,P4,P5,P6,P7,P8N DB

5S1DW?S2DW?S3DW?S4DW?S5DW?S6DW?S7DW?S8DW?DATA ENDSSTACK SEGMENT DB200DUP(0)STACK ENDSCODE SEGMENT

ASSUMEDS:DATA,SS:STACK,CS:CODE

第45页,共104页,2023年,2月20日,星期四START: MOV AX,DATA

MOV DS,AX

MOV AL,N DEL AL ADD AL,AL MOV BL,AL MOV BH,0

JMP TAB[BX]P1:MOVAX,1MOVS1,AX JMPEXITP2:MOVAX,2MOVS2,AXJMP EXITP3:MOVAX,3MOVS3,AXJMP EXITP4:MOVAX,4MOVS4,AX第46页,共104页,2023年,2月20日,星期四P5:MOVAX,5MOVS5,AXJMP EXITP6:MOVAX,6MOVS6,AXJMP EXITP7:MOVAX,7MOVS7,AXJMP EXITP8:MOVAX,8MOVS8,AX

EXIT:MOV AH,4CH INT 21HCODEENDS END START第47页,共104页,2023年,2月20日,星期四

上述程序中的无条件转移指令的转移地址采用的是变址寻址。同理,转移地址也可以用寄存器间接寻址或基址加变址寻址,读者可自行考虑。返回本节第48页,共104页,2023年,2月20日,星期四5.4循环程序设计5.4.1循环程序的结构5.4.2单重循环程序设计5.4.3多重循环程序设计返回本章首页第49页,共104页,2023年,2月20日,星期四5.4.1循环程序的结构1、循环程序的常见结构形式如图5.5(a),(b)所示。

第50页,共104页,2023年,2月20日,星期四循环有两种结构形式.

一种是DO_WHILE形式;另一种是DO_UNTIL形式。当条件为真时执行循环体,为假时跳出循环体。

DO—WHILEDO—WHILE型把对循环条件的判断放在循环的入口,先判断条件,DO—UNTIL结构则先执行循环体,然后再判断控制条件,不满足则继续执行循环操作,一旦满足循环条件则退出循环。第51页,共104页,2023年,2月20日,星期四区别:DO—WHILE型有可能一次也不执行循环体;

DO—UNTIL型则至少执行一次循环体;循环程序可由如下三部分组成:1.初始化部分2.循环体部分3.循环控制部分1)

设置循环的初始状态;设置循环次数的计数值,以及为循环体正常进行工作而建立的初始状态。2)

循环体这是工作的主体,它由循环的工作部分及修改部分组成。工作部分:完成程序功能。修改部分:保证每一次重复时,参加执行的信息能发生有规律的变化。3)

循环控制部分程序设计的关键,控制循环的运行和结束。循环次数已知时作为结束的条件等……第52页,共104页,2023年,2月20日,星期四5.4.2单重循环程序设计1.计数控制2.条件控制第53页,共104页,2023年,2月20日,星期四例计算

sum=1+2+3datasegmentarydb1,2,3countdb3sumdb?dataends……leasi,arynmovcl,countmoval,0next:addal,[si]yaddsi,1loopnextmovsum,al数据段定义:arydb1,2,3si←Ary首地址cl←元素数,al←0和初值求和:al←al+[si],求下一元素地址si←si+1Cx-1且cx=0?存累加和:sum←al显示累加和:sum结束第54页,共104页,2023年,2月20日,星期四例计算sum=1+2+3datasegmentarydb1,2,3countdb3sumdb?dataendsstacksegmentstackdw100dup(0)stackendscodesegmentmainprocfarassumecs:code,ds:data,ss:stackstart:movax,datamovds,ax第55页,共104页,2023年,2月20日,星期四

leasi,arymovcl,countmoval,0next:addal,[si]addsi,1loopnextmovsum,almoval,sum addal,30hmovdl,al movah,2 int21h

movah,4ch int21hmainendpcodeendsendstart第56页,共104页,2023年,2月20日,星期四1.计数控制【例5.7】已知有几个元素存放在以BUF为首址的字节存贮区中,试统计其中正元素的个数。 显然,每个元素为一个8位有符号二进制数,统计其中正元素的个数可用循环程序实现。其程序流程图如图5.6所示。第57页,共104页,2023年,2月20日,星期四第58页,共104页,2023年,2月20日,星期四LEA BX,BUFMOVCX,N MOVAX,0L1:MOVDL,BYTEPTR[BX]CMPDL,0JLEL2 INCAX;正元素个数L2:INCBX;BX←元素地址+1

LOOPL1MOVNUM,AX

第59页,共104页,2023年,2月20日,星期四DATA SEGMENT

BUF DB1,3,5,,0,-1,-3,-5,-7N EQU$-BUFNUM DW?DATA ENDSSTACKSEGMENTSTACK DB200DUP(0)STACK ENDSCODE SEGMENT ASSUMEDS:DATA,CS:CODE,SS:STACK第60页,共104页,2023年,2月20日,星期四START: MOVAX,DATA MOV DS,AX

LEA BX,BUF;元素起始地址

MOV CX,N ;元素总个数

MOV AX,0;正元素个数初值=0L1: MOVDL,BYTEPTR[BX]CMP DL,0 JLE L2 INC AX;正元素个数L2:INC BX;BX←元素地址+1,指向下一个元素

LOOPL1;←DEC CX

;JNE L1 ; MOV NUM,AX

MOV AH,4CH INT 21HCODE ENDS END START第61页,共104页,2023年,2月20日,星期四【例5.8】字符串比较

【例5.8】试编写一程序,要求比较两个字符串STR1和STR所含字符是否相同,若相同则显示‘MATCH!’,若不相同则显示‘NOMATCH!’。(程序略)

其流程图如图5.7所示。第62页,共104页,2023年,2月20日,星期四图5.7程序流程图第63页,共104页,2023年,2月20日,星期四datasegmentstring1DB'abcde'MATCHDB'MATCH$'NOMATCHdb'nomatch$'dataendsextrasegmentstring2db'abcde'numdb'ok'extraendsprognamesegmentmainprocfarassumecs:progname,ds:data,es:extra第64页,共104页,2023年,2月20日,星期四start:pushdsmovax,0pushaxmovax,datamovds,axmovax,extramoves,axmoval,match-string1;字符串1元素个数

cmpal,num-string2jnedispnoleasi,string1leadi,string2movcx,match-string1第65页,共104页,2023年,2月20日,星期四rota:moval,[si]cmpal,[di]jnedispnoincsiincdilooprotadispma:movdx,offsetmatchmovah,9int21hjmpexitdispno:movdx,offsetnomatchmovah,9int21hexit:ret第66页,共104页,2023年,2月20日,星期四mainendpprognameendsendstart第67页,共104页,2023年,2月20日,星期四例5.11、在ADDR单元中存放着数Y的地址,试编制一程序,把Y中1的个数存入COUNT单元中。要测出Y中1的个数,就应逐位测试,一个比较简单的办法是可根据最高有效位是否为1来计数,然后用移位的方法把各位数逐次移到最高位去。循环的结束可以用计数值为16来控制,但更好的办法是结合上述方法可以用测试数是否为0来作为结束条件,这样可以在很多情况下缩短程序的执行时间。2.条件控制

第68页,共104页,2023年,2月20日,星期四第69页,共104页,2023年,2月20日,星期四例5.11、在ADDR单元中存放着数Y的地址,试编制一程序,把Y中1的个数存入COUNT单元中。要测出Y中1的个数,就应逐位测试,一个比较简单的办法是可根据最高有效位是否为1来计数,然后用移位的方法把各位数逐次移到最高位去。循环的结束可以用计数值为16来控制,但更好的办法是结合上述方法可以用测试数是否为0来作为结束条件,这样可以在很多情况下缩短程序的执行时间。第70页,共104页,2023年,2月20日,星期四第71页,共104页,2023年,2月20日,星期四例5.11、在ADDR单元中存放着数Y的地址,试编制一程序,把Y中1的个数存入COUNT单元中。DatasegmentAddrdwnumberNumberdw1100110011110000BCountdw?DataendsPrognamsegmentMainprocfarAssamecs:progname,ds:data第72页,共104页,2023年,2月20日,星期四Start:Movax,dataMovds,axMovcx,0;Movbx,addrMovax,[bx]Repeat:testax,offfffh;ax=offffjzexit;为零则exit,ZF=1

jnsshift;ax正数则转移(非负)

inccxshift:shlax,1;逻辑左移,最右添0jmprepeatexit:count,cx

movdl,clmovah,2movah,4chint21hmainendp||

Prognamends||endstart

第73页,共104页,2023年,2月20日,星期四

这个例子说明算法和循环控制条件的选择对程序的工作效率影响很大。在编程时,应据具体情况来确定循环控制条件。

第74页,共104页,2023年,2月20日,星期四第二种解法:【例5.11】试编一个程序将字单元BUF中所含1的个数存入COUNT单元中。要测出BUF字单元所含1的个数,首先将BUF中的数送给寄存器AX,然后将AX寄存器逻辑左移一次,如果CF=1,则表明AX中的最高位为1,则计数器CL计数1次,如果CF=0,表明AX最高位为0,这样依次将最高位移入CF中去测试。移位之后,判断AX的值是否为0,如果为0则结束循环,不为0,则继续循环。其流程图如图5.8所示。第75页,共104页,2023年,2月20日,星期四第76页,共104页,2023年,2月20日,星期四程序如下:STACK SEGMENTSTACK DB200DUP(0)STACK EDNSDATA SEGMENT

BUF DW0011110010101011B

COUNT

DB?DATA ENDSCODE SEGMENTASSUMEDS:DATA,CS:CODE,SS:STACK第77页,共104页,2023年,2月20日,星期四START: MOV AX,DATA MOV DS,AX MOV AX,BUF MOV CL,0 ;计数器为0LOPA:CMP AX,0 JE EXIT ;(AX)=0,结束循环

SHL AX,1 ;AX左移一位

JNC LOPA INC CL ;产生进位,(CL)+1→CL JMP LOPAEXIT: MOV COUNT,CL MOV AH,4CH INT 21HCODE ENDS END START第78页,共104页,2023年,2月20日,星期四3、循环条件设计方法综合举例例5.10、试编制一个程序把BX寄存器内的二进制数用十六进制数的形式在屏幕上显示出来。把BX的内容从左到右每4位为一组在屏幕上显示出来,显然这可以用循环结构来完成,每次循环显示一个十六进制数位,因而循环次数是已知的,BX中存放十六个二进制数位,故计数值为4。

第79页,共104页,2023年,2月20日,星期四

(1)程序中用CH寄存器存放循环计数值:CH=4,而用DEC及JNZ两条指令完成循环计数功能;(2)因为循环移位要用CL寄存器,而LOOP指令也要使用CX,故循环不用LOOP语句。BX0011,0110,0011,0111显示为3637HBX0110,0011,0111,0011BL0111,0011,左移4次

andal,ofH;0000,1111al0111,0011

0000,0011al0000,0011addal,30H0011,0000

0011,0011al00110011=33H

显示为3637H中的3第80页,共104页,2023年,2月20日,星期四例1将BX寄存器中的内容以十六进制形式显示出来。BX是一个16位寄存器二进制1010100100111110

用十六进显示时,每4位用一个字符显示,共4个其中:0000

→’0’30H,1010→’A’41H0001→’1’31H,1011

→’B’42H、、、、1001→’9’39H,1111→’F’46H?十六进制A93E屏幕上的显示‘A’‘9’‘3’‘E’对应的ASCII41H39H33H45H第81页,共104页,2023年,2月20日,星期四(1)对于0000~1001(0~9),先扩展成一个字节,高4位清0,加上30H后,即可得字符’0’~’9’对应的ASCII码。00000001B+30H=31H00001001B+30H=39H

0001B‘1’1001B‘9’(2)对于1010~1111(A~F),先扩展成一个字节,高4位清0,

加上30H后,还要再加上07H,才能得到’A’~’F’对应的ASCII码00001010B+30H+07H=41H00001111B+30H+07H=46H

1010B‘A’1111B‘F’算法:取出要显示的某4位,转换为对应的ASCII码,再调用DOS系统功能进行显示。第82页,共104页,2023年,2月20日,星期四这里采用了循环移位的方法,把所有显示的四位二进制数移到最右面,以便作数字到字符的转换工作。另外由于数字0~9的ASCII为30~39H,而字母A~F的ASCII为41~46H,所以在把四位二进制数加上30H后还需做一次判断,如果为字符A~F,则还应加上7才能显示出正确的十六进制数二进制到十六进制转换第83页,共104页,2023年,2月20日,星期四C显示字符个数CH=4循环移位次数CL=4BX循环左移4位,将要显示的值移至低4位,保存在DL中清DL的高4位,只保留要显示位的值DL←DL+30H完成数值0~9的ASCII码转换YNDL←DL+07H完成数值A~F的ASCII码转换用02功能显示DL中的字符YNRET返回DL超出39H?CH←CH-1转换结束?list_bxPROC

MOVCH,4MOVCL,4

next:

ROLBX,CL

MOVDL,BL

ANDDL,0FH

ADDDL,30H

CMPDL,39H

JLEprint

ADDDL,07H

print:MOVAH,2HINT21HDECCHJNZnext

RET

;子程返回

list_bxENDP

codeENDS

ENDstart第84页,共104页,2023年,2月20日,星期四例5.10、试编制一个程序把BX寄存器内的二进制数用十六进制数的形式在屏幕上显示出来。datasegmrntcountdw3637HdataendsprognamsegmentMainprocfarassumecs:prognam,ds:data

start:pushdssubax,axpushax

movbx,countmovch,4;共显示4位数.第85页,共104页,2023年,2月20日,星期四next:movcl,4;计数为4.rolbx,cl;左移4次.movdl,bl;得到8位ALanddl,ofh;取低4位.adddl,30h;变为ASCII码

cmpdl,3ah;>9?.jlprint;小于34h……adddl,07h

Print:Movah,2;Asciidl,调中断显示dl.Int21h;

温馨提示

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

评论

0/150

提交评论