1、微机程序设计代码例题一、简单程序设计简单程序设计是没有分支,没有循环的直线运行程序,程序执行按照IP内容自动增加的顺序进行。例1 利用查表法计算平方值。已知0 9的平方值连续存在以SQTAB开始的存储区域中,求SUR单元内容X的平方值,并放在DIS单元中。假定0X 9且为整数。分析:建立平方表,通过查表完成。STACK SEGMENT DB 100 DUP(?)STACK ENDSDATA SEGMENT SUR DB ? DIS DB ? SQTAB DB 0,1,4,9,16,25,36,49,64,81 ; 09的平方表DATA ENDSCODE SEGMENT ASSUME CS:CO
2、DE,DS:DATA,SS:STACK,ES:DATABEGIN:PUSH DS MOV AX,0 PUSH AX ;保证返回DOS, MOV AX,DATA MOV DS,AX ;为DS送初值 LEA BX,SQTAB ;以下程序部分完成查表求平方值 MOV AH,0 ;亦可用查表指令完成(如下程序段) MOV AL,SUR ;AL=X LEA BX, SQTAB ADD BX,AX ; MOV AL, SUR MOV AL,BX ; XLAT MOV DIS,AL ; MOV DIS, ALCODE ENDS END BEGIN例2 已知 Z=(X+Y)-(W+Z),其中X,Y,Z,W均为
3、用压缩BCD码表示的数,写出程序。分析:这也是一种典型的直线程序,在这里要注意是BCD数相加,要进行十进制调整。具体程序如下: MOV AL,Z MOV BL,W ADD AL,BL DAA MOV BL,AL ; BL=(W+Z) MOV AL,X MOV DL,Y ADD AL,DL ; AL=(X+Y) DAA ;十进制调整 SUB AL,BL ; AL=(X+Y)-(Z+W) DAS ;十进制调整 MOV Z,AL ;结果送Z 表3-2 子程序R1R8的入口地址表P1子程序R1的入口偏移地址P2子程序R2的入口偏移地址P3子程序R3的入口偏移地址.P7子程序R7的入口偏移地址P8子程序
4、R8的入口偏移地址例2 利用表实现分支根据AL中各位被置位情况,控制转移到8个子程序P1P8之一中去。转移表的结构如表3-2所示。分析:对于这种程序关键要找出每种情况的转移地址,从图中可见表地址=表基地址+偏移量, 而偏移量可由AL各位所在位置*2求得。流程图见图3-3。DATA SEGMENTBASE DW SR0,SR1,SR2,SR3, SR4,SR5,SR6,SR7DATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA,ES:DATABEGIN: PUSH DS XOR AX,AX PUSH AX MOV AX,DATA 图3-3 流程图 MOV DS,
5、AX LEA BX,BASE ;表头送BX IN AL,PORT GETBIT: RCR AL,1 ;右移一位 JC GETAD ;移出位是1?INC BXINC BX ;修改指针JMP GETBI GETAD: JMP WORD PTRBX ;实现散转CODE ENDS END BEGIN根据跳转表构成方法不同,实现分支的方法也有所改变,下面有三个问题希望大家思考:(1) 若跳转表地址由段值和偏移量四个字节构成,程序应如何实现?(2) 若跳转表中的内容由JMP OPRD指令构成,表的结构应如何组织、程序如何实现?(3) 上述程序若不用间接跳转指令,而改为直接跳转,程序如何变动?例3 将内存中
6、某一区域的原数据块传送到另一区域中。分析:这种程序若源数据块与目的数据块之间地址没有重叠,则可直接用传送或串操作实现;若地址重叠,则要先判断源地址+数据块长度是否小于目的地址,若是,则可按增量方式进行,否则要修改指针指向数据块底部,采用减量方式传送。程序如下:DATA SEGMENTSTR DB 1000 DUP(?)STR1 EQU STR+7STR2 EQU STR+25STRCOUNT EQU 50DATA ENDSSTACK SEGMENT PARA STACK STACKSTAPN DB 100DUP(?)STACK ENDSCODE SEGMENT ASSUME CS:CODE,D
7、S:DATA,ES:DATA,SS:STACKGOO PROC PUSH DS SUB AX,AX ;将AX清零 PUSH AX MOV AX,DATA MOV DS,AX MOV ES,AX MOV AX,STACK MOV SS,AX MOV CX,STRCOUNT MOV SI,STR1 MOV DI,STR2 CLD ;将DF置0确定地址修改方向 PUSH SI ;将源首地址入栈 ADD SI,STRCOUNT-1 ;判断源地址+数据块长度是否小 CMP SI,DI ;于目的地址 POP SI ;将源首地址弹出堆栈,赋给SIJL OK ;如果源地址数据;块长度小于目的地址,直接传送数据
8、STD ;如果大于目的地址,将DF置1改变地址修改方向 ADD SI,STRCOUNT-1 ;从最后一个存储单元传送数据,以免 ADD DI,STRCOUNT-1 ;把源数据中最后几个单元的数据覆盖OK: REP MOVSB RETGOO ENDPCODE ENDS END GOO例4 设内存BUFF开始的单元中依次存放着30个8位无符号数,求它们的和并放在SUM单元中,试编写程序。分析:这是一个求累加的程序。(设计思想同C语言)程序如下:MOV SI,BUFF ;设地址指针MOV CX,30 ;设计数初值XOR AX,AX ;设累加器初值AGAIN: ADD AL,SI ADC AH,0 I
9、NC SI DEC CX JNZ AGAIN ;循环累加 MOV SUM,AX例4 在给定个数的16位数串中,找出大于零、等于零和小于零的个数,并紧跟着原串存放。分析:这是一个统计问题,须设定三个计数器分别统计三种情况下的结果。程序如下:DATA SEGMENTBUFF DW X1,X2,X3,XnCOUNT EQU $-BUFF ;此时,COUNT的值为BUFF所占的字节数PLUSE DB ?ZERO DB ?MINUS DB ?DATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATAASSUME ES:DATA,SS:STACKBEGIN: MOV AX,DA
10、TA MOV DS,AX MOV CX,COUNT SHR CX,1 ;相当于除2,正好为BUFF中的数据个数 MOV DX,0 ;设定计数器初值 MOV AX,0 ;设定计数器初值 LEA BX,BUFFAGAIN: CMP WORD PTRBX,0 JAE PLU ;大于等于0,则转PIU INC AH ;0,则统计 JMP NEXTZER: INC DH ;0,则统计NEXT: INC BX INC BX LOOP AGAIN MOV PLUS,DL MOV ZERO,DH MOV MINUS,AH MOV AX,4C00H INT 21HCODE ENDS END BEGIN第七章82
11、59A的应用举例例1 IBMPC机中,只有一片8259A,可接受外部8级中断。在I/O地址中,分配8259A的端口地址为20H和21H,初始化为:边沿触发、缓冲连接、中断结束采用EOI命令、中断优先级采用完全嵌套方式,8级中断源的中断类型分别为08H0FH,初始化程序为: MOV DX,20H MOV AL,00010011B OUT DX,AL ;写入ICW1 MOV DX,21H MOV AL,08H OUT DX,AL ;写入ICW2 MOV AL,00001101B OUT DX,AL ;写入ICW4 XOR AL,AL OUT DX,AL ;写入OCW1 。 STI 。例2进入和退出
12、特殊屏蔽方式的流程图。 假定,初始化之后,8259A工作于完全嵌套方式,要求对于IR3的中断级,能够允许任何级别的中断中断其中断服务程序,即8259A按特殊屏蔽方式工作。因而在响应IR3而执行IR3的中断服务程序时,在A处,写入OCW1以屏蔽IR3,然后写入OCW3使ESMM=SMM=1,于是从A处开始,8259A进而特殊屏蔽方式,此后继续执行IR3的中断服务程序。在中断服务结束之前,再向8259A写入OCW3使ESMM=1,SMM=0,结束特殊屏蔽方式,返回到完全嵌套方式,接着写入OCW1,撤消对IR3的屏蔽,最后写入OCW2,向8259A发出EOI命令。此例,说明在IR3的中断服务程序的A
13、处至B处,允许任何级别的中断源中断IR3的服务程序。(除本身之外) 。 IR3中断服务程序入口 STI 保护现场 。 STI 开中断 MOV AL,00001000B 服务程序 OUT 21H,AL ;OCW1 写入OCW1,使IM3=1 MOV AL,01101000B 写入OCW3,使ESMM=SMM=1 OUT 20H,AL ;OCW3 继续服务 。 写入OCW3,使ESMM=1,SMM=0 MOV AL,01001000B 写入OCW1,使IM3=0 OUT 20H,AL ;OCW3 写入OCW2,普通的EOI命令 MOV AL,00H 中断返回 OUT 21H,AL ;OCW1 MO
14、V AL,00100111B OUT 20H,AL ;OCW3 OUT 21H,AL ;OCW3 EOI命令例3读8259A相关寄存器的内容。设8259A的端口地址为20H、21H,请读入IRR、ISR、IMR寄存器的内容,并相继保存在数据段2000H开始的内存单元中;若该8259A为主片,请用查询方式,查询哪个从片有中断请求。解:MOV AL,xxx01010B 发OCW3,欲读取IRR的内容OUT 20H,ALIN AL,20H 读入并保存IRR的内容 MOV (2000H),ALMOV AL,xxx01011B 发OCW3,欲读取ISR的内容 OUT 20H,ALIN AL,20H 读入
15、并保存ISR的内容MOV (2001H),ALIN AL,21H 读入并保存ISR的内容MOV (2002H),ALMOV AL,xxx0110xB 发OCW3,欲查询是否有中断请求OUT 20HIN AL,20H 读入相应状态,并判断最高位是否为1TEST AL,80H JZ DONEAND AL,07H 判断中断源的编码 DONE:HLT第八章接口应用举例 例4 将上例中8255A的工作方式改为方式1,采用中断方式将BUFF开始的缓冲区中的100个字符从打印机输出。(假设打印机接口仍采用Centronics标准)分析:仍用PC0作为打印机的选通,打印机的作为8255A的A口, 8255A的
16、中断请求信号(PC3)接至系统中断控制器8259A的IR3,其它硬件连线同上例,如图7-15所示。图7-15 中断方式硬件连线8255A的控制字为:1010XXX0 PC0置位: 00000001 即 01HPC0复位: 00000000 即 00HPC6置位: 00001101 即 0DH ,允许8255A的A口输出中断由硬件连线可以分析出,8255A的4个口地址分别为:00H,01H,02H,03H。假设8259A初始化时送ICW2为08H,则8255A A口的中断类型码是0BH,此中断类型码对应的中断向量应放到中断向量表从2CH开始的4个单元中。主程序: MAIN: MOV AL,0A0
17、H OUT 03H,AL ;设置8255A的控制字 MOV AL,01H ;使选通无效 OUT 03H,AL XOR AX,AX MOV DS,AX MOV AX,OFFSET ROUTINTR MOV WORD PTR 002CH,AX MOV AX,SEG ROUTINTR MOV WORD PTR 002EH,AX ;送中断向量 MOV AL,0DH OUT 03H,AL ;使8255A A口输出允许中断 MOV DI,OFFSET BUFF ;设置地址指针 MOV CX,99 ;设置计数器初值 MOV AL,DI OUT 00H,AL ;输出一个字符 INC DI MOV AL,00H
18、 OUT 03H,AL ;产生选通 INC AL OUT 03H,AL ;撤消选通 STI ;开中断NEXT: HLT ;等待中断 LOOP NEXT ;修改计数器的值,指向下一个要输出的字符 HLT中断服务子程序如下:ROUTINTR:MOV AL,DI OUT 00H,AL :从A口输出一个字符 MOV AL,00H OUT 03H,AL :产生选通 INC AL MOV 03H,AL ;撤消选通 INC DI :修改地址指针 IRET :中断返回五8251A应用举例1异步模式下的初始化程序举例 设8251A工作在异步模式,波特率系数(因子)为16,7个数据位/字符,偶校验,2个停止位,发
19、送、接收允许,设端口地址为00E2H和00E4H。完成初始化程序。分析:根据题目要求,可以确定模式字为:11111010B 即FAH而控制字为:00110111B 即37H则初始化程序如下:MOV AL, 0FAH ;送模式字MOV DX,00E2HOUT DX, AL ;异步方式,7位/字符,偶校验,2个停止位 MOV AL,37H ;设置控制字,使发送、接收允许,清出错标志,使、 OUT DX, AL ;有效 2同步模式下初始化程序举例 设端口地址为52H,采用内同步方式,2个同步字符(设同步字符为16H),偶校验,7位数据位/字符。分析:根据题目要求,可以确定模式字为:00111000B
20、 即38H而控制字为:10010111B 即97H。它使8251A对同步字符进行检索;同时使状态寄存器中的3个出错标志复位;此外,使8251A的发送器启动,接收器也启动;控制字还通知8251A,CPU当前已经准备好进行数据传输。 具体程序段如下: MOV AL,38H ;设置模式字,同步模式,用2个同步字符, OUT 52H,AL ; 7个数据位,偶校验 MOV AL,16H OUT 52H,AL ;送同步字符16H 0UT 52H,AL MOV AL, 97H ;设置控制字,使发送器和接收器启动OUT 52H, AL3利用状态字进行编程的举例 下面的程序段先对8251A进行初始化,然后对状态
21、字进行测试,以便输入字符。本程序段可用来输入80个字符。 分析:8251A的控制和状态端口地址为52H,数据输入和输出端口地址为50H。字符输入后,放在BUFFER标号所指的内存缓冲区中。具体的程序段如下: MOV AL,0FAH ;设置模式字,异步方式,波特率因子为16, OUT 52H,AL ;用7个数据位,2个停止位,偶校验 MOV AL,35H ;设置控制字,使发送器和接收器启动, OUT 52H,AL ;并清除出错指示位 MOV DI,0 ;变址寄存器初始化MOV CX,80 ;计数器初始化,共收取80个字符BEGIN:IN AL,52H ;读取状态字,测试RXRDY位是否为1,如为
22、0, TEST AL,02H ;丢示未收到字符,故继续读取状态字并测试 JZ BEGIN IN AL,50 ;读取字符MOV DX,OFFSET BUFFERMOV DX+DI,AL INC DI ;修改缓冲区指针 IN AL,52H ;读取状态字 TEST AL,38H ;测试有无帧校验错,奇/偶校验错和 JZ ERROR ;溢出错,如有,则转出错处理程序 L00P BEGIN ;如没错,则再收下一个字符 JMP EXIT ;如输入满足80个字符,则结束ERROR: CALL ERR-0UT ;调出错处理 EXIT: 8253的初始化编程 要使用8253,必须首先进行初始化编程,初始化编程包
23、括设置通道控制字和送通道计数初值两个方面,控制字写入8253的控制字寄存器,而初始值则写入相应通道的计数寄存器中。初始化编程包括如下步骤:(1)写入通道控制字,规定通道的工作方式(2)写入计数值,若规定只写低8位,则高8位自动置0,若规定只写高8位,则低8位自动置0。若为16位计数值则分两次写入,先写低8位,后写高8位。D0:用于确定计数数制,0,二进制;1,BCD码例1:设8253的端口地址为:04H07H,要使计数器1工作在方式0,仅用8位二进制计数,计数值为128,进行初始化编程。控制字为:01010000B=50H初始化程序: MOV AL,50H OUT 07H,AL MOV AL,
24、80H OUT 05H,AL例2:设8253的端口地址为:F8HFBH,若用通道0工作在方式1,按二十进制计数,计数值为5080H,进行初始化编程。控制字为:00110011B=33H初始化程序: MOV AL,33H OUT 0FBH,AL MOV AL,80H OUT 0F8H,AL MOV AL,50H OUT 0F8H,AL例3:设8253的端口地址为:04H07H,若用通道2工作在方式2,按二进制计数,计数值为02F0H,进行初始化编程。(P164例3)控制字为:10110100B=0B4H初始化程序: MOV AL,0B4H OUT 07H,AL MOV AL,0F0H OUT 0
25、6H,AL MOV AL,02H OUT 06H,AL2读取8253通道中的计数值8253可用控制命令来读取相应通道的计数值,由于计数值是16位的,而读取的瞬时值,要分两次读取,所以在读取计数值之前,要用锁存命令,将相应通道的计数值锁存在锁存器中,然后分两次读入,先读低字节,后读高字节。当控制字中,D5、D4=00时,控制字的作用是将相应通道的计数值锁存的命令,锁存计数值在读取完成之后,自动解锁。如要读通道1的16位计数器,编程如下:地址F8HFBH。MOV AL,40H;OUT 0FBH,AL ;锁存计数值IN AL,0F9HMOV CL,AL;低八位IN AL,0F9H;MOV CH,AL
26、;高八位六、 8253的编程应用例1 在IBM PC/XT中,8253作为定时计数器电路,它的三个通道的作用分别为:计数器0编程为方式3,GATE0固定为高电平,OUT0作为中断请求信号接至8259A中断控制器的第0级IRQ0。这个定时中断(约55ms)用于报时时钟的时间基准。计数器1编程为方式2,GATE1固定为高电平,OUT1的输出经过一个D触发器后作为8237A5DMA控制器通道0的DMA请求DREQ0,用于定时(约15us)启动刷新动态RAM,这样在2ms内可以有132次刷新,大于128次(128次是系统的最低要求)。计数器2编程为方式3,1KHZ的方波输出,通过滤波,去除高频分量后送
27、扬声器,GATE2是8255的PB0,OUT输出经一与门控制,控制信号为8255的PB1,这样利用PB0、PB1同时为高的时间来控制发长音还是发短音。 时钟频率F为1.19MHZ,T=1/F82535的地址为040H043H,ROMBIOS对82535的编程如下:计数器0用于定时中断。MOV AL,00110110B;00110110二进制OUT 43H,ALMOV AL,0;计数初值为0000,即为OUT 40H,ALOUT 40H,AL;定时为:,即频率为每秒产生次 时钟中断(CLK周期为:)计数器1用于定时DMA请求。MOV AL,01010100B;01010100二进制OUT 43H
28、,ALMOV AL,12H;计数初值为18D,定时: OUT 41H,AL计数器2用于产生1KHZ的方波送至扬声器发声,声响子程序为BEEP,入口地址为FFA08H。 BEEP PROCNEAR MOV AL,10110110B;10110110二进制 OUT 43H,AL MOV AX,0533H;计数初值为1331 OUT 42H,AL MOV AL,AH OUT 42H,AL IN AL,61H;取8255B端口 MOV AH,AL;存在AH OR AL,03H;使 OUT 61H,AL;输出至82255的B端口,使扬声器发声 SUB CX,CX;循环计数G7: LOOP G7 MOV
29、BH,0 DEC BX;BL的值为控制长短声,BL6(长),BL1(短) JNZ G7 MOV AL,AH;恢复8255B端口值,停止发声 OUT 61H,AL RET BEEP ENDP例2:CPU为8088,用8253的CH0(通道0),每隔2ms输出一个负脉冲,设CLK为2MHZ,完成软件设计。分析:时间常数的计算:已知时钟频率F及定时时间t,求计数初值N:设用方式2,时间常数: 控制字:00110100二进制端口地址:CH000H;控制端口03H初始化编程:MOV AL,34H ;00110100BOUT 03H,ALMOV AX,4000OUT 00H,AL ;先送低八位MOV AL,AHMOV AL,02HOUT 00H,AL ;再送高八位
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1