汇编语言第5章 循环与分支程序设计_第1页
汇编语言第5章 循环与分支程序设计_第2页
汇编语言第5章 循环与分支程序设计_第3页
汇编语言第5章 循环与分支程序设计_第4页
汇编语言第5章 循环与分支程序设计_第5页
已阅读5页,还剩38页未读 继续免费阅读

下载本文档

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

文档简介

DOS系统功能调用DOS系统功能调用格式在AH中设置功能号在指定的寄存器中设置入口参数用INT

21H指令执行系统功能调用根据出口参数分析执行情况DOS系统功能调用INT

21H的部分I/O操作1).

键盘输入一个字符并回显计算机等待从标准输入设备(主要指键盘)输入,直到按下一个键。如果按下的是数字、字母等可用ASCII码表示的字符,则这个字符就被送到屏幕显示并把其对应的ASCII码值送到AL寄存器。如果按下Tab制表键,则光标通过添加空格。如按下的键是组合的Ctrl-Break两键,则执行23H的中断而退出命令执行。功能号AH=01H,出口参数AL=字符;AH

,

01H21H使用格式:

MOVINTEx2.asm2).

键盘输入字符到缓冲区:功能号:AH=0AH,入口参数:DS:DX=缓冲区首址(DS:DX)=缓冲区最大字符数(DS:DX+1)=缓冲区实际输入字符数(AL)=00有输入(AL)=FF无输入从键盘接收字符串存入内存。要求事先定义一个输入缓冲区,它的始址放于

DS:DX,第一个字节指出缓冲区能容纳的最大字符数(1~255),不能为零,该值由用户设置;第二字节保留以用作由D0S返回实际读入的字符数(回车除外);从第三个字节开始存放从键盘上接收的字符。若实际输入的字符数少于定义的字节数,缓冲区内其余字节填零;若多于定义的字节数,则后来输入的字符丢掉并且响铃。DOS还自动在输入字符串的末尾加上回车字符,然而这个回车字符未被计入由DOS填到第二个辅助字节内的数目之中。因此,在设立输入缓冲区最大尺寸时要比所希望输入的字节数多一个字节。Ex3.asm3).输出一个字符功能号

:

AH=2入口参数:DL=字符,光标随字符移动使用格式:MOVMOVINTDL

,

‘A’AH

,

02H21H执行上面程序后,将在屏幕上显示字符A.Ex4.asm4).输出字符串,

功能号

:

AH=9,入口参数:DS:DX=串地址,字串结束为“$”符号使用格式:

BUF

DB

‘HELLO!’,’$’……MOVMOVINTDX,

OFFSET

BUFAH,

09H21H……….

Ex5.asm5.S系统5)键盘输入一个字符无回显,支持CTRL_BREAK,CTRL_C检查处理。功能号:AH=08H出口参数:AL=字符;6)返回DOS系统功能号:AH=4CH7)清键盘缓冲区,并调用一种键盘功能功能号:AH=0CHAL=键盘功能号(1s7s8s0AH)第5章

循环与分支程序设计编制一个汇编程序的步骤:分析题意,确定算法。这一步是能否编制出高质量程序的关键,因此不应该一拿到题目就急于写程序,而是应该仔细地分析和理解题意,找出合理的算法及适当的数据结构。根据算法画出程序框图。这样可以减少出错的可能性。画框图时可以由粗到细把算法逐步地具体化。根据框图编写程序。上机调试程序。任何程序必须经过调试才能检查出你的设计思想是否正确以及你的程序是否符合你的设计思想,结果是否正确。5.1

顺序结构程序例1:自然数0~15的平方表,存在内存TABLE开始的连续16个单元中,现XAD单元存有任意一自然数(0

X<15),查表求X的平方,存入YAD单元中。X2的值的地址:TABLE表的首地址

+

Xdatatablesegmentdb

0,1,4,9,16,25,36,49,64,81db

100,121,144,169,196,225xad

db

3yad

db

?datacodeendssegmentassume

cs:code,ds:data,ss:stackstart

proc

farpushds;将DS入栈movax,0000h;AX置零pushax;将0入栈movax

,data;初始化DSmovds

,axah

,0al

,xadbx

,

ax;AH送0;将X送ALadd;求X平方值的地址al

,byte

ptr[bx]

;X平方值送mov

bx,offset

table;表的首址送B

movmovaddmov

movyad

,

almov

ah,4chint

21hstartcodeendpendsend

start例2:编程求y=((a+b)*c-d)/e

其中asbscsdse依次放在VARAsVARBs

VARCsVARDsVARE单元开始的内存中,结果存放在VARY单元中。DATA SEGMEN;定义数VARAVARBVARCVARDDW

6DW

7DW

8DW

9;

a=6;

b=7;

c=8;

d=9VAREDW

10;

e=10VARYDW

?;

yDATAENDSSTACK SEGMENT;定义堆栈段DW

20H

DUP

(?)STACKCODESTARTENDSSEGMENT;定义代码段PROC

FARASSUME

CS:CODE,

DS:DATA,SS:STACKPUSH

DS;DS:00压栈BEGIN:MOV

AX,

0PUSH

AXMOV

AX,

DATAMOV

DS,AX;置数据段MOV

AX,VARAADD

AX,

VARB;a+bIMUL

VARCMOV

CX,AXMOV

BX,DX;(a+b)*cMOV

AX,

VARD;(a+b)*c-dCWDSUB

CX,AXSBB

BX,DXMOV

AX,CXMOV

DX,BXIDIV

VARE ;((a+b)*c-d)/eMOV

VARY,

AXRETSTART

ENDPCODE

ENDSEND

BEGIN5.2

分支结构程序设计1.分支程序的结构形式分支程序结构可以有两种形式IF_THEN_ELSE语句和CASE语句。IF_THEN_ELSE语句可以引出两个分支,CASE语句则可以引出多个分支,不论哪一种形式,在某一种确定条件下,只能执行多个分支中的一个分支。1:符号函数:DATAXXYYDATACODEASSUMESTARTPROCBEGIN:SEGMENT

;定义数据段DB

10DB

?ENDSSEGMENT;定义代码段

CS:CODE,DS:DATA

FARPUSH

DS;DS:00压栈DS,

AXAL,

XXAL,

0BIGR;置数据段;AL=XX;AL与0比较;大于,等于转BIGRAL,

0FFH;AL=-1MOV AX,

0PUSH

AXMOV AX,

DATAMOVMOVCMPJGEMOVJMPEQUT

;转EQUTBIGR:MOVEQUT:JE

EQUT;

等于0,转EQUTAL,

01 ;

AL=1MOV YY,AL

;符号函数的结果存入YY单元

RETSTARTCODEENDENDPENDSBEGIN2:某车站需编写一个计算行李托运费的程序,其要求为:其中G为托运质量,当G=0时,退出程序,G>60Kg不受理。程序:;定义数据段;设托运质量为25KgSEGMENT

DW

25DW

?DATAXXYYDATA

ENDSSTACK

SEGMENT;定义堆栈段DW

50h

DUP(?)ENDSSTACKCODESTARTSEGMENT

;定义代码段PROC

FARASSUME

CS:

CODE,

DS:

DATA,

SS:

STACK;DS:00压栈DS,AX;置数据段AX,XX;取托运质量DEGIN:

PUSH

DSMOV AX,

0PUSH

AXMOV AX,

DATA

MOVMOV

CMPJLECMPJLEAX,

0EXITAX,

20OK;AX与0比较是否大于;小于、等于转EXIT;质量是否大于20Kg;小于、等于转OKCMPJGAX,LAB40;质量是否大于40Kg;大于转LABSUBAX,20;G-20movcx,2MULcx;(G-20)*2ADDAX,20;(G-20)*2+20JMPOK;转OK;质量是否大于60KgEXIT;大于60Kg转EXIT;(G-40)AX,

40cx,3cxAX,

60YY,

AXLAB:

CMP

AX,

60JGSUBmovMULADDMOVRETENDP;(G-40)*3;(G-40)*3+60;托运费存入YY中OK:EXIT:STARTCODE

ENDSEND

BEGIN3根据AL中的被放置位的情况控制转移到8个子程序(R1~R8)中的一个:若AL为00000001则转移至R1;若AL为00000010则转移至R2;若AL为00000100则转移至R3;若AL为00001000则转移至R4;若AL为00010000则转移至R5;若AL为00100000则转移至R6;若AL为01000000则转移至R7;若AL为10000000则转移至R8。分析:实现CASE结构时,可以使用跳跃表法,使程序能根据不同的条件转移到多个程序分支中去。变址寻址方式、寄存器间接寻址方式基址变址寻址方式实现跳跃表法的程序。DATASEGMENT;定义数据段BRTABDATADW

R11DW

R21DW

R31DW

R41DW

R51DW

R61DW

R71DW

R81ENDS;子程序R1入口偏移地址,段地址STACKSEGMENT

PARASTACK‘STACK’

;定义堆栈段DB100

DUP

(?)TOPEQU$-STACKSTACKENDSCODESEGMENT;定义代码段STARTPROC

FARASSUMEDEGIN:

PUSHCS:CODE,DS:DATA,

SS:STACKDSMOVAX,

0;DS:00压栈PUSHAX;使程序能返回DOSMOVAX,

DATAMOVDS,

AX;置数据段MOVAX,

STACMOVSS,

AX;置堆栈段MOVAX,

TOPMOVSP,

AX;置栈顶指针LEAGTBIT:

RCRBX,

BRTABAL,

1;BX指向跳转表JCGETAD;顺序检查AL中各位的状态INCBX;BX加2,指向跳转表中INCBX;下一个子程序地址JMPGTBITGETAD:JMPWORD

PTR

[BX];转移到相应的子程序START

ENDP

CODE

ENDSEND

BEGIN基址变址寻址方式;循环次数8送cxlea

bx,

BRTABmov

si,7*type

branch_tablemov

cx,8l:shl

al,1jnb

not_yetjmp

word

ptr[bx][si];把al逻辑左移1位;CF=0转到not_yet;CF=1转到相应程序分支not_yet:sub

si,type

branch_table;

修改地址loop

l ;

循环4、在附加段中,有一个按从小到大顺序排列的无符号数数组,其首地址存放在DI寄存器中,数组中的第一个单元存放着数组长度。在AX中有一个无符号数,要求在数组中查找(AX),如找到,则使CF=0,并在SI中给出该元素在数组中的偏移地址;如未找到,则使CF=1。折半查找算法:①

折半查找法先取有序数组的中间元素与查找值相比较,如相等则查找成功;②

如查找值大于中间元素,则再取高半部的中间元素与查找值相比较;如查找值小于中间元素,则再取低半部的中间元素与查找值相比较;如此重复直到查找成功或最终未找到该数(查找不成功)为止。③折半查找法的效率高于顺序查找法,对于长度为N的表格,顺查找法平均要作N/2次比较,而折半查找法的平均比较次数为log2N。所以,如果数组长度为100,则顺序查找法平均要作50次比较,而折半查找法平均作7次比较就可以了。①

初始化被查找数组的首尾下标,low=1,high=n②

若low>high,则查找失败,置CF=1,退出程序。否则,计算中点:mid=(low+high)/2K与中点元素r[mid]比较。若k=r[mid],则查找成功,程序结若k<r[mid],则跳转步骤4;若k>r[mid],则转步骤5③

低半部分查找(lower),high=mid-1返回步骤2继续查找。③

高半部分查找(higher),low=mid+1返回步骤2继续查找。dseglow_idxsegmentdw?high_idx

dw?endssegmentproc

neardsegcsegb_searchassumecs:cseg,ds:dseg,es:dsegpushpushmov

mov

movpopdsaxax,dsegds,axes,axaxcmp

ax,es:[di+2]ja

chk_lastsi,es:[di+2]leaje

exitstcjmpchk_last:exitmovshladdcmpjbjestcjmpsi,es:[di]si,1si,diax,es:[si]searchexitexitsearch:mov

mov

mov

movlow_idx,1bx,es:[si]high_idx,bxbx,dimid:mov

mov

cmpjaaddshrmovshlcompare:cx,low_idxdx,high_idxcx,dxno_matchcx,dxcx,1si,cxsi,1cmpax,es:[bx+si]jeexitjahigherdeccxmovhigh_idx,cxjmpmidhigher:inccxmovlow_idx,cxjmpmidno_match:stcexit:popdsretb_searchendpcsegendsend5.3

循环结构程序设计1、循环程序的结构形式①

DO_WHILE结构形式。DO_WHILE结构把对循环控制条件的判断放在循环的入口,先判断条件,满足条件就执行循环体,否则则退出循环。②

DO_UNTIL结构形式。先执行循环体然后再判断条件,不满足则继续,否则退出循环。循环结构程序设计(2)循环程序的结构形式流程图:循环结构程序设计(3)循环程序由三部分组成:设置循环的初始状态。设置循环次数的计数值,以及循环体正常工作而建立的初始状态等。循环体。由循环的工作部分及修改部分组成,循环的工作部分是为完成程序功能而设计的主要程序段,循环的修改部分则是为保证每一次重复(循环)时,参加执行的信息能发生有规律的变化而建立的程序段。循环控制部分。每个循环程序必须选择一个循环控制条件来控制循环的运行和结束。循环结构程序设计(4)AX;00压栈

AX,DATADS,AX

;置数据段PUSH

MOV

MOV

MOV

MOV

MOVAX,0;累加器清0CX,MAX;循环控CX=MAXBX,1;初始加数用1例1求S=1+2+3+…+100AGAIN:ADDAX,BX;累加求和DATASEGMENT;定义数据段INCBX;下一个数MAXDW100LOOPAGAIN;循环转AGAINSUMDW?MOVSUM,

AX;求和结果存SUM中DATAENDSRETSTACKSEGMENTPARASTARTENDPSTACK;定义堆栈段CODEENDSSTACKCODEDW

20HENDSDUP(?)

END

BEGINSEGMENT;定义代码段STARTPROCFARASSUMEBEGIN:CS:CODE,PUSHDS:DATA,

SS:STACKDS

;DS压栈MOVAX,

0循环结构程序设计(5)例2求N!DATA

SEGMENT;定义数据段DW

5DW

?NYYDATA

ENDSSTACKSEGMENT;定义堆栈段50H

DUP

(?);定义代码段STACKCODESTARTDWENDSSEGMENTPROC

FARASSUME

CS:CODE,

DS:DATA,

SS:STACKBEGIN:PUSHDS;DS压栈MOVAX,

0PUSHAX;00压栈MOVAX,

DATAMOVDS,

AX;置数据段MOVAX,

N;

AX=NCMP AX,0;比较是否为0JNENOZ;非0转NOZINCAX;0则AX=1JMPEXIT;转EXITNOZ:MOVBX,

AX ;

BX=AX=NMOVAX,1

;累积AX=1AGAIN:MULBX;相乘AX*BX->AXDECBX;BX减1EXIT:MOVJNE

AGAIN;非0继续

YY,AX;保存N!结果到YY中RETSTARTCODE

ENDENDPENDSBEGIN循环结构程序设计(6)VARADW500;

minVARBDW?VARCDW?DATASTACKENDSSEGMENT;定义堆栈段

DW

20H

DUP(?)ENDSSTACKCODESTARTSEGMENT ;定义代码段PROC

FARASSUME

CS:CODE,

DS:DATA,SS:STACK;DS压栈;0压栈DSAX,

0AXAX,

DATADS,

AXDX,

VARABEGIN:

PUSHMOV

PUSH

MOV

MOV

MOV

MOV

MOV

MOVAX,0;累加器清0BX,2;加数初值

CX,0;项数记录CX例3:求2+4+6+…直到和刚大于500,保存实际和及项数nDATA

SEGMENT;

定义数据段

AGAIN:

ADD AX,

BX

求和INC

CX

;项数记录CX加1INCINCBXBXCMP大于VARAJGE;加数加2AX,DX

;是否EXIT

;大于、等于转继续

EXIT:JMP

AGAIN

;否则,VARB,AX;保存和

VARC,CX;保存项数nENDSMOV

MOVRETSTART

ENDP

CODEENDBEGIN循环结构程序设计(7)例4试编制一个程序把BX寄存器内的二进制数用十六进制数的形式在屏幕上显示出来。循环结构程序设计(9)PROGNAM

MAINSEGMENT

PROC

FAR;代码段定义;主程序ASSUME

CS:

PROGNAMSTART:PUSH

DSSUBAX,

AX;DS:00压栈PUSHAXMOVCH,4

;CH循环次数ROTATE:

MOVCL,

4;每次循环输出一位十六进制数ROLBX,

CL;即移位4个二进制位MOVAL,

BL;

AL=BLANDAL,0FH

;取低4位ADDAL,30H

;转变为ASCII码CMPAL,3AH;是否为’0’-‘9’JLPRINTIT;是转PRINTITADDAL,7

H

;否转为’A’-‘F’PRINTIT:MOVDL,

AL;DL=输出字符MOVAH,

2INT21H

;调用DOS中断,显示字符DECCHJNZROTATE;没循环结束,继续RET;返回MAINENDPENDSPROGNAMEND

START循环结构程序设计(10)例5:在ADDR单元中存放着数Y的地址,试编制一程序把Y中1的个数存入COUNT单元中。程序框图循环结构程序设计(11)DATAREA

SEGMENT;数据段定义ADDR

NUMBER

COUNTDW

NUMBER

DW

YDW

?DATAREA

ENDS

PROGNAMMAIN

PROCSEGMENT;代码段定义

FARASSUME

CS:PROGNAM,

DS:DATAREASTART:

PUSH

DSSUBAX,

AX;DS:00压栈PUSHAXMOVAX,

DATAREAMOVDS,

AX;置数据段MOVCX,

0;CX计数器清0MOVBX,

ADDRMOVAX,

[BX];取Y值给AXREPEAT:TESTAX,0FFFFHJZ

EXIT;测试AX是否为0?,是转EXITJNS

SHIFT;符号为不为1转SHIFTINC

CX;计数器加1SHIFT:SHLAX,

1;左移一位JMP

REPEAT;继续找1EXIT:MOVCOUNT,

CX;保存计数值RETMAINENDPPROGNAMENDSENDS例6:学生成绩统计,要求键盘输入成绩、人数,并统计优、良中、及格和不及格各多少人。循环结构程序设计(12)循环结构程序设计(13)DATASEGMENT;定义数据段STUNUM

EQU30;学生人数SCOREDB68,75,37,93,65,80,78,70,84,67;学生成绩DB86,74,65,54,56,77,85,69,78,95DB69,53,77,68,88,93,84,76,77,80LT60DB0;存放不及格人数GE60DB0;存放及格人数GE70DB0;存放中人数GE80DB0;存放良人数GE90DB0;存放优人数DATASEGMENTSTACKSEGMENT;定义堆栈段STADW20HDUP(?)TOPDW?STACKENDSCODESEGMENT;定义代码段MAINPROCFARASSUME

CS:CODE,

DS:DATA,

SS:STACKSTART:PUSHDS;DS压栈MOVAX,0PUSHAX;0压栈MOVAX,DATAMOVDS,AX;置数据段循环结构程序设计(14)MOVCX,STUNUM;取学生人数MOVBX,OFFSET

SCORE;BX指向学生成绩表首地址B60:MOVAL,[BX];取出一个学生成绩CMPAL,60;是否大于60JAM60;大于、等于转M60LEASI,LT60;SI指向LT60单元INC[SI];SI加1JMPNEXT;继续统计下一个成绩M60:CMPAL,70;是否大于70JAM70;大于、等于转M70LEASI,GE60;SI指向GE60单元INC[SI];SI加1JMPNEXT;继续统计下一个成绩M70:CMPAL,80;是否大于80JAM80;大于、等于转M80LEASI,GE70;SI指向GE70单元INC[SI];SI加1JMPNEXT;继续统计下一个成绩M80:CMPAL,90;是否大于90JAM90;大于、等于转M90LEASI,GE80;SI指向GE80单元INC[SI];SI加1JMPNEXT;继续统计下一个成绩M90:LEASI,GE90;SI指向GE90单元INC[SI];SI加1NEXT:INCBX;BX加1LOOPB60;没有统计完,继续RETMAINENDPENDSTART循环结构程序设计(12)多重循环程序设计例1、延时程序DELAY:MOV

DX,3FFH;外层循环3FFH次TIME:MOVAX,0FFFFH;内层循环FFFFH次TIME1:DECAXNOP;空操作,起延时作用

温馨提示

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

评论

0/150

提交评论