汇编语言程序设计第10章_第1页
汇编语言程序设计第10章_第2页
汇编语言程序设计第10章_第3页
汇编语言程序设计第10章_第4页
汇编语言程序设计第10章_第5页
已阅读5页,还剩148页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第10章中断和输入/输出程序设计10.1概述10.2中断处理程序设计10.3DOS功能调用10.4BIOS中断调用10.5输入/输出程序设计10.1概述在微型计算机中,CPU与外部设备之间的信息传送是通过接口进行的,每个接口由一组寄存器组成,这些寄存器用来存放命令、状态和数据,为了对这些寄存器进行存取,它们都分配有一个称为I/O端口的地址编码。在80x86系统中,I/O端口编址在一个独立的地址空间中,这个空间对80x86来讲,允许设置64K个8位端口或32K个16位端口;80386和80486提供了一个独立的I/O地址空间。I/O地址空间由216(64K)个可独立编址的8位端口(即64KB)组成。任意两个连续的8位端口可作为16位端口处理;4个连续的8位端口可作为32位端口处理。因此,这个I/O地址空间对80486来讲,最多能提供64K个8位端口、32K个16位端口、16K个32位端口或总容量不超过64KB的不同位端口的组合。这64K的I/O地址空间是指物理地址而不是线性地址,因为I/O指令不经过分段或分页部件。处理器要访问的是存储地址空间还是I/O地址空间是容易区分的。所有I/O端口与CPU之间的通信都是由输入/输出指令完成的。其中输入指令完成从I/O到CPU的信息传送;而输出指令完成从CPU到I/O的信息传送。输入和输出设备是计算机系统的重要组成部分。程序、数据和各种现场采集到的信息要通过输入装置输入至计算机。计算结果或各种控制信息要输出到各种输出设备,以便显示、打印和实现各种控制操作。因此,CPU与输入/输出设备之间的信息交换也是计算机系统中非常重要和十分频繁的操作。输入过程是:输入设备把数据送到接口,由CPU执行输入程序把接口中的数据读入CPU,再根据需要放入存储器或寄存器中。处理程序完成对数据的处理并将处理结果放入指定的寄存器或存储器中。输出过程:CPU执行输出程序,将存储器或寄存器中等待输出的内容送到输出接口中,然后启动输出设备,将接口中的数据通过输出设备输出。输入/输出的基本条件是:连接CPU与外设的接口电路和相应的软件——驱动程序。10.1.1I/O指令IN和OUT1.格式输入指令:

INOP1,OP2INAL,imm8INAX,imm8INEAX,imm8

INAL,DXINAX,DX

INEAX,DX输出指令:

OUTOP1,OP2OUTimm8,ALOUTimm8,AXOUTimm8,EAX

OUTDX,AL

OUTDX,AXOUTDX,EAX

2.功能:

I/O指令IN和OUT用于在I/O端口和AL、AX或EAX累加器之间交换数据。输入指令IN完成从I/O到CPU的信息传送;输出指令OUT完成从CPU到I/O的信息传送。

3.端口访问方法80486有16条I/O地址线,I/O端口范围是64K。访问端口方法有两种:①用1字节立即数指定的方法,可以访问0~255的端口;②采用DX寄存器间接寻址方法,可以访问0~(64K-1)个端口中的任一端口。

4.举例

INAL,0FAH ;从端口0FAH输入8位数到ALINEAX,28H ;将端口28H、29H、2AH和2BH的32位数送EAXMOVDX,3AEH ;I/O地址大于255时,应通过DX间接寻址

IN AX,DX ;从DX指出的端口输入16位数到AXOUT21H,AL ;将8位数从AL输出到端口21HOUTDX,EAX ;将32位数从EAX输出到DX指出的端口

5.说明在保护方式下,当处理器遇到一条I/O指令时,它首先检查现行任务的特权级是否高于或等于I/O特权级,即是否CPL≤IOP1。若是,则执行I/O操作;否则,处理器检查I/O允许位图,若I/O允许位图不允许访问,则会发生异常13。10.1.2端口地址通过以上叙述可以看出,在进行I/O程序设计时,需要对端口地址、控制及状态端口的各位含义有清楚的了解。IBMPC机的部分端口地址如表10-1所示。控制及状态端口各位的含义在讨论具体外设时描述。表10-1端口地址对照表端口地址端口设备或接口芯片00H~0FHDMA控制器0H~21H中断控制器40H~43H时钟/定时器60H~63H可编程外围接口芯片200~20FH游戏适配器2F8H~2FEHCOM1320H~32FH硬盘控制器378H~37AH2号并行口(打印机适配器)3B0H~3BFH单色显示及1号并行口3D0H~3DFH彩色/图形适配器3F0H~3F7H软盘控制器3F8H~3FEHCOM210.1.3CPU与外设之间的信息交换方式

CPU与外设通过硬件接口电路或控制器相连接,这些接口或控制器中都有数量不等的端口,用作CPU与外设之间传送数据及提供数据传送所需要的控制逻辑与信号。使用IN、OUT指令对这些端口进行操作,便可以实现CPU与外设的信息交换。概括起来,CPU与外设需要交换的信息有:数据信息、状态信息以及控制信息。例如,当需要在打印机上打印一个字符(数据)时,需要先检查打印机是否准备好(状态),若准备好则输出选通命令(控制),以便打印。

CPU与外设之间的信息交换通常有程序查询、中断传送、DMA(直接存储器存取)、通道、I/O处理机管理等几种方式。CPU寻址外设有两种方式,一种是存储器对应输入/输出方式,另一种是端口寻址方式。其中,存储器对应输入/输出方式把一个外设作为一个存储单元对待,一次输入/输出操作就相当于一次存储器的读/写操作,这种方式虽然优点不少,但实际应用却不多,因为它本身不直观,容易与正常的存储器读/写操作混淆,同时还需要占用存储器的部分空间并给存储器地址分配带来不便。CPU输入/输出端口寻址方式设有专门的输入/输出指令,并要求为外设接口分配端口地址。这种端口寻址方式为一个端口一个地址,使用专门的输入/输出指令,使用方便,不易出错,清楚直观。需要注意的是,端口寻址可以为直接方式寻址或间接方式寻址。直接方式可以寻址0~255个端口地址。间接方式通过DX寄存器给出端口地址,可寻址64K个端口地址。1.数据信息数据通常为8位或16位,可分为3种基本类型:数字量、模拟量和开关量。一般地,由键盘、光电输入机等提供的二进制形式的信息为数字量数据。电机的启停、开关的开合等可用两个状态表示的量,即用一位二进制数表示,这样的量称为开关量;由传感器等提供的信号往往是模拟量,它需先经模/数(A/D)转换后再输入到计算机中。例如,温度、电压等信号。CPU与外设进行数据传送的方式有串行传送(一位一位传送)和并行传送(n位同时传送)两种方式,但都要经过I/O指令实现。串行方式比较经济,但速度受限,而并行方式则速度较快,成本较高。

2.状态信息在输入时,有表示输入装置是否已准备好的信息(READY);在输出时,有表示输出装置是否忙的信息(BUSY)等。

3.控制信息控制信息有控制输入/输出装置的启停信号,工作方式、工作规约及格式选择信息等。值得指出的是,控制信息和状态信息与数据是不同性质的,必须要分别传送。但它们都通过IN和OUT指令在数据总线上进行传送,所以通常采用分配不同端口的方法将它们加以区别。10.2中断处理程序设计10.2.1中断处理程序的编写中断是指执行当前程序的过程中,由于某种随机出现的外设请求,使CPU暂停(即中断)正在执行的程序而转去执行为外设服务的程序;当服务完毕后,CPU再退回到暂停处(即断点)继续执行原来的程序。现在,中断的概念除了传统的外部事件(硬件)引起的中断外,又产生了内部软件中断的概念。在80386/80486中则把许多执行指令过程中产生错误的情况也纳入了中断处理的范围,并将它们和通常意义上的内部软件中断一起统称为异常中断,简称异常(Exceptions),而将通常意义上的外部中断简称为中断。中断和异常之间的区别在于,中断用来处理CPU外部的异步事件,而异常是用来处理在执行指令期间由CPU本身对检测出的某些条件作出响应的同步事件。用产生异常的程序和数据再次执行时,该异常总是可再现的,而中断通常与现行执行程序无关。但中断和异常在使处理器暂停执行其现行程序,以执行更高优先级程序方面是一样的。引起中断的原因或发出中断请求的来源,称为中断源。可以根据重要性的不同为各中断源安排不同的优先级,CPU首先响应优先权高的中断。8086具备一个简单而灵活的中断系统,它能处理256种类型的中断,中断类型由类型号0~255指定,中断源的情况可见图10-1。80286以后使用两片8259A级连结构,管理15级中断。图10-18086的中断源

1.外部中断8086有两条外部中断请求线NMI和INTR。NMI为非屏蔽中断,INTR为可屏蔽中断。NMI用于重要的中断源,如电源掉电等,它的类型号是2。CPU不禁止NMI线上的中断请求,但可由指令STI(中断允许标志置“1”)和CLI(中断允许标志置“0”)允许和禁止INTR线上的中断请求,即CPU可用STI和CLI指令开、关中断,当关中断时,CPU将不响应INTR线上的中断请求。

2.内部中断1)除法指令在执行除法指令时,若发现除数为0或商超过了寄存器所能表达的范围,则立即产生一个类型0的内部中断。2)溢出中断指令INTO

若上一条指令使溢出标志OF置1,那么当执行溢出中断指令INTO时,立即产生一个类型4的中断;若标志OF为0,则此指令不起作用。3)INTn指令

CPU执行完INTn指令时立即产生一个中断,所以又称它为“软件中断”。中断的类型由指令中的n指明。因为INT指令中可以指定任何的类型号,故此指令可方便地用来调试为外设编写好的中断服务程序。4)单步中断若单步标志IF为1,则在每条指令执行后,CPU自动产生一个类型1的中断(单步中断),使程序单步执行,它提供给用户强有力的调试手段。8086规定这些中断的优先权从高到低的顺序是:●除法错误、INTO、INTn;●NMI;●INTR;●单步中断。3.中断矢量表中断矢量表占用内存中00000H到003FFH的1KB空间。表中内容分为256项,对应于类型号0~255,每一项占用4个字节,用来存放相应类型的中断服务程序的入口地址,高两字节存放入口地址的段地址部分,低两字节存放段内偏移地址部分,如图10-2所示。对于任一指定类型的中断,CPU只要将其类型号乘4就可以得到其中断矢量(即此类中断在中断矢量表中占用的4个字节的最低字节的地址),然后取出它所占有的4个字节的内容分别送到IP和CS,就实现了中断服务程序的调用,所以中断矢量表是中断类型号与其对应的中断服务程序之间的连接链。图10-2中断矢量表采用中断矢量表的方法,CPU可以直接通过中断矢量转向相应的处理程序,而不必逐个检查和确定中断源,因而加快了中断处理的速度。80386到PentiumCPU使用中断描述表IDT来管理各种中断。当系统工作于实模式时,IDT变为8086中的中断矢量表。10.2.2中断矢量的获取1.中断类型号的获取方法(1)除法错误、单步中断、非屏蔽中断NMI、断点中断和溢出中断分别自动提供类型号0~5。(2)对于外部中断INTR,可以有两种方法提供中断类型号。方法1:自己设计接口电路,利用寄存器/缓冲器或利用8212芯片这样的组件存放中断类型号。CPU响应中断后,接口电路将此类型号送入数据总线,CPU读数据总线从而获得中断类型号。图10-3给出了实现这一功能的接口电路的方框图。某一外设的中断类型号可事先由输出指令送入它的中断类型号寄存器/缓冲器或预先将组件(如8212芯片)的引线接好。当外部设备已准备好数据可以向CPU输送,或外设已准备好可以接收来自CPU的信号时,状态信号线上发一脉冲信号,经中断请求触发器向CPU的INTR线发出中断请求,CPU响应中断后,进入中断响应周期,发INTA信号,此信号将已预先装入的或由硬件芯片提供的中断矢量号送入数据总线,CPU即可读得。在中断服务程序中可以安排与此外设的数据交换。可通过将图10-3中的中断屏蔽触发器设置为1或为0来控制是否让外设发中断请求。图10-3中断方式接口电路方框图

例10-1已为某一外设指定中断类型号为6,编写此外设中断服务程序。程序描述如下:

CODESEGMENTMAIN: ;主程序

HLTINTR6PROCNEAR ;中断类型号为6的中断服务程序

STIIRETINTR6ENDP

CODENED…做了以上安排后,应在主程序的初始化部分将此中断服务程序的入口地址送入中断矢量表内对应中断类型6的4个单元中。完成这个功能的程序段描述如下:

MOV AX,0MOV ES,AXMOV DI,06H*4MOV AX,OFFSETINTR6CLDSTOSWMOV AX,CSSTOSW在所有中断服务程序的结尾处,应安排开中断指令STI和从中断返回的指令IRET。

另一种方法:利用Intel8259A芯片。Intel8259A是可编程的中断控制器,如图10-1所示,它可以接收来自外设的8个各自独立的中断请求信号,分别为IRQ0~IRQ7。8259A将它们按优先权的高低进行排队。IRQ0优先权最高,依次降低,IRQ7为最低。当某一时刻出现两个或两个以上的中断请求信号时,8259A首先响应优先权高者。将中断信号送到CPU的INTR线上,进而又将对应于该中断源的惟一的中断类型号送给CPU。CPU获得此中断类型号,就自动转入对应的中断服务程序。表10-28259A的中断源表10-28259A的中断源8259A输入

中断类型号

IRQ008H定时器(通道0)

IRQ109H键盘

IRQ20AH彩色图像接口

IRQ30BH未用

IRQ40CH串行(RS-232)接口

IRQ50DH未用

IRQ60EH软盘

IRQ70FH打印机8259A中有一个中断屏蔽寄存器(IMR),它的I/O端口地址是21H。它的位0~7对应于IRQ0~IRQ7,可以通过设置这个寄存器的任一位为0或1去控制任一中断源的中断允许或禁止。某位为0表示允许该中断源发出的中断请求信号经8259A产生一个要发给CPU的中断,为1则禁止该中断源。例如,只允许键盘中断,则可设置如下中断屏蔽字:

MOVAL,0FDHOUT21H,AL使用8259A时,应在主程序开始处按上述原则初始化中断屏蔽寄存器。在中断服务程序的结束处应发出“中断结束”(EOI)命令(20H)给8259A的中断命令寄存器(I/O端口地址20H),具体程序如下:

MOVAL,20HOUT20H,AL

2.中断过程在调用相应的中断服务程序前,CPU先将机器状态用标志位入栈的方法保存起来。接着CPU清除标志位IF和TF,屏蔽新的中断请求和单步中断。然后,CPU把当前的代码段寄存器的内容入栈保护,从矢量表(高两个字节)中取出新的代码段寄存器值送至CS;接着CPU把当前的指令指针值入栈,再从矢量表中取出新的IP值,送至IP中。于是程序就转到了中断服务程序。中断服务程序可按各个设备的要求来加以编制,但通常有保护现场(入栈)指令,在返回前要恢复现场(退栈)指令,最后要用中断返回指令IRET,恢复断点处的CS值和IP值,并保存CPU的状态。在中断发生时,CPU自动清除了IF和TF,其目的是使CPU转入中断处理程序后,不允许再产生新的中断。如果在执行中断处理程序中,还允许外部中断,可以通过STI指令再把IP置1。编写中断处理程序和编写子程序一样,所使用的汇编语言指令没有特殊限制,只是中断处理程序返回时使用IRET指令。这条指令的工作步骤和中断发生的工作步骤正好相反。它首先把IP、CS和EFLAGS的内容弹栈,然后返回中断发生时紧接着的下一条指令,CPU接着执行原来的程序。在中断发生时,下述操作是由硬件自动完成的:(1)取中断类型号n;(2)标志寄存器(EFLAGS)内容入栈;(3)当前代码段寄存器(CS)内容入栈;(4)当前指令指针(IP)内容入栈;(5)禁止外部中断和单步中断(置IF=0,TF=0);(6)从中断矢量表中取4×n地址的内容送IP,取4×n+2地址中内容送CS;(7)转中断处理程序。10.2.3中断程序设计举例1.中断和中断返回指令INT/INTO/IRET

指令格式:INTimm8

INTO

IRETINTimm8为软中断指令,用于产生一个由8位立即数指定中断号的软中断。该指令首先将标志寄存器和断点地址(CS和IP的值)入栈,并将标志位TF和IF清0(关单步和可屏蔽中断),然后转向指定中断号对应的中断服务程序。中断服务程序的入口地址是以中断号作为索引,查中断矢量表或中断描述符表得到的。

INTO为溢出中断指令。它实际上是软中断指令INT的特例,其中断号隐含为1,所以INTO=INT4。它只有当OF置1时才产生中断。

IRET为中断返回指令,用于从中断服务程序返回原程序。它执行的操作是从堆栈中弹出原入栈保护的IP、CS和标志寄存器值,并重新开始被中断程序的执行。

2.中断处理程序的编写前面已提及,当一个可屏蔽中断被响应后,CPU进入中断响应周期。此时被响应的外设应将本身的中断类型号送往数据总线。CPU读取这个类型号,将其乘4,就得到中断矢量表中相应的中断矢量入口,并转入中断处理程序。具体的工作由中断处理程序完成,外中断和软中断程序设计不尽相同。1)外中断处理程序外设中断是随机发生的,在中断处理程序设计时必须考虑这一点。外中断处理程序的主要步骤如下:(1)保护现场,主要指各通用寄存器的内容和除CS外代码段寄存器的内容,保护方法一般是入栈;(2)尽快完成中断处理,以免影响其他外设的中断请求;(3)恢复现场;(4)中断返回,用IRET指令返回。2)软中断处理程序由中断指令引起的软中断尽管是不可屏蔽的,但只有在CPU执行中断指令后才会发生。中断指令类似于子程序调用指令,相应的软中断处理程序在很大程度上类似于子程序。(1)栈切换。由于软中断处理程序往往在开中断状态下执行,占用栈空间量大,栈的切换不可避免,同时,为实现中断的嵌套,也需要栈的切换。(2)开中断。只有在开中断后,CPU才响应可屏蔽的外设请求,外设的中断请求才能及时得到处理。如果此软件中断处理程序要被外设中断处理程序“调用”,则是否要开中断或何时开中断,应根据实际情况,再作考虑。(3)保护现场。应保护中断处理程序中要使用的寄存器,而这些寄存器在进入中断处理程序前,可能已被其他程序所使用。这样在使用软中断指令时,可不必考虑有关寄存器内容的保护问题。(4)中断处理。(5)恢复现场。依次恢复被保护寄存器的原有内容。(6)再次实施栈切换。如果在开始时切换了栈,那么也要再重新切换回原栈。(7)利用IRET指令实现中断返回。

例10-2当需要改变某个中断矢量的内容时,必须要先将原中断矢量的入口地址保护起来,以便用完之后恢复。使用DOS的35号系统功能调用,读取指定中断矢量(由AL寄存器给出)的入口地址到寄存器对ES和BX中,ES寄存器用于存放段基址,BX寄存器存放偏移量。这就是取中断矢量所要实现的功能。实现取中断矢量功能的程序描述如下:

CSEGSEGMENTPARAPUBLIC'CODE'

ASSUMECS∶CSEGGETINTV PROCFAR PUSHAXMOV AH,35H;调用DOS功能35HINT 21HPOP AXRETGETINTV ENDPCSEG ENDS

END例10-3当用户需要建立一个指定的中断矢量,使其指向用户定义的中断处理程序时,可以使用DOS的37号系统功能调用,将用户定义的中断处理程序的入口地址DS∶DX送入由AL寄存器指定中断号的矢量地址中。现要求编程实现置中断矢量(60H号)指向中断处理程序MYINT的功能。此类问题求解的一般方法是:改变中断矢量之前,必须将原中断矢量的入口地址读出,并保存到存储器中,以便自定义的中断程序处理完后进行恢复。下述程序中,GETINTV子程序完成的就是将原中断矢量的入口地址读出的任务。程序描述如下:

EXTRNGETINTV:FAR,SETINTV:FARPUBLICOLDSEG,OLDOFFDATASEGMENTPARAPUBLIC'DATA'OLDSEG DW? ;保存段址

OLDOFF DW? ;保存偏移量

DATA ENDSCSEG SEGMENTPARAPUBLIC'CODE'

ASSUME CS:CSEG,DS:DATASTARTPROC FAR PUSH ES

;保护ES MOV AL,60H;取60H号中断矢量

CALL GETINTV MOV OLDSEG,ES;并保存到存储器中

MOV OLDOFF,BX POP ES;恢复ES PUSH DS PUSH CS POP DS

;使DS指向代码段

LEA DX,MYINT;使DS∶DX指向MYINT CALL SETINTV;改变中断矢量

POP DS RETSTART ENDPCSEG

ENDS ENDMYINT PROCNEAR ;中断处理程序

IRETMYINT ENDP

…值得说明的是,执行上述程序段后,将60H号中断矢量的内容变为MYINT。一般情况下,在处理完MYINT之后,需恢复60H号中断矢量的原有内容,可执行下述程序段:

EXTRNOLDSEG:WORD,OLDOFF:WORDEXTRNSETINTV:FARPUSHDS

;保护程序的DSMOVDS,OLDSEG ;DS∶DX为原先中断矢量

MOVDX,OLDOFFCALLSETINTV ;改变中断矢量

POP DSCSEGSEGMENTPARAPUBLIC'CODE'

ASSUME CS∶CSEGSETINTVROC FAR

PUSH AX

MOV AH,25H ;调用DOS功能25H

INT 21H

POP AX

RETSETINTVENDPCSEGENDSEND

例10-4编一段中断处理程序,在主程序运行的过程中,每隔10秒钟响铃一次,同时在屏幕上显示“Thebellisring!”

问题分析:在系统定时器(中断类型为8)的中断处理程序中,有一条中断指令INT1CH,时钟中断每发生一次(约每秒中断18.2次),都要调用一次中断类型1CH的处理程序。使用1CH中断类型时,应注意:(1)在ROMBIOS中,1CH的处理程序只有一条IRET指令,实际上它并没有做任何工作,只是为用户提供了一个中断类型号。如果用户有某种周期性的工作需要完成,就可以利用系统定时器的中断间隔,用自己设计的处理程序来代替原有的1CH程序。(2)1CH是用户的中断类型,可能已被其他功能的程序所引用,所以在编写新的中断程序时,应做下述工作:①在主程序的初始化部分,先保存当前中断矢量表的内容,再置新的中断矢量;②在主程序的结束部分恢复保存的1CH矢量。程序描述如下:

DATASEGMENTCOUNTDW1MESSDB'Thebellisring!',0DH,0AH,'$'DATADNDSCODESEGMENT

ASSUMECS∶CODE,DS∶DATA,ES∶DATAMAIN PROC FARSTART: PUSH DS

SUB AX,AX PUSHAXMOV AX,DATAMOVDS,AX MOVAL,1CH ;取原中断矢量

MOVAH,35HINT 21H PUSHES ;存原中断矢量段址

PUSHBX ;存原中断矢量偏移量

PUSHDSMOVDX,OFFSETRING ;新偏移量送DX MOVAX,SEGRING

MOVDS,AX

;新段址送DS MOV AL,1CH MOVAH,25H INT 21H ;写入新的中断矢量

POP DS IN AL,21H ;读取中断屏蔽字

AND AL,11111110B ;允许定时器中断

OUT 21H,ALSTI ;开中断

MOVDI,2000

DELAY: MOVSI,3000 ;延时

DELAY1: DEC SI JNZ DELAY1 DEC DI JNZ DELAY POP DX ;恢复原中断矢量

POP DS MOV AL,1CH MOV AH,25H INT 21H RET

MAIN ENDPRING PROC NEAR PUSH DS ;各工作寄存器内容入栈

PUSH AX PUSH CX PUSH DX MOV AX,DATA MOV DS,AX STI DEC COUNT;计秒值

JNZ EXIT MOV DX,OFFSETMESS MOV AH,09H

INT 21H MOV DX,100 IN AL,61H AND AL,0FCHSOUND: XOR AL,02 OUT 61H,AL ;扬声器发声

MOV CX,140HWAIT1: LOOP WAIT1 ;延时等待

DEC DX JNE SOUND MOV COUNT,182EXIT: CLI ;关中断

POP DX POP CX POP AX POP DS IRET ;中断返回

RING ENDPCODE ENDS ENDSTART10.3DOS功能调用10.3.1概述为便于编程,DOS系统把涉及设备驱动和文件管理等方面的子程序编写成相对独立的程序模块并编号,通过功能调用的方法来使用这些子程序,满足用户对设备驱动、文件管理等的需要。减少对系统硬件环境的考虑和依赖,能使应用程序的编制变得简单且有较好的通用性。DOS系统中,已编号的、可由程序员调用的子程序称为DOS的功能调用或系统调用。通常,DOS的各种命令是操作员与DOS的接口,而功能调用则是程序员与DOS的接口。DOS功能调用主要包括3方面的子程序:(1)设备驱动(基本I/O);(2)文件管理;(3)内存管理、存取时间、存取终端矢量、终止程序等。10.3.2基本I/O功能调用1.调用方法为了使用方便,DOS已将所有子程序按功能顺序编了号,调用时只要按如下方法使用就可以了。(1)将要调用功能的功能号送入AH寄存器;(2)根据所调用功能的规定设置入口参数;(3)用INT21H指令转入子程序入口;(4)调用结束后,按规定取得出口参数。需要指出的是,有的子程序不要入口参数,但大部分需要将参数送入指定地点。编程时,只须给出这三个方面的信息,而不必关心具体程序如何,在内存中的存放地址如何。DOS根据所给的信息,自动转入相应的子程序去执行。输出的结果一般是在调用结束后通过出口参数送出,出口参数一般是寄存器。有些子程序,如屏幕显示字符子程序,调用结束后会在屏幕上显示结果。例10-5

MOV DL,':'MOV AH,2INT 21H

这是2号功能调用(编号为2),实现将字符送入屏幕(或打印机)显示的功能。它要求将要显示的字符的ASCII码值送入DL,调用结束,屏幕上显示DL中的内容“:”。

2.基本I/O功能调用1)键盘输入(1号调用)1号系统功能调用等待从标准输入设备输入一个字符并送入寄存器AL,不需入口参数。例10-6

MOVAH,1INT21H

执行上述指令,系统将扫描键盘,等待有键按下,一旦有键按下,就将键值(相应字符的ASCII码值)读入,先检查是否是Ctrl-Break,若是,则退出命令执行;否则将键值送入AL寄存器,同时将这个字符显示在屏幕上。2)控制台输入但无显示(8号调用)8号调用与1号调用类同,只是不在屏幕上显示输入的字符。3)打印输出(5号调用)把DL中的字符输出到打印机上。例10-7

MOVDL,'A'MOVAH,5INT21H4)直接控制台输入/输出(6号调用)6号调用可从标准输入设备输入字符,也可以向屏幕上输出字符,并且不检查Ctrl-Break。若DL=0FFH时,表示从键盘输入。若标志ZF=0,表示AL中为键入的字符值。若标志ZF=1,表示AL中不是键入的字符值,即尚无键按下。若DL≠0FFH时,表示向屏幕输出,DL中为输出字符的ASCII码值。例10-8

MOVDL,0FFHMOVAH,6INT21H;从键盘输入字符

MOVDL,24HMOVAH,6INT21H;将24H对应的字符'$'输出5)直接控制台输入但不显示(7号调用)等待从标准输入设备输入字符,然后将其送入AL,如同6号调用,对字符不做检查。6)输出字符串(9号调用)调用时,要求DS∶DX必须指向内存中一个以“$”作为结束标志的字符串。字符串中每一个字符(不包括结尾标志$)都输出显示或打印。例10-9

DATASEGMENTBUFDB'HOWDOYOUDO?$'

DATAENDSCODESEGMENT

MOVAX,DATAMOVDS,AX

MOVDX,OFFSETBUFMOVAH,9INT21H

CODEENDS执行本程序,屏幕将显示:HOWDOYOUDO?…………7)字符串输入(0AH号调用)从键盘接收字符串到内存输入缓冲区。要求事先定义一个输入缓冲区,缓冲区内第一个字节指出缓冲区能容纳的字符个数,不能为零。第二个字节保留以用作填写输入的字符个数。从第三个字节开始存放从键盘接收的字符。若实际输入的字符数少于定义的字节数,缓冲区内其余字节填零;若多于定义的字节数,则后来输入的字符丢掉,且响铃。调用时,要求DS:DX指向输入缓冲区。例10-10

DATA SEGMENTBUF DB50 ;缓冲区长度

DB? ;保留为填入实际输入的字符个数

DB50 DUP(?) ;定义50个字节存储空间

DATA ENDSCODEE SEGMENT

MOV AX,DATAMOV DS,AX

MOV DX,OFFSETBUFMOV AH,10INT 21HCODE ENDS………8)异步通信口输入(03H)

从标准异步通信接口等待输入一个字符,然后送到寄存器AL中。启动时DOS把一个异步通信端口初始化为2400波特,没有奇偶校验位,一个停止位,字长为8位。9)异步通信口输出(04H)

在DL中的数据被输出到异步通信接口去。关于异步通信口的输入/输出,推荐使用ROMBIOS中断调用14H。10)日期设置(28H调用)调用时,CX:DX中必须有一个有效的日期,CX中存放年号(1900~2099),DH中存放月号(1~12),DL中存放日号。若日期有效,设置成功,AL=0;否则AL=0FFH。

例10-11将日期设置为2003年3月15日,程序段描述如下:

MOVCX,2003MOVDH,3MOVDL,15MOVAH,2BHINT21H11)取得日期(2AH)

调用后返回日期在CX∶DX中。CX中放年号,为二进制数,DH中放月号,DL中放日号。如果日时钟转到下一天,日期将自动调整,也考虑每月的天数和闰年。不需要入口参数。12)设置时间(2DH)

时间的格式是四个8位二进制数,具体地说:CH表示小时(0~23),CL表示分(0~59),DH表示秒(0~59),DL表示百分之一秒(0~99),这个格式可转化为打印/显示形式。也可用来计算,比如从一个时间值中减去另一个时间值。调用时,要求CX∶DX中存放要求的时间。若此时间是有效的,设置成功,AL返回0,若时间的组成部分无效,设置操作取消,AL返回0FFH。13)取得时间(2CH)

时间的格式如同2DH功能调用,不需要入口参数,调用结束时,CX∶DX中为返回的时间。例10-12执行下述程序段:

MOVAH,2DHMOVCX,5FHMOVDX,900HINT21H将把系统时间设置为5点15分9秒。执行下述程序段:

MOVAH,2CHINT21H将在CX∶DX中得到时间的二进制值。10.3.3应用举例例10-13将内存中BUF单元开始的一个字符串(长度为10个字节)送CRT显示,并回车换行。将一个字符串送CRT显示,使用DOS的9号系统功能调用最为方便。9号系统功能调用要求两个入口参数,一是要求DX中为字符串首字符的偏移地址,二是要求字符串必须以“$”字符结尾,回车符、换行符的ASCII码分别是0DH和0AH。编程如下:

DATA SEGMENTBUF DB'Thisismyfirstprogram!'DATA ENDSCSEG SEGMENT'CODE'

ASSUMECS∶CSEG,DS∶DATASTART: MOV AX,DATA MOV DS,AX LEA BX,BUF MOV AX,0D0AH;回车换行符的ASCII码送AX

MOV [BX+10],AX ;字符串后加换行、回车符

MOV BYTEPTR[BX+12],'$';串尾加结尾符

MOV DX,BX ;字符串首地址送DX CALL LIST_1 ;显示字符串

MOV AH,4CH INT 21H ;返回DOSCSEG ENDS END STARTCODESEGMENT

ASSUMECS∶CODELIST_1 PROC FAR

PUSH AX ;保护AX MOV AH,09H

INT 21H ;调用9号功能

POP AX ;取回AX RET ;返回LIST_1 ENDPCODE ENDS

例10-14利用DOS功能调用,模拟实现登录网络时口令的输入。接收用户的保密口令或其他特殊信息意味着从标准输入设备上读一个字符串,但不在输出设备上显示。具体实现方法是,从键盘输入最多8个字符的口令(不显示),送入存储器中,并将口令串的开始地址送BX保存,然后返回。利用DOS的8号系统功能调用可实现读一个字符不回显的功能。该功能调用从标准输入设备上接收一个ASCII字符,并送AL寄存器。程序描述如下:

DATASEGMENTPARAPUBLIC'DATA'PROMPTDB'P1easeenteryourPassword:$'BUFFERDB8DUP(?)

;存放口令

DATAENDSCSEGSEGMENTPARAPUBLIC'CODE'

ASSUMECS:CSEG,DS:DATAPASSWORDPROCFARSTART:

PUSHDX

;保存寄存器

PUSHCX

PUSHAX

LEADX,PROMPT ;给出提示

CALL LIST_1

MOV CX,8 ;输入8个字符

LEA BX,BUFFER ;口令字符串存放处NEXTKEY:CALL GETCHR ;读入下一键

CMP AL,0DH ;是回车?

JE LEAVE ;是的,转LEAVEMOV [BX],AL ;不是,存字符

INC BX ;并指向下一位置

LOOP NEXTKEY ;取另一键

LEAVE:LEA BX,BUFFER ;口令串地址送BX

POP AX ;恢复寄存器

POP CXPOP DX

RET ;返回调用程序

PASSWORDENDPCSEGENDSENDSTART

PUBLICGETCHRCSEGSEGMENTPARAPUBLIC'CODE'ASSUMECS:CSEGGETCHRPROC FARPUSH CXMOV CH,AHMOV AH,8HINT 21HMOV AH,CHPOP CXRETGETCHRENDPCSEGENDS如果输入“Ctrl-C”字符,DOS则产生23H号中断。为避免产生这种情况,用户可用7号系统功能调用替换8号系统功能调用,即把子程序中的指令MOVAH,08H改成MOVAH,07H。另外,子程序需等待键盘上有键输入后才返回调用程序,而很多情况下需要当键盘上有键输入时就读入,否则返回调用程序,即并不等待键盘输入。为此,该子程序就需将INT21H指令前的MOVAH,08H修改成下列形式:

MOVAH,06HMOVDL,0FFH子程序LIST_1为例10-13中的子程序LIST_1。

例10-15

编程清除屏幕并使光标回到左上角的位置。要解决以上的问题,首先使用软中断INT10H的15号子功能读取屏幕的现行状态,再使用0号子功能以同样的模式设置显示方式。这样不仅完成了清屏功能,而且不改变屏幕的显示模式。程序描述如下:CSEG SEGMENTPARAPUBLIC'CODE' ASSUMECS∶CSEGCLEARS PROC FARSTART: PUSH AX PUSH BX MOV AH,15 INT 10H MOV AH,0 INT 10H POP BX POP AX RETCLEARS ENDPCSEG ENDS ENDSTART10.4BIOS中断调用10.4.1BIOS概述

BIOS(BasicInput/OutputSystem)是驻留在ROM中的程序,提供了系统加电自检,引导装入以及对主要I/O接口的控制等功能。对I/O接口的控制主要是对键盘、磁带、磁盘、显示器、打印机、异步串行通信接口等的控制,提供了最基本的系统硬件与软件间的接口。BIOS在汇编语言一级上向用户或操作系统提供微机所带的一些主要外设的设备控制功能,包括开机自检,显示器、键盘和打印机的字符传送,图形发生等,主要是I/O设备的处理程序和许多常用例行程序,以中断处理程序的形式存在。这些操作均不需要用户考虑外设的I/O地址等细节。例如,负责显示输出的显示I/O中断为10H号中断,负责打印输出的打印I/O程序为17H中断等等。在BIOS功能调用中,应重点掌握10H、16H、17H和1AH四种类型的功能调用。主要的BIOS中断类型有以下5种。1)CPU中断类型0除法错;1单步;2非屏蔽中断;3断点;4溢出;5打印屏幕;6保留;7保留。2)8259中断类型88254系统定时器;9键盘;A保留;B保留(通信);

C保留(通信);D保留(打印机);E软盘;F打印机。3)BIOS中断类型10显示器;11设备检验;12内存大小;13磁盘;14通信;15I/O系统扩充;16键盘;17打印机;18驻留BASIC;19引导;1A时钟;40软盘。4)用户应用程序1B键盘Break;1C定时器;4A报警。5)数据表指针1D显示器参量;1E软盘参量;1F图形字符扩充;411#硬盘参量;462#硬盘参量。10.4.2BIOS中断调用方法用户在自己编制的程序中,可以调用BIOS提供的这些设备驱动子程序,就像调用用户自己编的子程序一样。调用BIOS各子程序的方法是利用中断指令INT,先按调用类型要求设置入口参数,再通过带有类型号的软中断指令进行功能调用。CPU响应中断后就把控制权交给所调用的BIOS的子程序,由它提供中断服务。BIOS调用的基本步骤是:(1)置入口参数;(2)使用中断语句INTn,其中n为中断号。例10-16MOVAH,0 ;功能号为0

INT1AH ;1AH为BIOS中断号,功能为读时间计数器的值10.4.3BIOS中断调用与DOS功能调用的比较

BIOS中断程序处于DOS功能调用和硬件环境之间,和DOS功能调用相比其优点是效率高,缺点是编程相对复杂;和直接对硬件编程相比,优点是实现相对容易,缺点是效率相对较低。在一些情况下既能选择DOS中断也能选择BIOS中断来执行同样的功能。例如,打印机输出一个字符的功能,可用DOS中断21H的功能5,也可用BIOS中断17H的功能0。因为BIOS比DOS更靠近硬件。一般情况下,尽可能地使用DOS功能,但在少数情况下必须使用BIOS功能。例如,BIOS中断17H的功能2为读打印机状态,DOS就没有等效的功能。因此,对BIOS和DOS调用的选择原则是,无法使用DOS功能调用或DOS没有提供而BIOS提供了功能的情况下可以考虑使用BIOS中断。例10-17根据显示输出不同的内容,对显示器的使用通常需要变换显示模式。这时,可使用BIOS所提供的视频显示I/O驱动程序来设置屏幕的显示模式。屏幕显示方式的设置使用软中断INT10H功能来实现,若需设置屏幕显示模式为黑白字符方式,应使用INT10H的0号子功能。0——40×25 黑白字符方式1——40×25 彩色字符方式2——80×25 黑白字符方式3——80×25 彩色字符方式4——320×200 彩色图形方式(4种颜色)5——320×200 黑白图形方式6——640×200 黑白图形方式7——720×350 单色字符方式(与单色适配器兼容)8~0CH——保留0DH——320×200 彩色图形方式(16种颜色)0EH——640×200 彩色图形方式(16种颜色)0FH——640×350 单色图形方式10H——640×350 彩色图形方式(EGA卡)。显存为64KB时4种颜色; 显存大于64KB时16种颜色11H——640×480 单色图形方式(仅VGA)12H——640×480 16色图形方式(仅VGA)13H——320×200 256色图形方式(仅VGA)输入参数:AH中为显示方式码,编制的程序描述如下:

CSEG SEGMENTPARAPUBLIC'CODE' ASSUME CS∶CSEGSETSMODE PROC FAR

START: PUSH AX MOV AH,0 INT 10H POP AX RETSETSMODE ENDPCSEG ENDSEND START10.5输入/输出程序设计10.5.1程序直接控制方式1.直接输入/输出方式直接输入/输出方式,也称无条件传送方式或称同步方式。这种传送方式使用较少,只有在外部控制过程的各个动作时间是固定的,且是已知的条件下才能够应用。它不考虑外设的状态,输入时,就只给出IN指令。输出时,也只给出OUT指令,这种传送方式的优点是程序编写容易,硬件电路简单,调试方便。例10-18一个无条件传送的例子如图10-4所示。图中10H、11H、20H是来自地址总线的端口地址信号。要求编程完成采集不同的模拟量。图10-4无条件传送举例这是一个同步的数据采集系统。被采样的数据是八个模拟量,由继电器绕组P0、P1、P2、…、P7控制触点K0、K1、K2、…、K7逐个接通,用一个四位(十进制数)数字电压表测量,把被采样的模拟量转换成十六位BCD代码,高八位和低八位通过两个不同的端口输入。它们的地址分别为10H和11H。CPU通过端口20H输出控制信号,以控制继电器的吸合,从而实现采集不同的模拟量。数据采集过程可用下列程序实现:START:MOVDX,0100H ;01→DH,设置合第一个继电器代码 ;00→DL,设置断开所有继电器代码

LEA BX,DSIOK ;输入数据缓冲区的地址偏移量→BX

XOR AL ;清AL及进位标志

AGAIN:MOV AL,DIOUT 20H,AL ;断开所有继电器线圈

CALL NEARDELAY1 ;模拟继电器触点的释放时间

MOV AL,DH

OUT 20H,AL ;使P0吸合CALL NEARDELAY2 ;模拟触点闭合及数字电压表的转换时间IN AX,10H ;输入MOV [BX],AXINC BXINC BXRCL DH,1;DH左移一位,为下一个触点闭合作准备JNC AGAIN;8个模拟量未输入完,循环此段程序

2.查询输入/输出方式查询输入/输出方式,也称条件传送方式或称异步方式。当CPU与外部操作同步时,采用无条件传送是很方便的。但如果两者不同步时,就很难确保其正确性。为解决这个问题,可以采用查询输入/输出方式。在传送数据前,先去查询一下外设的状态,当外设准备好以后再进行传送。这样就要求CPU与外设之间的接口部分除了传送数据的端口以外,还必须设置传送状态信号的端口。端口数据一般是8位(或16位)的,而状态信息往往是一位的。这样,不同的外设状态信息可以使用同一端口,只要使用不同的位就可以了,查询输入/输出方式解决了高速CPU与慢速外设之间传送数据的问题,并能够保证传送的正确性。综上,可得到查询输入/输出方式的工作过程如下所述。1)查询输入工作过程当输入装置的数据已准备好后应发一个信号给CPU,送出要传送数据的同时给出“准备好”(Ready)信号。数据与状态是由不同的端口输入至CPU数据总线。当CPU要由外设输入信息时,CPU先输入状态信息,检查数据是否已准备好,当数据已经准备好后,才输入数据,读入数据的命令,使状态信息清“0”。读入的数据是8位的;而读入的状态信息往往是一位的(比如用D7位),如图10-5所示。所以,不同外设的状态信息,可以使用同一个端口的不同位。这种查询输入方式的程序流程图如图10-6所示。图10-5查询式输入的数据和状态信息图10-6查询式输入程序流程图工作过程描述如下:①从状态端口读入状态信息;②测试Ready位是否为1,若不为1则转①操作,循环等待;③从数据端口读入数据到AX寄存器。

POLL:IN

AL,STATUS_PORT;从状态端口输入状态信息

TESTAL,80H ;检查READY是否是1

JE

POLL ;未准备好,循环

IN

AL,AATA_PORT;准备好,从数据端口输入数据这种CPU与外设之间状态信息的交换方式,称为应答式,状态信息称为“联络”(Han

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论