第六章 输入输出和WIN32编程.docx
《第六章 输入输出和WIN32编程.docx》由会员分享,可在线阅读,更多相关《第六章 输入输出和WIN32编程.docx(23页珍藏版)》请在冰豆网上搜索。
第六章输入输出和WIN32编程
第六章输入/输出和中断
和WIN32编程
前面已经讲过有关输入/输出的问题,主要是用DOS中断调用INT21H来完成键盘输入以及屏幕显示。
对于计算机来说,仅有这种输入/输出还不够,因为DOS的中断调用无法实现对其它外设的控制。
关于如何用汇编程序实现主机与外设之间的信息交换,将是本章的主要内容。
包括:
输入输出指令的使用格式及功能;
主机与外部设备之间传送数据的方式;
中断的概念及中断处理程序设计;
WIN32程序设计基本方法与技术。
I/O设备与数据传送方式
主机与外设之间数据的传送方式
计算机与外设之间传送数据有如下4中方式:
1.无条件传送方式:
适合于CPU与外设同步的情况。
直接传送,高速外设与主机之间数据传送。
2.查询传送方式:
适合于低速外设与主机之间数据传送。
3.中断传送方式:
适合于低速外设与主机之间数据传送。
4.直接存贮器(又称DMA)传送方式:
适合于高速外存与主机的数据传送。
其中:
无条件传送和查询传送,直接在端口上利用IN和OUT指令传送数据。
中断传送:
在DOS及BIOS层上通过系统功能调用的中断指令实现。
直接存贮方式:
在端口上,采用通道技术实现。
在计算机准备好接收,外设准备好传送数据时,外设向CPU发一个请求DMA传送信号,此时CPU让出总线控制权,使外设与主存在短时间内成批传送数据。
外设与主机传送的接口与信息
1.端口与接口
计算机的外设都是通过接口连接到系统上,每个接口由一组寄存器组成,寄存器都有一个称为I/O端口的地址编码。
也就是,每一台外设都通过硬件接口与主机端口相连,并交换信息。
接口的组成:
设备状态寄存器、设备控制寄存器、数据寄存器。
上述寄存器在I/O空间中都有固定编码。
I/O端口的地址空间:
允许设置64K个8位端口或32K个16位端口。
对I/O空间的访问用IN或OUT两个指令。
I/O端口地址分配,可以查手册。
如:
40H~43H时钟/定时器,60H~63H为8255通讯芯片的接口。
2.外设与主机的信息交换
传送的信息分为三类:
1控制信息:
CPU把控制信息从端口输出到对应外设接口的控制寄存器中,告诉外设应做什么。
2状态信息:
把外设的状态寄存器中的内容送到对应的端口中,以便CPU了解外设状态。
3数据信息:
需要交换的数据(8位、16位)。
程序直接控制I/O方式
直接I/O方式有两种:
1无条件传送方式:
不查询外设状态寄存器的状态,直接用IN或OUT指令实现CPU与外设信息传送。
该方式的特点是:
CPU与外设必须同步工作。
2查询传送方式:
查询外设状态和控制寄存器中的内容,确定是否传送。
特点:
CPU与外设不同步。
IN和OUT指令
通过前面的学习,我们已经知道,外设与主机传送信息,必须用IN和OUT指令。
1.输入指令IN
功能:
从外设寄存器取信息送入AX或AL。
4种形式:
INAL,PORT功能:
(PORT)→AL
INAX,PORT功能:
(PORT+1,PORT)→AX
INAL,DX功能:
([DX])→AL
INAX,DX功能:
([DX])→AX
由AL或AX决定取几个端口的内容。
2.输出指令OUT
功能:
将AX或AL内容送到外设寄存器中。
4种形式:
OUTPORT,AL功能:
(AL)→PORT
OUTPORT,AX功能:
(AX)→PORT(2个8位口)
OUTDX,AL功能:
(AL)→[DX]
OUTDX,AX功能:
(AX)→[DX]
同样,由AL或AX决定送到几个端口。
如:
INAL,40H
OUT80H,AL
MOVDX,379H
INAL,DX
注意:
端口地址>255,就放到DX中。
程序直接控制传送方式
1.无条件传送方式
特点:
不查询外设状态,直接用IN和OUT指令传送信息。
采用这种方式,必须保证外设与CPU在传送数据的过程中,具有相同速度(同步)。
例:
扬声器发声程序。
已知扬声器的控制寄存器的端口地址为61H,硬件结构如下:
程序通过I/O指令,使设备控制寄存器的b1位为0或1(交替为0或1),与门的输入为0和1交替的电信号,输出为一个脉冲电流,经放大后,送扬声器使之发声。
STACKSEGMENTSTACK
DB200DUP(0)
STACKENDS
CODESEGMENT
ASSUMECS:
CODE,SS:
STACK
BEGIN:
MOVDX,100;开关次数100
INAL,61H
ANDAL,11111100B;最低2位变为0
S1:
XORAL,2;第1次b1为0,第2次b1为1
OUT61H,AL
MOVCX,140H;延时一段时间(声音频率)
WAIT1:
LOOPWAIT1
DECDX
JNES1
MOVAH,4CH
INT21H
CODEENDS
ENDBEGIN
2.查询传送方式
特点:
查询外设状态,条件满足时传送。
适合于低速外设与CPU传送信息。
1输入
输入之前,查询数据是否准备好,若准备好则输入,否则等待。
流程:
例:
串行通讯I/O。
串行通讯端口:
采用8250芯片,数据寄存器端口地址为3F8H,状态寄存器端口地址为3FDH,其中b0位是输入数据数据准备位,b5位是输出数据准备位。
串行口输入程序:
C_INPROCFAR
PUSHDX
MOVDX,3FDH
C1:
INAL,DX;读入状态
TESTAL,01H;测试b0位,b0=1,数据准备好
JZC1
MOVDX,3F8H
INAL,DX;接收一个字符
POPDX
RET
C_INENDP
2输出
输出之前,要查询外设是否“忙”,若“忙”则等待,否则输出数据。
流程:
例:
串行口输出子程序。
C_OUTPROCFAR
PUSHDX
PUSHAX
MOVDX,3FDH
C2:
INAL,DX;读入状态
TESTAL,20H;测试b5位,b5=1,准备好接收
JZC2
POPAX
MOVDX,3F8H
OUTDX,AL;输出一个字符
POPDX
RET
C_OUTENDP
查询方式的缺点:
CPU反复等待状态位,浪费大量CPU资源。
中断传送方式
为了解决查询方式下,CPU等待外设,浪费大量CPU资源的问题,提出了中断传送方式。
引入中断之后,有如下优点:
1提高CPU效率
2可以处理突发事件
3提高了计算机工作的灵活性
在中断方式下,程序设计的主要任务:
设置中断向量、编制中断处理程序。
中断的概念
中断是一种使CPU中止正在执行的程序,而转去处理特殊事件的操作,处理结束之后,又返回到断点处继续往下执行。
中断的处理过程:
①中断请求、②中断响应、③中断处理、④中断返回。
中断系统:
实现中断的软硬件设施。
其中,硬件有:
8259A、中断源、中断请求等。
软件有:
中断向量表、中断处理程序。
中断源(内中断/外中断)
●内中断
来自CPU内部事件:
1程序中使用的INT指令产生的中断;
2CPU的某些错误结果产生的中断(除法、溢出、单步)。
内中断的处理特点:
1中断类型号一般在指令中;
2不受中断允许标志位IF的影响。
●外中断
由外设控制器、协处理器等CPU以外的事件引起的中断,称为外中断。
外中断的处理特点:
1中断类型号由8259A提供,或由自制电路来提供;
2受中断允许标志位IF的影响(IF=1,响应中断)。
8086/8088中断源:
不可屏蔽中断请求由硬件故障引起:
掉电、存贮器错、总线奇偶校验错等。
8086系统中断优先级:
其中,“INTn”可处理256种中断,n的范围:
BIOS中断:
10H~1FH
DOS中断:
20H~3FH
自由中断:
40H~FFH
中断向量表
1.中断向量表的结构
中断向量表就是各种中断类型的处理程序的入口地址表。
内存中从00000H~003FFH用于存放中断向量表。
中断类型:
0~FFH,每个类型的中断占4个字节。
如:
INT4AH
中断向量地址=4AH*4=128H
2.中断类型号的获取
(1)除法错、单步中断、不可屏蔽中断NMI、断点中断、溢出中断(中断号0~4)。
中断类型号由CPU芯片内的部件自动提供。
(2)软中断INTn,执行时从指令流中读出类型号。
(3)外中断
1标准外设,利用8259A提供的类型号;
2非标准外设,自制电路通过接口提供给总线,获得类型号。
3.设置或取出中断向量指令
(1)设置中断向量指令
功能:
把由AL指定的中断类型的中断向量DS:
DX放入中断向量表中。
(AH)=25H
(AL)=中断类型号
DS:
DX=中断向量
INT21H
(2)取出中断向量指令
功能:
把AL中指定的中断类型的中断向量从中断向量表中取出送到ES:
DX中。
(AH)=35H
(AL)=中断类型号
INT21H
4.保护方式下的中断向量表
在保护方式下,中断矢量表称作中断描述符表(IDT),按照统一的描述符风格定义其中的表项;每个表项(称作门描述符)存放中断处理程序的入口地址以及类别、权限等信息,占8个字节,共占用2KB的主存空间。
IDTR决定IDT的起始PA。
软中断及中断的有关指令
1.软中断
形式:
INTn
功能:
1(FLAGS)→↓(SP)同时0→IF、TF
2(CS)→↓(SP)(4*n+2)→CS
3(IP)→↓(SP)(4*n)→IP
2.中断返回
形式:
IRET。
功能:
1↑(SP)→IP
2↑(SP)→CS
3↑(SP)→FLAGS
举例
用空闲的中断类型号45H,做新增的软中断类型号,实现功能:
将AX中的内容以十六进制形式在屏幕上输出。
实现步骤:
(1)按指定功能编制中断处理子程序
(2)在中断向量表中,找出一个空闲的中断号N
(3)将新编制的中断处理子程序的入口地址送入中断向量表4*N~4*N+3这四个字节中
(4)调用“INTN”调用N号中断,执行新增的中断处理子程序
.386
STATCKSEGMENTUSE16STACK
DB200DUP(0)
STACKENDS
DATASEGMENTUSE16
DATAENDS
CODESEGMENTUSE16
ASSUMECS:
CODE,SS:
STACK,DS:
DATA
START:
MOVAX,0
MOVDS,0
CLI
MOVWORDPTRDS:
[45H*4],OFFSETINTR45
MOVWORDPTRDS:
[45H*4+2],CS
STI
MOVAX,DATA
MOVDS,AX
LEASI,BUF
MOVCX,N
L1:
MOVAX,[SI]
INT45H
MOVAH,2
MOVDL,20H
INT21H
ADDSI,2
LOOPL1
MOVAH,4CH
INT21H
INTR45PROCFAR
PUSHA
;16进制输出AX中的内容
POPA
IRET
INTR45ENDP
CODEENDS
ENDSTART
注意:
(1)在中断处理子程序中,必须保护和恢复现场
(2)设置中断向量前CLI,设置中断向量后CLI
(3)利用IRET实现中断返回
WIN32编程
WIN32编程基础
1.段的简化定义
(1)使用简化的段定义后,16位程序结构如下:
.MODELSMALL
.386
.STACK200
.DATA
…
.CODE
START:
MOVAX,@DATA
MOVDS,AX
…
MOVAH,4CH
INT21H
ENDSTART
(2)使用简化的段定义,32位程序结构如下:
.386
.MODELFLATSTDCALL
OPTIONCASEMAP:
NONE
INCLUDEKENEL32.INC
INCLUDEUSER32.INC
INCLUDEGDI32.INC
INCLUDEKERNEL32.LIB
INCLUDEUSER32.LIB
INCLUDEGDI32.LIB
.STACK
.DATA
.CODE
START:
…
INVOKEExitProcess,0
ENDSTART
2.控制伪指令
32位汇编提供了类似高级语言的分支控制伪指令和循环控制伪指令
(1)分支控制伪指令
格式:
.IF条件表达式
语句序列
[.ELSEIF条件表达式
语句序列]
[.ELSE
语句序列]
.ENDIF
功能:
实现条件控制
注意:
条件表达式中的关系操作符包括:
==,!
=,>,>=,<,<=,&&,||,!
(和C语言中的类似)
(2)循环控制伪指令
格式:
.WHILE条件表达式
循环体
.ENDW
格式:
.REPEAT
循环体
.UNTIL条件表达式
功能:
实现循环结构
格式:
.BREAK
功能:
退出当前循环
格式:
.CONTINUE
功能:
终止本次循环,开始下一次循环
3.函数的定义、调用与说明
32位汇编提供了函数的定义、调用与说明伪指令
(1)函数定义伪指令:
格式:
函数名PROC[函数类型][语言类型][USES寄存器表][参数名:
参数类型]
(2)函数调用伪指令:
格式:
INVOKE函数名[,参数]…
例:
RADIX_SPROCNEARSTDCALLUSESEBX,EDX,SI,
lpResult:
WORD,Radix:
DWORD,Num:
DWORD
LOCALCount:
WORD
…
RET
RADIX_SENP
…
INVOKERADIX_S,SI,10,EAX
(3)函数说明伪指令
格式:
函数名PROTO[函数类型][语言类型][USES寄存器表][参数名:
参数类型]
功能:
说明本模块中要调用的函数,类似于EXTRN
外模块中的WIN32函数,例如WIN32APIDLL中的函数,需要用PROTO说明后,才能用INVOKE调用。
WIN32API函数的说明,一般放在.INC头文件中,也可以单个地在主程序中说明。
4.WIN32编程环境、库和头文件
(1)WIN32编程环境
●使用MASM32工具包;
●目录介绍
MASM32\BIN:
可执行目录
MASM32\INCLUDE:
头文件目录
MASM32\LIB:
导入库文件目录
●汇编过程:
生成源程序文件:
A.ASM
生成资源脚本文件:
A.RC
生成目标程序:
“ML/c/coffA.ASM”,得到A.OBJ
生成资源文件:
“RCA.RC”,得到A.RES
生成可执行程序:
“LINK/subsystem:
windowsA.OBJA.RES”,得到A.EXE
(2)库和头文件
WIN32编程不再使用DOS系统功能调用,而使用WIN32API函数。
这些WIN32函数在Windows提供的动态链接库中。
WIN32编程环境提供了:
动态链接库
.DLL
函数实体
相应的导入库
.LIB
link时的接口
函数说明
.INC
函数说明
基本的WIN32函数库包括:
内核函数库
KERNEL32.DLL
KERNEL32.LIB
KERNEL32.INC
处理内存管理和进程调度
用户界面函数库
USER32.DLL
USER32.LIB
USER32.INC
处理窗口、基本用户界面及特性
图形函数库
GDI32.DLL
GDI32.LIB
GDI32.INC
处理画图操作
WINDOW.INC
常用杂项
WIN32程序的结构
Windows是一个多任务的操作系统,允许多个程序同时运行。
其关键是:
应用程序以窗口作输入/输出界面;以消息驱动;程序内部有一个消息循环。
1.无消息循环的WIN32程序
.386
.MODELFLATSTDCALL
OPTIONCASEMAP:
NONE
INCLUDEWINDOWS.INC
INCLUDEKENEL32.INC
INCLUDEUSER32.INC
INCLUDEGDI32.INC
INCLUDEKERNEL32.LIB
INCLUDEUSER32.LIB
INCLUDEGDI32.LIB
.STACK
.DATA
;------------------------------------------------------
Msg1DB‘titletest’,0
Msg2DB‘helloworld!
’,0
;------------------------------------------------------
.CODE
START:
;------------------------------------------------------
INVOKEMessageBoxA,0,ADDRMsg2,ADDRMsg1,MB_OK
;------------------------------------------------------
INVOKEExitProcess,0
ENDSTART
2.有消息循环的WIN32程序
完整的Windows程序依靠消息来驱动。
每个程序中有一个“死循环”——消息循环。
程序不断等待可能输入的消息,然后对消息作判断,然后再做适当的处理。
(1)消息驱动机制
(2)框架
.386
.MODELFLATSTDCALL
OPTIONCASEMAP:
NONE
INCLUDEWINDOWS.INC
INCLUDEKENEL32.INC
INCLUDEUSER32.INC
INCLUDEGDI32.INC
INCLUDEKERNEL32.LIB
INCLUDEUSER32.LIB
INCLUDEGDI32.LIB
.STACK
.DATA
…
.CODE
START:
;------------------------------------------------------
…
invokeWinMain,hInstance,NULL,CommandLine,SW_SHOWDEFAULT
invokeExitProcess,0
;------------------------------------------------------
WinMainPROChInst:
dword,hPrevInst:
dword,CmdLine:
dword,CmdShow:
dword
…
movwc.lpfnWndProc,offsetWndProc
…
invokeRegisterClassEx,addrwc
…
invokeCreateWindowEx,WS_EX_ACCEPTFILES+WS_EX_APPWINDOW,addrszClassName,…
…
StartLoop:
invokeGetMessage,addrmsg,NULL,0,0
cmpeax,0
jeExitLoop
invokeTranslateMessage,addrmsg
invokeDispatchMessage,addrmsg
jmpStartLoop
ExitLoop:
moveax,msg.wParam
ret
WinMainendp
WndProcprochWin:
dword,uMsg:
dword,wParam:
dword,lParam:
dword
.ifuMsg==WM_COMMAND
.ifwParam=1000
invokeFileOpen,addrszOpenFileName
.elseifwParam==1100
invokeMessageBox,hWin,addrTheText,addrszDisplayName,MB_YESNO
…
.endif
moveax,0
ret
WndProcendp
FileOpenproclpszFileName:
dword
…
invokeCreateFile,lpszFileName,…
…
invokeReadFile,hFile,addrBuf,…
ret
FileOpenendp
…
endstart
说明:
(1)GetMessage()从应用程序的消息队列中取一个消息
(2)DispatchMessage()分发消息,触发WndProc()函数
(3)WndProc()是一个回调函数(类似于中断处理子程序),一般不直接调用,而是在分发一个消息后,Windows系统根据分发的消息调用(被OS调用,触发)
(4)WndProc()根据不同的消息,调用不同的处理函数
第四次上机
1.将实验3中的求n个数的平均值、最大值、最小值用软中断实现。
2.将实验3用windows程序实现。
实验报告内容包括:
1.题目
2.源码
3.注释