第章汇编语言程序设计本章内容SingleChipMicrocomputer概述分支程序循环程序简单程序查表程序子程序应用举例程序设计概述—设计语言最早人们只能用机器语言(二进制)编写程序;为了方便记忆,人们开始用助记符形式的汇编语言编写程序,称为低级语言。然后再用汇编系统将其翻译成机器语言,该过程称为汇编;为了用更接近人的语言编写程序,程序设计师们发明了高级语言,如:BASIC、FORTRAN、PASCAL、C、JAVA然后再用编译系统将其翻译成机器语言,该过程称为编译;机器只能识别机器语言。所以必须用编译系统将高级语言编写的源程序编译成机器语言,用汇编系统将用汇编语言编写的源程序汇编成机器语言;由低级或高级语言构成的程序称为源程序,由机器语言构成的程序称作目标程序;源程序目标程序低级语言机器语言汇编高级语言机器语言编译程序设计实例引入实例假设一个班有50个人,共有3门选修课:计算机算法服装CAD设计德语请找出:同时选了三门课的同学;问题的解决第一步如何在计算机中表示选修某门课的所有同学5122325225392939412252939计算机算法服装CAD设计德语选修这门人数学生的学号这个过程实际上是设计数据结构的问题问题的解决第二步设计思路:找出同时选了三门课的同学这个过程实际上是设计算法的过程,既构建模型。计算机算法CAD设计德语重复该过程第三步:设计流程找出第一个学生他选了德语吗?他选了CAD吗?记录要找的人还有学生吗?下一个学生NNYNYY结束他选计算机吗?NY几点启示整体构思;构建整体流程框图;结构合理,流程清晰,简单明了;局部模块化;为什么要用流程图?符合人进行逻辑思考的习惯计算机从根本上来说,没有任何逻辑性,所以,你必须告诉它,先做什么,后做什么,遇到什么情况又该做什么,等等流程图设计本身是一个逐步求精的过程,最终将任务划分为若干能由机器指令实现的小模块简单程序设计结构特点:按指令的先后顺序依次执行。例1:将20H单元的两个压缩BCD码拆开变成ASCII码,存入21H、22H单元。(假设20H中的BCD码为00110100)什么是BCD码?什么是ASII码?·········20H21H22HAB0011压缩BCD码001100110100低四位ASII码高四位ASII码方法1:将BCD码除以10H,恰好是将BCD码分别移到了A、B的低4位。然后再各自与30H相或,即成为ASCII码。方法2:利用半字节交换指令来实现。ORG0000HMOVA,20HMOVB,#10HDIVABORLB,#30HMOV22H,BORLA,#30HMOV21H,ASJMP$开始(20H)A10HBA/B(A中为高4位BCD码,B中为低4位BCD码)B+30HBB(22H)A+30HAA(21H)结束简单程序例1---方法1源程序如下:·········20H21H22HAB00110100PCPCPC0011010000010000PC0011000000000100PC00110100PCPCPC0011PCORG0000HMOVR0,#20HMOVA,#30HXCHDA,@R0MOV22H,AMOVA,@R0SWAPAORLA,#30HMOV21H,ASJMP$简单程序例1---方法2开始#20HR0#30HAA的低4位(20H)的低4位A(22H)(20H)AA的低4位A的高4位A(21H)结束A+30HAPCPCPCPCPCPCPCPCPC源程序如下:·········20H21H22HAR000110010000000110100000001000011010000110000001100000011PC0011程序设计概述--基本步骤题意分析画出流程图分配内存及端口编制源程序仿真、调试程序固化程序例2:有两组BCD码分别存放在23H、22H单元和33H、32H单元,求它们的和并送入43H、42H单元中去。(高位在前,低位在后)分析:·········32H33H42HA22H23H43H···00111000011001010001000110000111BCD码83HBCD码11H例2:有两组BCD码(如:1183H和5678H),分别存放在23H、22H单元和33H、32H单元,求它们的和,并送入43H、42H单元中去。(高位在前,低位在后)解:流程图(框图)如何?请同学们自己绘制流程图。开始(22H)A(32H)+AA十进制调整(33H)+AAA(43H)结束A(42H)(23H)A十进制调整ORG0000HMOVA,22HADDA,32HDAAMOV42H,AMOVA,23HADDCA,33HDAAMOV43H,ASJMP$END此条加法指令可否改用带进位的(ADDC)?开始(22H)A(32H)+AA十进制调整(33H)+AAA(43H)结束A(42H)(23H)A十进制调整ORG2000HCLRCMOVA,22HADDA,32HDAAMOV42H,AMOVA,23HADDCA,33HDAAMOV43H,AEND·········32H33H42HA22H23H43H···100000110101011000010001011110001000001101111000+111110110110000100010001010101100110011101101000PCPCPCPCPCPCPCPCPC1111101101100001PC01101000PC01100111分支程序设计结构特点:不一定按指令的先后顺序依次运行程序,程序的流向有两个或两个以上分支,根据指定条件选择程序的流向。如实训程序中采用的分支:P3.4=0?点亮所有二极管N二极管交叉点亮Y分支程序的典型实例实例:已知30H单元中有一变量X,要求编写一程序按下述要求给Y赋值,结果存入31H单元。X+1,X>0Y=0,X=0–1,X<0题意:根据X的不同,程序编写时有三个出口,即有三个分支!!!!想一想:程序怎么编写?分支程序实例---三分支程序开始XAA=–1A=A+1存结果结束YYNN程序框图:A0?A=0?分支程序实例---三分支程序源程序如下:ORG2000HMOVA,30HJZLP1;X=0,转LP1处理JNBACC.7,LP2;X>0,转LP2处理MOVA,#0FFH;X<0,则Y=–1SJMPLP1LP2:ADDA,#01;X>0,Y=X+1LP1:MOV31H,A;存结果SJMP$;循环等待,$表示转至本地址,此方法适用于一字节的偏移量最高位为符号位。例设内部RAM20H单元和30H单元中分别存放了两个8位的无符号数X、Y,若X≥Y则让P1.0管脚连接的LED亮;若XY则让P1.1管脚连接的LED亮。方法1:两个数据做减法SUBB,可根据借位CY来判断两个数的大小!方法2:两个数据做比较CJNE,再根据是否相等和借位CY来判断两个数的大小!分支程序实例---数据比较大小方法1编程:XDATE20HYDATE30HORG0000HMOVA,XCLRCSUBBA,YJCL1CLRP1.0SJMPFINISHL1:CLRP1.1FINISH:SJMP$ENDXDATE20HYDATE30HORG0000HMOVA,XCJNEA,Y,L0L0:JCL1CLRP1.0SJMPFINISHL1:CLRP1.1FINISH:SJMP$END方法2编程:分支程序实例---数据比较大小**例两个有符号数的比较。问题1:如何表示有符号数呢?问题2:有符号数怎样比较大小?1.先判断符号位,负数小;正数大.2.符号相同,则用减法判断是否有借位.比较20H和30H单元两个有符号数的大小,结果按下述规律显示。(20H)=(30H),P1.0点亮;(20H)(30H),P1.1点亮;(20H)(30H),P1.2点亮;程序框图结束开始NYYYNNX,Y符号相同?XY,点亮P1.1X=Y,点亮P1.0XY,点亮P1.2X-YX=Y?CY=1X0?NY程序清单XDATA20HYDATA30H;伪指令ORG0000HMOVA,XXRLA,Y;X,Y进行异或JBACC.7,NEXT1;二者符号不同,跳转到NEXT1MOVA,X;符号相同CJNEA,Y,NEQUAL;X≠Y,跳转到NEQUALCLRP1.0;X=Y,点亮P1.0SJMPFINISHNEQUAL:JCXXY;XY,转移到XXYSJMPXDY;否则,XY,转移到XDYNEXT1:MOVA,XJNBACC.7,XDY;判断X的正、负,正则转移到XDYXXY:CLRP1.2;XY,点亮P1.2SJMPFINISHXDY:CLRP1.1;XY,点亮P1.1FINISH:SJMP$END散转程序散转程序是指通过修改某个参数后,程序可以有三个以上的流向,多用于键盘程序。常用的指令是JMP@A+DPTR,该指令是把16位数据指针DPTR的内容与累加器A中的8位无符号数相加,形成地址,装入程序计数器PC,形成散转的目的地址。DPTR+APCA中内容为8位无符号数16位地址数程序清单如下:JUMP1:MOVDPTR,#JPTAB1;跳转表首送数据指针MOVA,R7ADDA,R7;R72A(修正变址值)JNCNOAD;判有否进位INCDPH;有进位则加到高字节地址NOAD:JMP@A+DPTR;转向形成的散转地址人口JPTAB1:AJMPOPR0;直接转移地址表AJMPOPR1.AJMPOPRn例:根据R7的内容,转向各自对应的操作程序(R7=0,转入OPR0;R7=1,转入OPR1…R7=n,转入OPRn)循环程序设计结构特点:利用转移指令反复运行需要多次重复的程序段。实例:前面几个实训中用到的延时程序:(DELAY)DELAY:MOVR3,#OFFHDEL2:MOVR4,#0FFHDEL1:NOPNOPDJNZR4,DEL1DJNZR3,DEL2RET循环程序的组成:1.初始化部分(设定循环次数等)。2.循环体(重复执行的部分,用于完成实际操作)3.循环控制(不断修改和判别循环变量,直至结束)。4.循环结束处理。循环程序设计延时程序中延时时间的设定:源程序:指令周期DELAY:MOVR3,#(X)H2个T机器DEL2:MOVR4,#(Y)H2个T机器DEL1:NOP1个T机器NOP1个T机器DJNZR4,DEL12个T机器DJNZR3,DEL22个T机器RET指令周期、机器周期T机器与时钟周期T时钟的关系:T机器=12T时钟=121/fosc=1us(假设晶振频率fosc为12M)延时时间的简化计算结果:(1+1+2)XY延时时间怎样计算?若想延时100ms,只需修改计数初始值,即(1+1+2)125200us=100ms#200#125循环程序设计1S延时程序源程序:DELAY:MOVR2,#10DEL3:MOVR3,#200DEL2:MOVR4,#125DEL1:NOPNOPDJNZR4,DEL1DJNZR3,DEL2DJNZR2,DEL3RET循环程序设计编程实现P1口连接的8个LED显示方式如下:从P1.0到P1.7的顺序,依次点亮其连接的LED。设循环次数显示模式字送P1口开始显示模式字左移1位设循环初值次数-1=0YN子程序实例引入ORG0000HSTART:MOVR2,#08H;设置循环次数MOVA,#0FEH;送显示模式字NEXT:MOVP1,A;点亮二极管ACALLDELAYRLA;左移一位,改变显示模式字DJNZR2,NEXT;循环次数减1,不为零,继续点亮SJMPSTART;下面一个二极管DELAY:MOVR3,#0FFH;延时子程序开始DEL2:MOVR4,#0FFHDEL1:NOPDJNZR4,DEL1DJNZR3,DEL2RETEND数据传送程序不同存储区域之间的数据传输:将内部RAM30H单元开始的内容传送到外部RAM0