微机程序设计代码例题.docx

上传人:b****1 文档编号:23098457 上传时间:2023-04-30 格式:DOCX 页数:21 大小:47.63KB
下载 相关 举报
微机程序设计代码例题.docx_第1页
第1页 / 共21页
微机程序设计代码例题.docx_第2页
第2页 / 共21页
微机程序设计代码例题.docx_第3页
第3页 / 共21页
微机程序设计代码例题.docx_第4页
第4页 / 共21页
微机程序设计代码例题.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

微机程序设计代码例题.docx

《微机程序设计代码例题.docx》由会员分享,可在线阅读,更多相关《微机程序设计代码例题.docx(21页珍藏版)》请在冰豆网上搜索。

微机程序设计代码例题.docx

微机程序设计代码例题

一、简单程序设计

简单程序设计是没有分支,没有循环的直线运行程序,程序执行按照IP内容自动增加的顺序进行。

例1利用查表法计算平方值。

已知0~9的平方值连续存在以SQTAB开始的存储区域中,求SUR单元内容X的平方值,并放在DIS单元中。

假定0≤X≤9且为整数。

分析:

建立平方表,通过查表完成。

STACKSEGMENT

DB100DUP(?

STACKENDS

DATASEGMENT

SURDB?

DISDB?

SQTABDB0,1,4,9,16,25,36,49,64,81;0~9的平方表

DATAENDS

CODESEGMENT

ASSUMECS:

CODE,DS:

DATA,SS:

STACK,ES:

DATA

BEGIN:

PUSHDS

MOVAX,0

PUSHAX;保证返回DOS,

MOVAX,DATA

MOVDS,AX;为DS送初值

LEABX,SQTAB;以下程序部分完成查表求平方值

MOVAH,0;亦可用查表指令完成(如下程序段)

MOVAL,SUR;AL=XLEABX,SQTAB

ADDBX,AX;MOVAL,SUR

MOVAL,[BX];XLAT

MOVDIS,AL;MOVDIS,AL

CODEENDS

ENDBEGIN

例2已知Z=(X+Y)-(W+Z),其中X,Y,Z,W均为用压缩BCD码表示的数,写出程序。

分析:

这也是一种典型的直线程序,在这里要注意是BCD数相加,要进行十进制调整。

具体程序如下:

MOVAL,Z

MOVBL,W

ADDAL,BL

DAA

MOVBL,AL;BL=(W+Z)

MOVAL,X

MOVDL,Y

ADDAL,DL;AL=(X+Y)

DAA;十进制调整

SUBAL,BL;AL=(X+Y)-(Z+W)

DAS;十进制调整

MOVZ,AL;结果送Z

表3-2子程序R1—R8的入口地址表

P1

子程序R1的入口偏移地址

P2

子程序R2的入口偏移地址

P3

子程序R3的入口偏移地址

……

……

…….

……

P7

子程序R7的入口偏移地址

P8

子程序R8的入口偏移地址

例2利用表实现分支

根据AL中各位被置位情况,控制转移到8个子程序P1~P8之一中去。

转移表的结构如表3-2所示。

分析:

对于这种程序关键要找出每种情况的转移地址,从图中可见

表地址=表基地址+偏移量,而偏移量可由AL各位所在位置*2求得。

流程图见图3-3。

DATASEGMENT

BASEDWSR0,SR1,SR2,SR3,

SR4,SR5,SR6,SR7

DATAENDS

CODESEGMENT

ASSUMECS:

CODE,DS:

DATA,ES:

DATA

BEGIN:

PUSHDS

XORAX,AX

PUSHAX

MOVAX,DATA图3-3流程图

MOVDS,AX

LEABX,BASE;表头送BX

INAL,PORT

GETBIT:

RCRAL,1;右移一位

JCGETAD;移出位是1?

INCBX

INCBX;修改指针

JMPGETBI

GETAD:

JMPWORDPTR[BX];实现散转

CODEENDS

ENDBEGIN

根据跳转表构成方法不同,实现分支的方法也有所改变,下面有三个问题希望大家思考:

(1)若跳转表地址由段值和偏移量四个字节构成,程序应如何实现?

(2)若跳转表中的内容由JMPOPRD指令构成,表的结构应如何组织、程序如何实现?

(3)上述程序若不用间接跳转指令,而改为直接跳转,程序如何变动?

例3将内存中某一区域的原数据块传送到另一区域中。

分析:

这种程序若源数据块与目的数据块之间地址没有重叠,则可直接用传送或串操作实现;若地址重叠,则要先判断源地址+数据块长度是否小于目的地址,若是,则可按增量方式进行,否则要修改指针指向数据块底部,采用减量方式传送。

程序如下:

DATASEGMENT

STRDB1000DUP(?

STR1EQUSTR+7

STR2EQUSTR+25

STRCOUNTEQU50

DATAENDS

STACKSEGMENTPARASTACK‘STACK’

STAPNDB100DUP(?

STACKENDS

CODESEGMENT

ASSUMECS:

CODE,DS:

DATA,ES:

DATA,SS:

STACK

GOOPROC

PUSHDS

SUBAX,AX;将AX清零

PUSHAX

MOVAX,DATA

MOVDS,AX

MOVES,AX

MOVAX,STACK

MOVSS,AX

MOVCX,STRCOUNT

MOVSI,STR1

MOVDI,STR2

CLD;将DF置0确定地址修改方向

PUSHSI;将源首地址入栈

ADDSI,STRCOUNT-1;判断源地址+数据块长度是否小

CMPSI,DI;于目的地址

POPSI;将源首地址弹出堆栈,赋给SI

JLOK;如果源地址+数据;块长度小于目的地址,直接传送数据

STD;如果大于目的地址,将DF置1改变地址修改方向

ADDSI,STRCOUNT-1;从最后一个存储单元传送数据,以免

ADDDI,STRCOUNT-1;把源数据中最后几个单元的数据覆盖

OK:

REPMOVSB

RET

GOOENDP

CODEENDS

ENDGOO

例4设内存BUFF开始的单元中依次存放着30个8位无符号数,求它们的和并放在SUM单元中,试编写程序。

分析:

这是一个求累加的程序。

(设计思想同C语言)程序如下:

MOVSI,BUFF;设地址指针

MOVCX,30;设计数初值

XORAX,AX;设累加器初值

AGAIN:

ADDAL,[SI]

ADCAH,0

INCSI

DECCX

JNZAGAIN;循环累加

MOVSUM,AX

例4在给定个数的16位数串中,找出大于零、等于零和小于零的个数,并紧跟着原串存放。

分析:

这是一个统计问题,须设定三个计数器分别统计三种情况下的结果。

程序如下:

DATASEGMENT

BUFFDWX1,X2,X3,……,Xn

COUNTEQU$-BUFF;此时,COUNT的值为BUFF所占的字节数

PLUSEDB?

ZERODB?

MINUSDB?

DATAENDS

CODESEGMENT

ASSUMECS:

CODE,DS:

DATA

ASSUMEES:

DATA,SS:

STACK

BEGIN:

MOVAX,DATA

MOVDS,AX

MOVCX,COUNT

SHRCX,1;相当于除2,正好为BUFF中的数据个数

MOVDX,0;设定计数器初值

MOVAX,0;设定计数器初值

LEABX,BUFF

AGAIN:

CMPWORDPTR[BX],0

JAEPLU;大于等于0,则转PIU

INCAH;<0,则统计

JMPNEXT

PLU:

JZZER;=0,则转ZER

INCDL;>0,则统计

JMPNEXT

ZER:

INCDH;=0,则统计

NEXT:

INCBX

INCBX

LOOPAGAIN

MOVPLUS,DL

MOVZERO,DH

MOVMINUS,AH

MOVAX,4C00H

INT21H

CODEENDS

ENDBEGIN

第七章

8259A的应用举例

例1.IBMPC机中,只有一片8259A,可接受外部8级中断。

在I/O地址中,分配8259A的端口地址为20H和21H,初始化为:

边沿触发、缓冲连接、中断结束采用EOI命令、中断优先级采用完全嵌套方式,8级中断源的中断类型分别为08H—0FH,初始化程序为:

MOVDX,20H

MOVAL,00010011B

OUTDX,AL;写入ICW1

MOVDX,21H

MOVAL,08H

OUTDX,AL;写入ICW2

MOVAL,00001101B

OUTDX,AL;写入ICW4

XORAL,AL

OUTDX,AL;写入OCW1

STI

例2.进入和退出特殊屏蔽方式的流程图。

假定,初始化之后,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处至B处,允许任何级别的中断源中断IR3的服务程序。

(除本身之外)

IR3中断服务程序入口

STI保护现场

STI开中断

MOVAL,00001000B服务程序

OUT21H,AL;OCW1写入OCW1,使IM3=1

MOVAL,01101000B写入OCW3,使ESMM=SMM=1

OUT20H,AL;OCW3继续服务

写入OCW3,使ESMM=1,SMM=0

MOVAL,01001000B写入OCW1,使IM3=0

OUT20H,AL;OCW3写入OCW2,普通的EOI命令

MOVAL,00H中断返回

OUT21H,AL;OCW1

MOVAL,00100111B

OUT20H,AL;OCW3

OUT21H,AL;OCW3EOI命令

例3.读8259A相关寄存器的内容。

设8259A的端口地址为20H、21H,请读入IRR、ISR、IMR寄存器的内容,

并相继保存在数据段2000H开始的内存单元中;若该8259A为主片,请用查询

方式,查询哪个从片有中断请求。

解:

MOVAL,xxx01010B发OCW3,欲读取IRR的内容

OUT20H,AL

INAL,20H读入并保存IRR的内容

MOV(2000H),AL

MOVAL,xxx01011B发OCW3,欲读取ISR的内容

OUT20H,AL

INAL,20H读入并保存ISR的内容

MOV(2001H),AL

INAL,21H读入并保存ISR的内容

MOV(2002H),AL

MOVAL,xxx0110xB发OCW3,欲查询是否有中断请求

OUT20H

INAL,20H读入相应状态,并判断最高位是否为1

TESTAL,80H

JZDONE

ANDAL,07H判断中断源的编码

…………

DONE:

HLT

第八章

接口应用举例

例4将上例中8255A的工作方式改为方式1,采用中断方式将BUFF开始的缓冲区中的100个字符从打印机输出。

(假设打印机接口仍采用Centronics标准)

分析:

仍用PC0作为打印机的选通,打印机的

作为8255A的A口,

8255A的中断请求信号(PC3)接至系统中断控制器8259A的IR3,其它硬件连线同上例,如图7-15所示。

图7-15中断方式硬件连线

8255A的控制字为:

1010XXX0

PC0置位:

00000001即01H

PC0复位:

00000000即00H

PC6置位:

00001101即0DH,允许8255A的A口输出中断

由硬件连线可以分析出,8255A的4个口地址分别为:

00H,01H,02H,03H。

假设8259A初始化时送ICW2为08H,则8255AA口的中断类型码是0BH,此中断类型码对应的中断向量应放到中断向量表从2CH开始的4个单元中。

主程序:

MAIN:

MOVAL,0A0H

OUT03H,AL;设置8255A的控制字

MOVAL,01H;使选通无效

OUT03H,AL

XORAX,AX

MOVDS,AX

MOVAX,OFFSETROUTINTR

MOVWORDPTR[002CH],AX

MOVAX,SEGROUTINTR

MOVWORDPTR[002EH],AX;送中断向量

MOVAL,0DH

OUT03H,AL;使8255AA口输出允许中断

MOVDI,OFFSETBUFF;设置地址指针

MOVCX,99;设置计数器初值

MOVAL,[DI]

OUT00H,AL;输出一个字符

INCDI

MOVAL,00H

OUT03H,AL;产生选通

INCAL

OUT03H,AL;撤消选通

STI;开中断

NEXT:

HLT;等待中断

LOOPNEXT;修改计数器的值,指向下一个要输出的字符

HLT

中断服务子程序如下:

ROUTINTR:

MOVAL,[DI]

OUT00H,AL:

从A口输出一个字符

MOVAL,00H

OUT03H,AL:

产生选通

INCAL

MOV03H,AL;撤消选通

INCDI:

修改地址指针

IRET:

中断返回

五.8251A应用举例

1.异步模式下的初始化程序举例

设8251A工作在异步模式,波特率系数(因子)为16,7个数据位/字符,偶校验,2个停止位,发送、接收允许,设端口地址为00E2H和00E4H。

完成初始化程序。

分析:

根据题目要求,可以确定模式字为:

11111010B即FAH

而控制字为:

00110111B即37H

则初始化程序如下:

MOVAL,0FAH;送模式字

MOVDX,00E2H

OUTDX,AL;异步方式,7位/字符,偶校验,2个停止位

MOVAL,37H;设置控制字,使发送、接收允许,清出错标志,使

OUTDX,AL;有效

2.同步模式下初始化程序举例

设端口地址为52H,采用内同步方式,2个同步字符(设同步字符为16H),偶校验,7位数据位/字符。

分析:

根据题目要求,可以确定模式字为:

00111000B即38H

而控制字为:

10010111B即97H。

它使8251A对同步字符进行检索;同时使状态寄存器中的3个出错标志复位;此外,使8251A的发送器启动,接收器也启动;控制字还通知8251A,CPU当前已经准备好进行数据传输。

具体程序段如下:

MOVAL,38H;设置模式字,同步模式,用2个同步字符,

OUT52H,AL;7个数据位,偶校验

MOVAL,16H

OUT52H,AL;送同步字符16H

0UT52H,AL

MOVAL,97H;设置控制字,使发送器和接收器启动

OUT52H,AL

3.利用状态字进行编程的举例

下面的程序段先对8251A进行初始化,然后对状态字进行测试,以便输入字符。

本程序段可用来输入80个字符。

分析:

8251A的控制和状态端口地址为52H,数据输入和输出端口地址为50H。

字符输入后,放在BUFFER标号所指的内存缓冲区中。

具体的程序段如下:

MOVAL,0FAH;设置模式字,异步方式,波特率因子为16,

OUT52H,AL;用7个数据位,2个停止位,偶校验

MOVAL,35H;设置控制字,使发送器和接收器启动,

OUT52H,AL;并清除出错指示位

MOVDI,0;变址寄存器初始化

MOVCX,80;计数器初始化,共收取80个字符

BEGIN:

INAL,52H;读取状态字,测试RXRDY位是否为1,如为0,

TESTAL,02H;丢示未收到字符,故继续读取状态字并测试

JZBEGIN

INAL,50;读取字符

MOVDX,OFFSETBUFFER

MOV[DX+DI],AL

INCDI;修改缓冲区指针

INAL,52H;读取状态字

TESTAL,38H;测试有无帧校验错,奇/偶校验错和

JZERROR;溢出错,如有,则转出错处理程序

L00PBEGIN;如没错,则再收下一个字符

JMPEXIT;如输入满足80个字符,则结束

ERROR:

CALLERR-0UT;调出错处理

EXIT:

……

8253的初始化编程

要使用8253,必须首先进行初始化编程,初始化编程包括设置通道控制字和送通道计数初值两个方面,控制字写入8253的控制字寄存器,而初始值则写入相应通道的计数寄存器中。

初始化编程包括如下步骤:

(1).写入通道控制字,规定通道的工作方式

(2).写入计数值,若规定只写低8位,则高8位自动置0,若规定只写高8位,则低8位自动置0。

若为16位计数值则分两次写入,先写低8位,后写高8位。

D0:

用于确定计数数制,0,二进制;1,BCD码

例1:

设8253的端口地址为:

04H~07H,要使计数器1工作在方式0,仅用8位二进制计数,计数值为128,进行初始化编程。

控制字为:

01010000B=50H

初始化程序:

MOVAL,50H

OUT07H,AL

MOVAL,80H

OUT05H,AL

例2:

设8253的端口地址为:

F8H~FBH,若用通道0工作在方式1,按二――十进制计数,计数值为5080H,进行初始化编程。

控制字为:

00110011B=33H

初始化程序:

MOVAL,33H

OUT0FBH,AL

MOVAL,80H

OUT0F8H,AL

MOVAL,50H

OUT0F8H,AL

例3:

设8253的端口地址为:

04H~07H,若用通道2工作在方式2,按二进制计数,计数值为02F0H,进行初始化编程。

(P164 例3)

控制字为:

10110100B=0B4H

初始化程序:

MOVAL,0B4H

OUT07H,AL

MOVAL,0F0H

OUT06H,AL

MOVAL,02H

OUT06H,AL

2.读取8253通道中的计数值

8253可用控制命令来读取相应通道的计数值,由于计数值是16位的,而读取的瞬时值,要分两次读取,所以在读取计数值之前,要用锁存命令,将相应通道的计数值锁存在锁存器中,然后分两次读入,先读低字节,后读高字节。

当控制字中,D5、D4=00时,控制字的作用是将相应通道的计数值锁存的命令,锁存计数值在读取完成之后,自动解锁。

如要读通道1的16位计数器,编程如下:

地址F8H~FBH。

MOVAL,40H;

OUT0FBH,AL;锁存计数值

INAL,0F9H

MOVCL,AL;低八位

INAL,0F9H;

MOVCH,AL;高八位

六、8253的编程应用

例1在IBMPC/XT中,8253作为定时计数器电路,它的三个通道的作用分别为:

计数器0编程为方式3,GATE0固定为高电平,OUT0作为中断请求信号接至8259A中断控制器的第0级IRQ0。

这个定时中断(约55ms)用于报时时钟的时间基准。

计数器1编程为方式2,GATE1固定为高电平,OUT1的输出经过一个D触发器后作为8237A-5DMA控制器通道0的DMA请求DREQ0,用于定时(约15us)启动刷新动态RAM,这样在2ms内可以有132次刷新,大于128次(128次是系统的最低要求)。

计数器2编程为方式3,1KHZ的方波输出,通过滤波,去除高频分量后送扬声器,GATE2是8255的PB0,OUT输出经一与门控制,控制信号为8255的PB1,这样利用PB0、PB1同时为高的时间来控制发长音还是发短音。

时钟频率F为1.19MHZ,T=1/F

8253-5的地址为040H~043H,ROM-BIOS对8253-5的编程如下:

计数器0用于定时中断。

MOVAL,0011 0110B;0011 0110――二进制

OUT43H,AL

MOVAL,0;计数初值为0000,即为

OUT40H,AL

OUT40H,AL;定时为:

,即频率为

――每秒产生

时钟中断(CLK周期为:

计数器1用于定时DMA请求。

MOVAL,0101 0100B;0101 0100――二进制

OUT43H,AL

MOVAL,12H;计数初值为18D,定时:

OUT41H,AL

计数器2用于产生1KHZ的方波送至扬声器发声,声响子程序为BEEP,入口地址为FFA08H。

BEEP  PROC  NEAR

MOVAL,1011 0110B;1011 0110――二进制

OUT43H,AL

MOVAX,0533H;计数初值为1331

OUT42H,AL

MOVAL,AH

OUT42H,AL

INAL,61H;取8255B端口

MOVAH,AL;存在AH

ORAL,03H;使

OUT61H,AL;输出至82255的B端口,使扬声器发声

SUBCX,CX;循环计数

G7:

LOOPG7

MOVBH,0

DECBX;BL的值为控制长短声,BL=6(长),BL=1(短)

JNZG7

MOVAL,AH;恢复8255B端口值,停止发声

OUT61H,AL

RET

BEEPENDP

例2:

CPU为8088,用8253的CH0(通道0),每隔2ms输出一个负脉冲,设CLK为2MHZ,完成软件设计。

分析:

时间常数的计算:

已知时钟频率F及定时时间t,求计数初值N:

    

设用方式2,时间常数:

控制字:

0011 0100――――二进制

端口地址:

CH0――00H;控制端口――03H

初始化编程:

MOVAL,34H;0011 0100B

OUT03H,AL

MOVAX,4000

OUT00H,AL;先送低八位

MOVAL,AH

MOVAL,02H

OUT00H,AL;再送高八位

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

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1