微机原理第八章微型计算机的程序设计ppt课件.ppt
1第八章第八章 微型计算机的程序设计微型计算机的程序设计w顺序结构程序顺序结构程序w分支结构程序分支结构程序w循环结构程序循环结构程序w子程序结构子程序结构2重点重点: :w程序设计方法程序设计方法w顺序结构程序顺序结构程序w分支结构程序分支结构程序w循环结构程序循环结构程序w子程序结构子程序结构38.1 8.1 程序设计步骤程序设计步骤w1.1.分析问题分析问题w2.2.建立数学模型建立数学模型w3.3.确定算法确定算法w4.4.绘制程序流程图绘制程序流程图w5.5.内存分配内存分配w6.6.编制程序编制程序w7.7.程序调试程序调试4wdata segmentw a1 db hellon!,0dh,0ah,$wdata endswStack1 segment para stackw.wStack1 endswcode segmentw assume cs:code,ds:data, ss:stack1w start:mov ax,dataw mov ds,axw mov ah,4chw int 21hwcode endsw end start数据段数据段堆栈段堆栈段代码段代码段58-1 8-1 顺序程序设计顺序程序设计补充:二进制编码的十进制数二进制编码的十进制数 就是BCD码(Binary Coded Decimal)。压缩BCD码 是用4位二进制数表示一位十进制数。一个字节表示两位十进制数。如:1001 0110B 表示 96 D非压缩BCD码 是用一个字节表示一位十进制数。高4位总是0。如: 0000 1001B 表示 9D 两种BCD码的编码对照表6两种两种BCDBCD码的编码对照表码的编码对照表十进制数 压缩 BCD 码 非压缩 BCD 码 0 0000 0000 0000 1 0001 0000 0001 2 0010 0000 0010 3 0011 0000 0011 9 1001 0000 1001 10 0001 0000 0000 0001 0000 0000 11 0001 0001 0000 0001 0000 0001 12 0001 0010 0000 0001 0000 0010 71. BCD数加法调整指令DAA和AAA(P196)wDAA-两个压缩BCD数相加调整指令:w(AL&0FH)9或者AF=1,则AL加6;w(AL&0F0H)90H或CF=1,则AL加60H;w如:MOV AX,3456HADD AL,AH; AL=8AHDAA ;AL=90H8wAAA-两个非压缩BCD数相加调整指令w若(AL&0FH)9或AF=1,则(AL+6)&0FH送AL,AH加1且CF置1;w否则:(AL&0F0H)送AL,AH不变且CF保持0不变;w如:MOV AX,0806H ADD AL,AH ; AL=0EH, AH=08H(没变) MOV AH,0 AAA ;属于第1种情况,故AL为(AL+6)&0F=14H&0FH=04H; AH=01H9w【例【例8.1】的的程序段为程序段为: stack segment stack stack dw 32 dup(0) stack stack ends data segment W1 DW 8931H W2 DW 5678H SUM DB3 DUP(0) data ends codesegmentbegin proc farassume ss: stack, cs: code, ds:datapush dssub ax, axpush ax10mov ax, datamov ds, axMOV AL, BYTE PTR W1 ;AL=31H (+78H)ADD AL, BYTE 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 begin11例8.2 非压缩BCD数W1与W2(均为字变量)相加,将其和送到SUM字节变量中。 data segment W1 DW 0809H ;即即89D W2 DW 0607H ;即即67D SUM DB3 DUP(0) ;一个字节放一个字节放1位位BCD码,用来放加完后的值码,用来放加完后的值156 data ends12MOV AX, W1 ;AX=0809H,W2为为0607HADD AL, BYTE PTR W2 ;AL=H, CF=0,AF=1AAA; 属于第一种情况,故属于第一种情况,故; AL为(为(AL+06H)&0FH=10H+06H )&0FH; =16H&0FH=06H=AL; ;AH加加1且且CF置置CF=1,所以,所以AH=08H+1=09H,则,则AX=0906HMOV SUM, AL ;(SUM)=06HMOV AL,AH; AL=09HADD AL, BYTE PTR W2+1 ; AL=09H+06H=0FH,属于第,属于第1种情况种情况MOV AH, 0AAA ; 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 SUM, ALMOV SUM, AL;见见P151P151132. BCD数减法调整指令DAS和DAA(自看,P198)wDAS-两个压缩BCD数相减调整指令:w(AL&0FH)9,则AL减6;w(AL&0F0H)90H,则AL减60H;w如:MOV AX,5634HSUB AL,AH; AL=DEH, 有借位DAS ;AL=78H,保持借位即134-56AAS-两个非压缩BCD数相减调整指令143. 非压缩BCD数乘除法调整指令AAM和AAD(P199,自看)15顺序程序设计举例:例7.7 镜子程序,P183-184 data segment OBUF DB 0DH, 0AH, $ IBUF DB 0FFH, 0, 255 DUP(0) data ends16MOV DX , OFFSET OBUF ;MOV DX , OFFSET OBUF ;显示提示符显示提示符“”并回车换行并回车换行MOV AH , O9MOV AH , O9INT 21HINT 21HMOV DX , OFFSET IBUF ;MOV DX , OFFSET IBUF ;输入并显示字符串输入并显示字符串MOV AH , 10MOV AH , 10INT 21HINT 21HMOV BL, IBUF+1MOV BL, IBUF+1MOV BH, 0MOV BH, 0MOV IBUFBX+2, $MOV IBUFBX+2, $MOV DL, 0AH ; MOV DL, 0AH ; 换行换行MOV AH, 2MOV AH, 2INT 21HINT 21HMOV DX , OFFSET IBUF+2 ; MOV DX , OFFSET IBUF+2 ; 再显示输入的字符串再显示输入的字符串MOV AH, 9MOV AH, 9INT 21HINT 21H178.2 分支程序设计w特点:利用改变标志位的指令和转移指令来实现。1.无条件转移指令:JMP (见P207)2.条件转移指令:Jcond short-label(偏移地址送到IP)特点:满足条件,则实现段内转移;80386开始才可以转移到代码段的任何位置。1819202122232425268.3 循环程序设计27288.3.2 重复控制指令1.LOOP short-label2.LOOPZ short-label 或或 LOOPE short-label3.LOOPNZ short-label 或或LOOPNE short-label4.JCXZ short-label5.JECXZ short-label共同点:均受共同点:均受CX或或EXC的值控制,详见的值控制,详见P214-215298.3.3 单重循环设计举例w例8.11 计算Z=X+Y,其中X和Y是双字变量w分析:双字变量是4个字节,则和可能占5个字节303132333435363738作业8.4 编写求两个4位非压缩BCD数之和,将和送显示器显示的程序。(P261)w分析:分析:两加数各要4个字节单元,可以为DD类型;考虑到进位,和要5个字节单元,另外,输出到显示器的结束符号$需要一个单元存放,故共需6个字节。因此,数据段定义为:data segment W1 DD 01020304HW2 DD 05060708HSUM DB 5 DUP(0) DB $data ends39代码段中的核心语句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中。下面是输出到显示器的程序语句中。下面是输出到显示器的程序语句MOV DX, OFFSET SUMMOV AH, 09INT 21H 40作业8.5 编写求两个4位压缩BCD数之和,将和送显示器显示的程序。(P261)w分析:分析:两个加数各要2个字节单元,可以为DW类型;考虑到进位,和要3个字节单元,另外,输出到显示器的结束符号$需要一个单元存放,故共需4个字节。因此,数据段定义为:data segment W1 DW 1234HW2 DW 5678HSUM DB 3 DUP(0) DB $data ends41代码段中的核心语句MOV CX, 2MOV SI, 0MOV DI, 2; 要在要在SUM+2中放个位,中放个位,SUM+0中放最高位的进位。中放最高位的进位。XOR AX, AX; 清清CFA1: MOV AL, BYTE PTR W1SI; ADC AL, BYTE PTR W2SIDAAMOV SUMDI, ALINC SIDEC DILOOP A1MOV SUMDI, 0RCL SUMDI; 以上是得到加的结果,放在以上是得到加的结果,放在SUM中。下面是输出到显示器的程序语句中。下面是输出到显示器的程序语句MOV DX, OFFSET SUMMOV AH, 09INT 21H 42作业8.17 编写求输入算式加数1+加数2的和并送显。(加数及其和均为4位(即指压缩)BCD数,P262)w分析:要求先有屏幕显示输出加数1+加数2:,然后从键盘输入两个4个字节的BCD数,加完后送显。w用到的变量:W1和W2因为从键盘输入,均不确定是几位十进制,故需确定其最大位数不超过要用wW1 43例6.2w将内存(将内存(10050)单元的内容拆成两段,每段)单元的内容拆成两段,每段4位,并将它位,并将它们分别们分别 存入内存(存入内存(10051)和()和(10052)单元。即()单元。即(10050)单元中的低单元中的低4位放入(位放入(10051)单元中的低)单元中的低4位,位, 而而(10050)单元中的高)单元中的高4位放入(位放入(10052)单元中的低)单元中的低4位。位。44开始开始初始化初始化用间址方法取数到用间址方法取数到ALAL用用ANDAND指令将该数指令将该数“与与”OFHOFH取得取得低低4 4位,存入内存(位,存入内存(1005110051)单元)单元再取出原始数到再取出原始数到ALAL逻辑右移得高逻辑右移得高4 4位,存入内存(位,存入内存(1005210052)单元)单元暂停暂停45程序段如下:wMOV AX, 1000HwMOV DS, AX ;给段寄存器DS赋值wMOV SI, 50HwMOV AL,SI ;把物理地址为10000H+0050H=10050Hw ; 中的存储内容给ALwAND AL, 0FH ;把AL中的前4位清0,取得低4位值wMOV SI+1, AL;把得到的低4位放到(10051H)单元wMOV AL, SI ;再取出需拆字节放到AL中wMOV CL, 4wSHR AL, CL ;逻辑右移4次,前4位补0;wMOV SI+2, AL ;放入(10052)单元AND AL, F0HMOVE SI+2, AL466-36-3、分枝结构程序、分枝结构程序两分支结构47多分支结构 48例6.3 求AX累加器和BX寄存器中两个无符号数之差的绝对值,结果放在内存(2800)单元中。w分析:不知AX与BX中数的大小,故需先判断谁大,然后用大的减小的才可求得绝对值,w 其流程图如图6-549开始开始初始化,清初始化,清CFCFAX-BX AXAX-BX AXAX AX 内存(内存(28002800和(和(2801)2801)单元单元暂停暂停AX-BX0AX-BX0AX-BX AXAX-BX AXBX BX 内存(内存(28002800和(和(2801)2801)单元单元否否是是50相应程序段如下 (p141)w CLCw SUB AX,BXw JC AA ;进位位为1,就转移到AAw MOV DI, 2800Hw MOV DI, AXw HLTwAA: SUB BX, AXw MOV DI, 2800Hw MOV DI, BXw HLT51例6.4 从外设71号中取一个数M,判断其值是否在10和20之间,即10M20.如果M20H,则送0FFH给外设73H;如果M10,则送00H给外设73H; 如果10M1,并且放在内存(,并且放在内存(2001)单元中,而数据块本)单元中,而数据块本身是从(身是从(2002)单元开始存放的,最后,把找出的)单元开始存放的,最后,把找出的最大值放到(最大值放到(2000)单元中。假设这段数据块中的)单元中。假设这段数据块中的数都是无符号的数都是无符号的8位数。位数。w(1)分析题目:此题必定是个循环程序,而且在处理部分应包括判)分析题目:此题必定是个循环程序,而且在处理部分应包括判断分支环节。断分支环节。 (2)根据指令系统,我们可以采用寻找最大值的计算方法。)根据指令系统,我们可以采用寻找最大值的计算方法。74 首先,我们用首先,我们用00值放在值放在AL累加器中作为最大值;累加器中作为最大值;然后,用数据块的第一个数和然后,用数据块的第一个数和AL中的数做比较,如果中的数做比较,如果比比00大,则用这个数取代大,则用这个数取代00,放入,放入AL中;接着取出第中;接着取出第二个数与二个数与AL中的数做比较,如果比它大,取而代之,中的数做比较,如果比它大,取而代之,否则不取代,如此往复,直至最后一个数。这样,最否则不取代,如此往复,直至最后一个数。这样,最后后AL累加器中必定存放着最大的数。这就是寻找最大累加器中必定存放着最大的数。这就是寻找最大值的方法,而数据块的总长度(数的个数)就是循环值的方法,而数据块的总长度(数的个数)就是循环次数。次数。 (3)绘制出此计算过程的程序流程如图)绘制出此计算过程的程序流程如图6-l5所示。所示。757677改为子程序时的程序段wMAX: PUSHFw PUSH AXw PUSH CXw PUSH SIwSTART: MOV SI, 2001Hw MOV CL, SIw INC SIw MOV AL, 00w MOV CH, 00HwLP: CLCw CMP AL, SIw JC BBw JMP AAwBB: MOV AL, SIwAA: INC SIw LOOP LPw MOV 2000H, AL w HLTw POP SIw POP CXw POP AXw POPFw RETSUB1 PROC NEAR/FARSUB1 PROC NEAR/FARSUB1 ENDPSUB1 ENDP78791、调用程序和子程序在同一代码段、调用程序和子程序在同一代码段 子程序的类型应为子程序的类型应为NEAR cod1 segment CALL SUB1 . SUB1 PROC NEAR . RET SUB1 ENDP cod1 ends红色部分为子程序红色部分为子程序子程序调用方式介绍:子程序调用方式介绍:802、调用程序和子程序、调用程序和子程序不在同一代码段不在同一代码段子程序的类型应为子程序的类型应为FAR。子程序子程序SUB1的类型是的类型是FAR,可段间调用可段间调用,也可段内调用也可段内调用.CODE2 SEGMENT . SUB1 PROC NEAR . RET SUB1 ENDP . CALL SUB1 .CODE2 ENDSCODE1 SEGMENT CALL FAR PTR SUB1 . CODE1 ENDS81 CODE2 SEGMENT . SUB1 PROC NEAR . SUB1 ENDP . CALL SUB1 ;段内调用段内调用 . CODE2 ENDS 子程序子程序SUB1的类型是的类型是FAR,可段间调用可段间调用,也可也可段内调用段内调用.826.6 查表程序查表程序w要点:要点:w1)确定表格的起始地址(或称基地址)给)确定表格的起始地址(或称基地址)给BXw2)确定要查找对象在表中的序号,(或称索引值)给)确定要查找对象在表中的序号,(或称索引值)给AL。w3)要用到换码指令)要用到换码指令XLAT,将累加器中的值变为内存表,将累加器中的值变为内存表格中的某一个值。格中的某一个值。w注:表格的起始地址为内存物理地址中的偏移地址注:表格的起始地址为内存物理地址中的偏移地址83例例6.9: 在在5.2节中表节中表5-2所列的十进制的所列的十进制的7段显示码段显示码实例,用程序来实现,假设这段数据存放在实例,用程序来实现,假设这段数据存放在2000H开始的内存中,取出开始的内存中,取出“5”所对应的所对应的7段码。段码。w程序段为:wSTART: MOV BX, 2000Hw MOV AL, 5w XLATw HLT84例例2 编一子程序利用编一子程序利用XLAT指令把十六进制数转换成指令把十六进制数转换成ASCII码。假设码。假设ASCII码存放在以码存放在以DAT1为首地址的数据区中,对为首地址的数据区中,对应的十六进制数放在以应的十六进制数放在以DAT2为首地址的数据区中,转换结为首地址的数据区中,转换结果送以果送以DAT3为首地址的数据区中。为首地址的数据区中。w分析:首地址即基址分析:首地址即基址DAT1送给送给BX,ASCII码表总共有码表总共有7FH(即(即128)个字符。所以索引值要从个字符。所以索引值要从0变到变到128(存放在(存放在DAT2为首地址的数据区为首地址的数据区中),需要用到循环将得到的值送到以中),需要用到循环将得到的值送到以DAT3为首地址的数据区中。为首地址的数据区中。w查表核心程序语句为:查表核心程序语句为:w MOV BX, 2000H(表的首地址)(表的首地址)w MOV AL, 5(表中对应的偏移量,即索引值)(表中对应的偏移量,即索引值)w XLATw此程序段的结果是将查到的结果送到累加器此程序段的结果是将查到的结果送到累加器AX中中85wSUB1 PROC NEARwSTART: LEA SI, DAT2;或为MOV SI, DAT2w LEA DI, DAT3; 或为 MOV DI, DAT3w MOV BX, DAT1w MOV CX, 16wLP1: MOV AL, SI; 或为 LODSB ,即从RAM AX/ALw XLATw MOV DI, AL; STOSB, 即从AX/AL RAMw INC SI ;若用了LODSB与STOSB,则不用此两句,w INC DI ; 因为串操作时SI和DI作自动增量修改w LOOP LP1w w RETwSUB1 ENDPw POP ALPOP ALP0P CXP0P CXPOP DIPOP DIPOP SIPOP SIPOP BXPOP BXPUSH BXPUSH BXPUSH SIPUSH SIPUSH DIPUSH DIPUSH CXPUSH CXPUSH ALPUSH AL861、 用串操作指令实现用串操作指令实现:先将先将100H个数从个数从2170H单元处搬到单元处搬到1000H1单元处单元处,然后从中检索等于然后从中检索等于AL中字符的单元中字符的单元,并将此单元换成空格字符并将此单元换成空格字符.2、从、从60H个元素中寻找一个最大的值个元素中寻找一个最大的值,并放到并放到AL中中. 假设这假设这60个元素防在个元素防在DATA1开始的单元中开始的单元中.3、在、在DS段有一个从段有一个从TABLE开始的由开始的由160个字符组成的链表个字符组成的链表,设计一个程序设计一个程序,实现对此表进行搜索实现对此表进行搜索,找到第一个非零元素后找到第一个非零元素后,将此单元和下一个单元将此单元和下一个单元清零清零.87 题题1: 用串操作指令实现用串操作指令实现:先将先将100H个数从个数从2170H单元处搬到单元处搬到1000H1单元处单元处,然后从中检索等于然后从中检索等于AL中字符中字符的单元的单元,并将此单元换成空格字符并将此单元换成空格字符. 参考程序段参考程序段: MOV SI,2170H MOV DI,1000H MOV CX,100H CLDREP MOVSB ;字串传送字串传送 CLD MOV CX,100HREPNZ SCASB ; AL- - DI,不相等不相等,继续继续 88JZ DON ;找到找到,转转 JMP P1 ;没找到没找到,退出退出DON: DEC DI MOV DI,20H ;相等相等,换成空格符换成空格符20H P1: HLT 89 题题2:从从60H个元素中寻找一个最大的值个元素中寻找一个最大的值,并放到并放到AL中中. 假设这假设这60个元素防在个元素防在DATA1开始的单元中开始的单元中. 参考程序段参考程序段: MOV CX, 60H MOV BX, OFFSET DATA1 MOV AL, BX DON: INC BX ;指向下一个数指向下一个数 CMP AL, BX ;AL- - BX JA P1 ;大于转大于转 MOV AL, BX ;交换交换 P1 : LOOP DON HLT 90开始BX 元素表首地址元素表首地址CX 60H BX BX+1AL =BX?AL、BX中的数交换中的数交换CX CX-1-1CX=0?YN题题4框图框图暂停暂停91 题题3:在在DS段有一个从段有一个从TABLE开始的由开始的由160个字符个字符组成的链表组成的链表,设计一个程序设计一个程序,实现对此表进行搜索实现对此表进行搜索,找到找到第一个非零元素后第一个非零元素后,将此单元和下一个单元清零将此单元和下一个单元清零. 注意注意:不能用串操作指令不能用串操作指令SCASB搜索搜索,因为字串位于因为字串位于数据段数据段. 参考程序段参考程序段: MOV DI,OFFSET TABLE MOV CX,160 DON: CMP DI, 0 ;DI - 0 - 0 =0? JNZ P1 ;找到一个找到一个0,转转P1 INC DI ;没找到没找到,指向下一个数指向下一个数 LOOP DON ;继续找继续找 P1: MOV DI,AL ;清该单元清该单元0 MOV DI-1DI-1,AL ;清下一单元清下一单元0 HLT