微机原理第八章微型计算机的程序设计.ppt

上传人:牧羊曲112 文档编号:6363372 上传时间:2023-10-21 格式:PPT 页数:91 大小:4.23MB
返回 下载 相关 举报
微机原理第八章微型计算机的程序设计.ppt_第1页
第1页 / 共91页
微机原理第八章微型计算机的程序设计.ppt_第2页
第2页 / 共91页
微机原理第八章微型计算机的程序设计.ppt_第3页
第3页 / 共91页
微机原理第八章微型计算机的程序设计.ppt_第4页
第4页 / 共91页
微机原理第八章微型计算机的程序设计.ppt_第5页
第5页 / 共91页
点击查看更多>>
资源描述

《微机原理第八章微型计算机的程序设计.ppt》由会员分享,可在线阅读,更多相关《微机原理第八章微型计算机的程序设计.ppt(91页珍藏版)》请在三一办公上搜索。

1、第八章 微型计算机的程序设计,顺序结构程序分支结构程序循环结构程序子程序结构,重点:,程序设计方法顺序结构程序分支结构程序循环结构程序子程序结构,8.1 程序设计步骤,1.分析问题2.建立数学模型3.确定算法4.绘制程序流程图5.内存分配6.编制程序7.程序调试,data segment a1 db hellon!,0dh,0ah,$data endsStack1 segment para stack.Stack1 endscode segment assume cs:code,ds:data,ss:stack1 start:mov ax,data mov ds,ax mov ah,4ch i

2、nt 21hcode ends end start,看一个例子,数据段,堆栈段,代码段,8-1 顺序程序设计,补充:二进制编码的十进制数,二进制编码的十进制数 就是BCD码(Binary Coded Decimal)。压缩BCD码 是用4位二进制数表示一位十进制数。一个字节表示两位十进制数。如:1001 0110B 表示 96 D非压缩BCD码 是用一个字节表示一位十进制数。高4位总是0。如:0000 1001B 表示 9D 两种BCD码的编码对照表,两种BCD码的编码对照表,1.BCD数加法调整指令DAA和AAA(P196),DAA-两个压缩BCD数相加调整指令:(AL AL=8AHDAA;

3、AL=90H,AAA-两个非压缩BCD数相加调整指令若(AL AH=01H,【例8.1】的程序段为:stack segment stack stackdw 32 dup(0)stackstack endsdata segmentW1 DW 8931HW2 DW 5678HSUM DB3 DUP(0)data endscodesegmentbeginproc farassume ss:stack,cs:code,ds:datapush dssub ax,axpush ax,mov ax,datamov ds,axMOV AL,BYTE PTR W1;AL=31H(+78H)ADD AL,BYTE

4、 PTR W2;AL=A9H,CF=0,AF=0DAA;BCD数加法调整指令;AL=09H,CF=1MOV SUM,ALMOV AL,BYTE PTR W1+1;AL=89H(+56H)ADC AL,BYTE PTR W2+1;AL=E0H,CF=0,AF=1DAA;AL=46H,CF=1MOV SUM+1,ALMOV SUM+2,0;处理向万位的进位RCL SUM+2,1;也可用指令ADC SUM+2,0retbegin endpcode endsend begin,例8.2 非压缩BCD数W1与W2(均为字变量)相加,将其和送到SUM字节变量中。,data segmentW1 DW 080

5、9H;即89DW2 DW 0607H;即67DSUM DB3 DUP(0);一个字节放1位BCD码,用来放加完后的值156data ends,MOV AX,W1;AX=0809H,W2为0607HADD AL,BYTE PTR W2;AL=10H,CF=0,AF=1AAA;属于第一种情况,故;AL为(AL+06H)AL=05H,AH=01H;第一种情况处理:AL=(AL+06H)&0FH,因0FH+06H=15H,故AL=05H,AH=AH+1=0+1=01H,所以AX=0105HMOV WORD PTR SUM+1,AX;(SUM+1)=05,(SUM+2)=01,此句也可表达为MOV SU

6、M,AL;见P151,2.BCD数减法调整指令DAS和DAA(自看,P198),DAS-两个压缩BCD数相减调整指令:(AL AL=DEH,有借位DAS;AL=78H,保持借位即134-56AAS-两个非压缩BCD数相减调整指令,3.非压缩BCD数乘除法调整指令AAM和AAD(P199,自看),顺序程序设计举例:例7.7 镜子程序,P183-184,data segmentOBUF DB 0DH,0AH,$IBUF DB 0FFH,0,255 DUP(0)data ends,MOV DX,OFFSET OBUF;显示提示符“”并回车换行MOV AH,O9INT 21HMOV DX,OFFSET

7、 IBUF;输入并显示字符串MOV AH,10INT 21HMOV BL,IBUF+1MOV BH,0MOV IBUFBX+2,$MOV DL,0AH;换行MOV AH,2INT 21HMOV DX,OFFSET IBUF+2;再显示输入的字符串MOV AH,9INT 21H,8.2 分支程序设计,特点:利用改变标志位的指令和转移指令来实现。无条件转移指令:JMP(见P207)条件转移指令:Jcond short-label(偏移地址送到IP)特点:满足条件,则实现段内转移;80386开始才可以转移到代码段的任何位置。,8.3 循环程序设计,8.3.2 重复控制指令,LOOP short-la

8、belLOOPZ short-label 或 LOOPE short-labelLOOPNZ short-label 或LOOPNE short-labelJCXZ short-labelJECXZ short-label共同点:均受CX或EXC的值控制,详见P214-215,8.3.3 单重循环设计举例,例8.11 计算Z=X+Y,其中X和Y是双字变量分析:双字变量是4个字节,则和可能占5个字节,作业8.4 编写求两个4位非压缩BCD数之和,将和送显示器显示的程序。(P261),分析:两加数各要4个字节单元,可以为DD类型;考虑到进位,和要5个字节单元,另外,输出到显示器的结束符号$需要一个

9、单元存放,故共需6个字节。因此,数据段定义为:data segment W1 DD 01020304HW2 DD 05060708HSUM DB 5 DUP(0)DB$data ends,代码段中的核心语句,MOV CX,4MOV SI,0MOV DI,4;要在SUM+4中放个位,SUM+0中放最高位的进位。XOR AX,AX;清CFA1:MOV AL,BYTE PTR W1SI;ADC AL,BYTE PTR W2SIAAAMOV SUMDI,ALINC SIDEC DILOOP A1MOV SUMDI,0RCL SUMDI;以上是得到加的结果,放在SUM中。下面是输出到显示器的程序语句MO

10、V DX,OFFSET SUMMOV AH,09INT 21H,作业8.5 编写求两个4位压缩BCD数之和,将和送显示器显示的程序。(P261),分析:两个加数各要2个字节单元,可以为DW类型;考虑到进位,和要3个字节单元,另外,输出到显示器的结束符号$需要一个单元存放,故共需4个字节。因此,数据段定义为:data segment W1 DW 1234HW2 DW 5678HSUM DB 3 DUP(0)DB$data ends,代码段中的核心语句,MOV CX,2MOV SI,0MOV DI,2;要在SUM+2中放个位,SUM+0中放最高位的进位。XOR AX,AX;清CFA1:MOV AL

11、,BYTE PTR W1SI;ADC AL,BYTE PTR W2SIDAAMOV SUMDI,ALINC SIDEC DILOOP A1MOV SUMDI,0RCL SUMDI;以上是得到加的结果,放在SUM中。下面是输出到显示器的程序语句MOV DX,OFFSET SUMMOV AH,09INT 21H,作业8.17 编写求输入算式加数1+加数2的和并送显。(加数及其和均为4位(即指压缩)BCD数,P262),分析:要求先有屏幕显示输出加数1+加数2:,然后从键盘输入两个4个字节的BCD数,加完后送显。用到的变量:W1和W2因为从键盘输入,均不确定是几位十进制,故需确定其最大位数不超过要用

12、W1,例6.2,将内存(10050)单元的内容拆成两段,每段4位,并将它们分别 存入内存(10051)和(10052)单元。即(10050)单元中的低4位放入(10051)单元中的低4位,而(10050)单元中的高4位放入(10052)单元中的低4位。,开始,初始化,用间址方法取数到AL,用AND指令将该数“与”OFH取得低4位,存入内存(10051)单元,再取出原始数到AL,逻辑右移得高4位,存入内存(10052)单元,暂停,逻辑右移得高4位,存入内存(10052)单元,程序段如下:,MOV AX,1000HMOV DS,AX;给段寄存器DS赋值MOV SI,50HMOV AL,SI;把物理

13、地址为10000H+0050H=10050H;中的存储内容给ALAND AL,0FH;把AL中的前4位清0,取得低4位值MOV SI+1,AL;把得到的低4位放到(10051H)单元MOV AL,SI;再取出需拆字节放到AL中MOV CL,4SHR AL,CL;逻辑右移4次,前4位补0;MOV SI+2,AL;放入(10052)单元,AND AL,F0HMOVE SI+2,AL,6-3、分枝结构程序,两分支结构,多分支结构,例6.3 求AX累加器和BX寄存器中两个无符号数之差的绝对值,结果放在内存(2800)单元中。,分析:不知AX与BX中数的大小,故需先判断谁大,然后用大的减小的才可求得绝对

14、值,其流程图如图6-5,开始,初始化,清CF,AX-BX AX,AX 内存(2800和(2801)单元,暂停,逻辑右移得高4位,存入内存(10052)单元,AX-BX0,AX-BX AXBX 内存(2800和(2801)单元,否,是,相应程序段如下(p141),CLC SUB AX,BX JC AA;进位位为1,就转移到AA MOV DI,2800H MOV DI,AX HLTAA:SUB BX,AX MOV DI,2800H MOV DI,BX HLT,例6.4 从外设71号中取一个数M,判断其值是否在10和20之间,即10M20.如果M20H,则送0FFH给外设73H;如果M10,则送00

15、H给外设73H;如果10M20,则送88H给外设73H.,分析:根据题意,我们可以看出这是一个需要两次判断M大小的问题。我们可以先判M是否大于10,再判M是否大于20。(2)根据解决问题的思路,我们先画出程序流程图,如下图所示。从图6中程序流程图来看,两个分支都要“回归”原程序。(3)编制的程序如下:,相关程序段如下(p142),START:IN AL,71H;将71H端口的字节读入AL CLC;清除CF CMP AL,10;AL-10,结果不返回 JC LP1;小于10转LP1 CMP AL,20;AL-20,结果不返回 JC LP2;10AL20 转LP2 MOV BL,0FFH;将0FF

16、H送入BL寄存器 LP3:OUT 73H,BL;将0FFH输出到73H端口 HLT;暂停 LP1:MOV BL,00 JMP LP3 LP2:MOV BL,88H JMP LP3,只能用累加器AX/AL作为执行输入/输出过程的机构,故要改为AL。故OUT 73H,BL替换为:MOV AL,BLOUT 73H,AL,赋初值,条件,循环体,修改,Y,N,开始,6-4、循环程序设计,1、先判断条件,然后执行循环体。,赋初值,循环体,修改,条件?,N,Y,开始,2、先执行循环体,然后判断条件。特点:至少执行一次循环体。,例6.5 求两个多字节数之和,这两个数在10050H地址开始的内存单元中,连续存放

17、,低位在小地址一端,结果放在这两个数之后。设这两个多字节数均为8个字节。,流程图如下:,初始化段地址DS:1000H第一个数指针SI=50H第二个数指针DI=58H结果指针BX=60H循环次数CX=4清除进位位CF,取一个字 AX,CX=0,Y,N,开始,和数=前一次+(指针)即AX AX+DI+CF,SI SI+2 修改指针DI DI+2计数器CX CX-1,暂停,结果和的指针起始值应该为60H,请分析!,相关程序段如下(p144),START:MOV AX,1000H MOV DS,AX MOV SI,50H;第一个指数指针SI=50H MOV DI,58H;第二个指数指针DI=58H M

18、OV BX,60H;结果指针60H CLC;清进位CF=0AA:MOV AX,SI;取一个字到AX ADC AX,DI;AX=AX+DI+CF MOV BX,AX;存一个字到BX;PUSHF;保护进位CF;ADD SI,2;修改第一个数的指针SI=SI+2 ADD DI,2;修改第二个数的指针DI=DI+2 ADD BX,2;修改结果指针BX=BX+2 POPF;恢复标志寄存器 LOOP AA;CX=CX-1,若CX0,转AA HLT;CX=0,暂停,例2、编程序统计 AX 寄存器中 1 的个数。(采用 AX=0?做为循环的条件)(本题即书上第六章习题第6.6题,见P152),其程序流程图如下

19、图,程序如下:,CODE SEGMENT ASSUME CS:CODESTART:MOV CX,0;存 1 的个数AGAIN:TEST AX,0FFFFH JZ B SAL AX,1;算术左移一位,此处用SHL(逻辑左移)也可 JNC A;进位不等于1,则转A;INC CX;进位为1,CX=CX+1;A:JMP AGAIN B:MOV AH,4CH;相当于B:HLT INT 21H CODE ENDS END START,例6.6 要求设计一个软件延时程序,延时时间约1ms左右。(1)分析题目:此题是想让计算机做一些无用的操作,来拖延时间。我们可以从指令手册中查得各条指令所需的时间节拍,但一般

20、指令执行时间只有几个时钟周期,亦即只有几个微秒,为了能用较少的指令来编较长时间的延时,我们可以利用循环程序结构。(2)程序流程图如图6-11所示。,在这个框图中,初始化部分由于没有数据操作问题,因此也就不用设置间接地址指针。另外,延时的时间主要取决于循环体及循环次数。我们从手册上可以查得PUSHF和POPF指令分别为 10 和 8个时钟节拍,LOOP BX指令为 3.4 个时钟节拍在此循环体需要用1083.421.4拍,而每个时钟节拍是根据此系统的晶振频率而定的。假设此系统用的是8Hz的晶振,则每个时钟节拍需要0.125微秒因此我们可以根据下列公式算出循环次数:,6-5 子程序,子程序:相对主

21、程序而言,是被主程序调用 的程序.子程序调用示意图:,子程序是程序设计中经常使用的程序结构,通过把一些固定的、经常使用的功能做成子程序的形式,可以使源程序及目标程序大大缩短,提高程序设计的效率和可靠性。对于一个子程序,应该注意它的入口参数和出口参数。入口参数是由主程序传给子程序的参数,而出口参数是子程序运算完传给主程序的结果。另外,子程序所使用的寄存器和存储单元往往需要保护,以免影响返回后主程序的运行。主程序在调用子程序时,一方面初始数据要传给子程序,另一方面子程序运行结果要传给主程序,因此,主子程序之间的参数传递是非常重要的。,参数传递一般有三种方法实现。,(1)利用寄存器。这是一种最常见方

22、法,把所需传递的参数直接放在主程序的寄存器中传递给子程序。(2)利用存储单元。这种参数传递方法,把所需传递的参数直接放在子程序调用指令代码之后。(3)利用堆栈。这种方法将参数压入堆栈,在子程序运行时从堆栈中取参数,其程序流程图如下图所示。,堆栈程序流程图,例6.7延时1秒的子程序段(见P148),DELAYS:PUSHF PUSH BX PUSH CX MOV BX,3E8H MOV CX,176HLP2:MOV CX,176HLP1:PUSHF POPF LOOP LP1 DEC BX JNZ LP2 POP CX POP BX POPF RET,SUB_DELAYS PROC NEAR,S

23、UB_DELAYS ENDP,把寄存器FR、BX、CX的内容压进堆栈,以保护CPU现场,按“先入后出”原则把栈中内容弹回到寄存器中去,以恢复CPU现场。,例6.8 找一个数据块中的最大数,其中数据块的长度1,并且放在内存(2001)单元中,而数据块本身是从(2002)单元开始存放的,最后,把找出的最大值放到(2000)单元中。假设这段数据块中的数都是无符号的8位数。,(1)分析题目:此题必定是个循环程序,而且在处理部分应包括判断分支环节。(2)根据指令系统,我们可以采用寻找最大值的计算方法。,首先,我们用00值放在AL累加器中作为最大值;然后,用数据块的第一个数和AL中的数做比较,如果比00大

24、,则用这个数取代00,放入AL中;接着取出第二个数与AL中的数做比较,如果比它大,取而代之,否则不取代,如此往复,直至最后一个数。这样,最后AL累加器中必定存放着最大的数。这就是寻找最大值的方法,而数据块的总长度(数的个数)就是循环次数。(3)绘制出此计算过程的程序流程如图6-l5所示。,改为子程序时的程序段,MAX:PUSHF PUSH AX PUSH CX PUSH SISTART:MOV SI,2001H MOV CL,SI INC SI MOV AL,00 MOV CH,00HLP:CLC CMP AL,SI JC BB JMP AABB:MOV AL,SIAA:INC SI LOOP

25、 LP MOV 2000H,AL HLT POP SI POP CX POP AX POPF RET,SUB1 PROC NEAR/FAR,SUB1 ENDP,1、调用程序和子程序在同一代码段 子程序的类型应为NEAR cod1 segment CALL SUB1.SUB1 PROC NEAR.RET SUB1 ENDP cod1 ends,红色部分为子程序,子程序调用方式介绍:,2、调用程序和子程序不在同一代码段子程序的类型应为FAR。子程序SUB1的类型是FAR,可段间调用,也可段内调用.,CODE2 SEGMENT.SUB1 PROC NEAR.RET SUB1 ENDP.CALL SU

26、B1.CODE2 ENDS,CODE1 SEGMENT CALL FAR PTR SUB1.CODE1 ENDS,CODE2 SEGMENT.SUB1 PROC NEAR.SUB1 ENDP.CALL SUB1;段内调用.CODE2 ENDS 子程序SUB1的类型是FAR,可段间调用,也可段内调用.,6.6 查表程序,要点:1)确定表格的起始地址(或称基地址)给BX2)确定要查找对象在表中的序号,(或称索引值)给AL。3)要用到换码指令XLAT,将累加器中的值变为内存表格中的某一个值。注:表格的起始地址为内存物理地址中的偏移地址,例6.9:在5.2节中表5-2所列的十进制的7段显示码实例,用程

27、序来实现,假设这段数据存放在2000H开始的内存中,取出“5”所对应的7段码。,程序段为:START:MOV BX,2000H MOV AL,5 XLAT HLT,例2 编一子程序利用XLAT指令把十六进制数转换成ASCII码。假设ASCII码存放在以DAT1为首地址的数据区中,对应的十六进制数放在以DAT2为首地址的数据区中,转换结果送以DAT3为首地址的数据区中。,分析:首地址即基址DAT1送给BX,ASCII码表总共有7FH(即128)个字符。所以索引值要从0变到128(存放在DAT2为首地址的数据区中),需要用到循环将得到的值送到以DAT3为首地址的数据区中。查表核心程序语句为:MOV

28、 BX,2000H(表的首地址)MOV AL,5(表中对应的偏移量,即索引值)XLAT此程序段的结果是将查到的结果送到累加器AX中,SUB1 PROC NEARSTART:LEA SI,DAT2;或为MOV SI,DAT2 LEA DI,DAT3;或为 MOV DI,DAT3 MOV BX,DAT1 MOV CX,16LP1:MOV AL,SI;或为 LODSB,即从RAM AX/AL XLAT MOV DI,AL;STOSB,即从AX/AL RAM INC SI;若用了LODSB与STOSB,则不用此两句,INC DI;因为串操作时SI和DI作自动增量修改 LOOP LP1 RETSUB1

29、ENDP,POP ALP0P CXPOP DIPOP SIPOP BX,PUSH BXPUSH SIPUSH DIPUSH CXPUSH AL,第六章 习题与思考题,1、用串操作指令实现:先将100H个数从2170H单元处搬到1000H1单元处,然后从中检索等于AL中字符的单元,并将此单元换成空格字符.2、从60H个元素中寻找一个最大的值,并放到AL中.假设这60个元素防在DATA1开始的单元中.3、在DS段有一个从TABLE开始的由160个字符组成的链表,设计一个程序,实现对此表进行搜索,找到第一个非零元素后,将此单元和下一个单元清零.,题1:用串操作指令实现:先将100H个数从2170H单

30、元处搬到1000H1单元处,然后从中检索等于AL中字符的单元,并将此单元换成空格字符.参考程序段:MOV SI,2170H MOV DI,1000H MOV CX,100H CLDREP MOVSB;字串传送 CLD MOV CX,100HREPNZ SCASB;AL-DI,不相等,继续,JZ DON;找到,转 JMP P1;没找到,退出DON:DEC DI MOV DI,20H;相等,换成空格符20H P1:HLT,题2:从60H个元素中寻找一个最大的值,并放到AL中.假设这60个元素防在DATA1开始的单元中.参考程序段:MOV CX,60H MOV BX,OFFSET DATA1 MOV

31、 AL,BX DON:INC BX;指向下一个数 CMP AL,BX;AL-BX JA P1;大于转 MOV AL,BX;交换 P1:LOOP DON HLT,开始,BX 元素表首地址CX 60H,BX BX+1,AL=BX?,AL、BX中的数交换,CX CX-1,CX=0?,Y,N,题4框图,暂停,题3:在DS段有一个从TABLE开始的由160个字符组成的链表,设计一个程序,实现对此表进行搜索,找到第一个非零元素后,将此单元和下一个单元清零.注意:不能用串操作指令SCASB搜索,因为字串位于数据段.参考程序段:MOV DI,OFFSET TABLE MOV CX,160 DON:CMP DI,0;DI-0=0?JNZ P1;找到一个0,转P1 INC DI;没找到,指向下一个数 LOOP DON;继续找 P1:MOV DI,AL;清该单元0 MOV DI-1,AL;清下一单元0 HLT,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号