第6章汇编语言程序设计用汇编语言编程属结构化程序设计。需按照结构化的思想来进行汇编程序的设计•分析题意,确定算法•根据算法画出程序框图•根据框图编写程序•上机调试程序•执行程序按照自上而下的设计方法,设计一个汇编程序的步骤:•顺序程序•分支程序•循环程序从结构上来讲,一般的汇编程序可分为:Eg:从键盘输入一个字符并存储到字节变量BUF单元中.分析:用DOS功能调用完成键入,输入的字符保存在AL寄存器中将AL中的内容存到定义在数据段的变量BUF所指单元中顺序程序设计.486DATASEGMENTUSE16BUFDB?DATAENDS源程序清单:CODESEGMENTUSE16ASSUMECS:CODE,DS:DATABEG:MOVAX,DATAMOVDS,AXMOVAH,1INT21H;AL=键入字符的MOVBUF,ALASIIC码MOVAH,4CHINT21HCODEENDSENDBEG分支程序设计转移指令可用来实现分支程序设计分支程序分三种:•简单分支•复合分支•多分支简单分支即两路分支,该分支程序结构为:条件满足否?程序段1程序段2YNEg:将BX寄存器的内容以二进制数格式显在屏幕上BX=1110010011100110B简单分支RCL0SALROLCFCFCF·486CODESEGMENTUSE16ASSUMECS:CODEBEG:MOVBX,5678HMOVCX,16LAST:MOVAL,’0’ROLBX,1JNCNEXTMOVAL,’1’NEXT:MOVAH,0EHINT10HLOOPLASTMOVAH,4CHINT21HCODEENDSENDBEGADCAL,0数→BX,16→CXC标=?‘1’→AL调BIOS.0EHCX-1→CXCX=0‘0’→ALBX左移一位10NY返DOS源程序清单:复合分支判断的条件是复合条件,称复合判断复合分支程序结构为:条件1和条件2...满足否?程序段1程序段2YNEg:某科室9人,统计月收入在800~900间的人数,并用十进制数显示复合分支分析:月收入是无符号数,对一批数处理应该用间址。数轴:··N1(800)N2(900)多分支判断条件后有多个出口,判断一次只能选择一个分支。多分支程序结构为:1条件属哪种情况?程序段1程序段n+m…...…...程序段nnn+m例.多分支段内转移要求:键入0,转P0程序段键入1,转P1程序段……键入9,转P9程序段思路:①用比较指令配合直接转移指令实现CMP键入字符,‘0’JEP0CMP键入字符,‘1’JEP1……②用转移地址表配合间接转移指令实现多分支·486DATASEGMENTUSE16TABDWP0,P1,…,P9;汇编后自动装入相应的偏移地址MESGDB0DH,0AH,’strike0~9:$’DATAENDSCODESEGMENTUSE16ASSUMECS:CODE,DS:DATABEG:MOVAX,DATAMOVDS,AXAGA:MOVAH,9MOVDX,OFFSETMESGINT21HMOVAH,1INT21HCMPAL,’0’JCAGACMPAL,’9’JAAGASUBAL,30HMOVZXBX,ALADDBX,BX;2×BX→BXMOVSI,OFFSETTABJMP[BX+SI];DS:[BX+SI]→IPP0:…P1:………P9:…CODEENDSENDBEG或:MOVBX,[BX+SI]JMPBX;BX→IP源程序清单:循环程序设计循环程序的组成:•循环准备•循环体•循环控制1.循环程序的结构Y预置循环次数其他准备工作循环体循环减1计数退出循环结果为0?N(a)单循环结构(b)双循环结构结果为0?循环体内循环减1计数结果为0?外循环减1计数退出循环预置外循环次数其他准备工作预置内循环次数其他准备工作NNYYEg:假设从BUF单元开始为一个ASCII码字符串,找出其中的最大数送屏幕显示。循环程序设计思路:ASCⅡ码数为无符号数,无符号数的最小数为0YNN数据区首址→DS:BX无符号最小数→AL数据个数→CX[BX]→AL[BX]=AL?BX+1→BXCX-1→CX显示结果返回DOSCX=0?Y·486DATASEGMENTUSE16BUFDB'QWERTYUIOP123'COUNTEQU$-BUF;统计串长度MAXDB'MAX=',?,0DH,0AH,'$'DATAENDSCODESEGMENTUSE16ASSUMECS:CODE,DS:DATABEG:MOVAX,DATAMOVDS,AXMOVAL,0;无符号最小数0→ALLEABX,BUF;串首址偏移量→BXMOVCX,COUNT;串长度→CXLAST:CMP[BX],AL;比较JCNEXTMOVAL,[BX];大数→ALNEXT:INCBXLOOPLAST;循环计数MOVMAX+4,AL;最大数→MAX+4单元MOVAH,9MOVDX,OFFSETMAXINT21H;显示结果MOVAH,4CHINT21H;返回DOSCODEENDSENDBEG源程序清单1:·486DATASEGMENTUSE16BUFDB'QWERTYUIOP123'FLAGDB-1;设置串结束标志MAXDB'MAX=',?,0DH,0AH,'$'DATAENDSCODESEGMENTUSE16ASSUMECS:CODE,DS:DATABEG:MOVAX,DATAMOVDS,AXMOVAL,0;无符号最小数0→ALLEABX,BUF;串首址偏移量→BXLAST:CMPBYTEPTR[BX],-1;[BX]=串结束标志?JEDISP;是,转CMP[BX],ALJCNEXTMOVAL,[BX];大数→ALNEXT:INCBXJMPLASTDISP:MOVMAX+4,AL;最大数→MAX+4单元MOVAH,9MOVDX,OFFSETMAXINT21H;显示结果MOVAH,4CHINT21H;返回DOSCODEENDSENDBEG源程序清单2:汇编程序设计举例代码转换代码转换常见的代码转换有:二进制数→显示二进制数→十进制数→显示二进制数→十六进制数→显示BCD码数→二进制数代码转换A一.二进制数显示:例.把键盘输入的一位数(0~9),转换成等值二进数显示显示的格式要求如下:PleaseEnter:ERROR!PleaseEnter:9=00001001B代码转换思路:键盘缓冲区中是键入字符的ASCⅡ码。0~9的ASCⅡ码为30H~39H。二进制数每一位代码的判断:本程序采用两种格式设计源程序:一种是EXE文件编程格式,另一种是COM文件编程格式。RCL0SALROLCFCFCF程序框图:AL-30H→BL‘=’→屏幕,8→CX‘0’→屏幕‘1’→屏幕CX-1→CX‘B’→屏幕,返回DOSNN给出操作提示键盘输入→ALAL=‘0’~’9’?CF=?CX=0?BL左移一位Y显示错误信息Y01.486DATASEGMENTUSE16MESG1DB'PleaseEnter!',0DH,0AH,'$'MESG2DB‘------Error!$'DATAENDSCODESEGMENTUSE16ASSUMECS:CODE,DS:DATABEG:MOVAX,DATAMOVDS,AXMOVAH,9MOVDX,OFFSETMESG1INT21H;显示操作提示MOVAH,1INT21H;等待键入CMPAL,3AHJNCERROR;>'9'转CMPAL,30H[EXE格式程序清单]JCERROR;<'0'转SUBAL,30HMOVBL,AL;BL=0~9的二进制数MOVAH,2MOVDL,'='INT21HCALLDISPMOVAH,2MOVDL,'B'INT21HJMPEXITERROR:MOVAH,9MOVDX,OFFSETMESG2INT21H;显示错误信息EXIT:MOVAH,4CHINT21H;---------------------------------DISPPROC;显示BL中的二进制数MOVCX,8LAST:MOVDL,'0'RCLBL,1JNCNEXTMOVDL,'1'NEXT:MOVAH,2INT21HLOOPLASTRETDISPENDPCODEENDSENDBEG[EXE格式程序清单].486CODESEGMENTUSE16ASSUMECS:CODEORG100HSTART:JMPBEGMESG1DB'PleaseEnter!',0DH,0AH,'$'MESG2DB'---Error!$'BEG:MOVAH,9MOVDX,OFFSETMESG1INT21H;显示操作提示MOVAH,1INT21H;等待键入CMPAL,3AHJNCERROR;>'9'转CMPAL,30HJCERROR;<'0'转SUBAL,30HMOVBL,AL;BL=0~9的二进制数MOVAH,2MOVDL,'='INT21HCALLDISPMOVAH,2MOVDL,'B'INT21HJMPEXITMOVDX,OFFSETMESG2INT21H;显示错误信息INT21HERROR:MOVAH,9EXIT:MOVAH,4CH[COM格式程序清单];-------------------------------DISPPROC;显示BL中的二进制数MOVCX,8LAST:MOVDL,'0‘RCLBL,1JNCNEXTMOVDL,'1'NEXT:MOVAH,2INT21HLOOPLASTRETDISPENDPCODEENDSENDSTART[COM格式程序清单]问题:键入的是两位十进制数时,如何将该十进制数的二进制数显示在屏幕上?代码转换二.二进制数→十六进制数显示算法:四位二进制数等值的十六进制数十六进制数ASCⅡ码算法0000~10011010~11110~9A~F30H~39H41H~46H四位二进制数+30H=等值的十六进制数ASCⅡ码四位二进制数+37H=等值的十六进制数ASCⅡ码代码转换编程技巧:8位二进制数截取高4位显示显示截取低4位XXXXXXXXXXXX0000XXXX000016进制数ASCⅡ码16进制数ASCⅡ码代码转换例.设从BNUM单元开始,有4个16位的二进制数,要求把它们转换成16进制数,并送屏幕显示。[程序清单].486DATASEGMENTUSE16BNUMDW0001001000110100B;1234HDW0101011001111000B;5678HDW0001101000101011B;1A2BHDW0011110001001101B;3C4DHBUFDB4DUP(?),‘H$’;输出缓冲区COUNTDB4DATAENDSCODESEGMENTUSE16ASSUMECS:CODE,DS:DATABEG:MOVAX,DATAMOVDS,AXMOVCX,4MOVBX,OFFSETBNUMAGA:MOVDX,[BX]SALEDX,16CALLN2_16ASCMOVAH,9MOVDX,OFFSETBUFINT21H;显示一个16进数ADDBX,2;地址加2LOOPAGAMOVAH,4CHINT21H;二进数→十六进数ACSII码N2_16ASCPROCMOVSI,OFFSETBUF;输出缓冲区地址→SIMOVCOUNT,4LAST:ROLEDX,4ANDDL,0FHCMPDL,10JCNEXTADDDL,7NEXT:ADDDL,30HMOV[SI],DLINCSI;地址加1DECCOUNT;计数JNZLASTRETN2_16ASCENDPCODEENDSENDBEG[EXE格式程序清单]代码转换三.BCD码→二进制数例.4位BCD码数→二进制数显示算法:设4位BCD码数列为:N3N2N1N0,等值二进制数=N3×1000+N2×100+N1×10+N0=(((0×10+N3)×10+N2)×10+N1)×10+N0编程考虑:4位BCD码最大为9999H,等值的二进制数最大为16位(超过8位),而且D15位肯定为0分离出BCD千位N3,百位N2,十位N1,个位N0设计一个