1第八章输入输出程序设计CPUMEMI/O设备总线I/O接口2查询方式(程序控制方式)中断方式DMA方式(直接存储器存取方式/成组传送方式)1.I/O设备的数据传送方式3I/O指令是主机与外设进行通信的最基本途径。DOS功能调用和BIOS例行程序中的输入/输出功能也是由IN和OUT指令完成的。例:循环测试某状态寄存器的第2位是否为1AGAIN:INAL,STATUS_PORTTESTAL,00000100BJZAGAIN2.程序直接控制I/O方式读I/O状态准备好?传送数据NYINAL,DATA_PORT4I/O指令是主机与外设进行通信的最基本途径。DOS功能调用和BIOS例行程序中的输入/输出功能也是由IN和OUT指令完成的。例:循环测试某状态寄存器的第2位是否为1AGAIN:INAL,STATUS_PORTTESTAL,00000100BJZAGAIN2.程序直接控制I/O方式读I/O状态准备好?传送数据NYMOVAL,DATAOUTDATA_PORT,AL5轮流查询几种I/O设备:DEV1:INAL,STAT1TESTAL,STAT1_BITJZDEV2CALLFARPTRPROC1DEV2:INAL,STAT2TESTAL,STAT2_BITJZDEV3CALLFARPTRPROC2DEV3:INAL,STAT3TESTAL,STAT3_BITJZDEV1CALLFARPTRPROC3优:程序安排或修改设备的优先次序缺:查询等待浪费CPU大量有效时间6设备控制寄存器(61h)1/00控制其它外部设备与门放大器2号定时器门控10例:Sound程序1……movdx,100inal,61handal,11111100bsound:xoral,2out61h,almovcx,140hwait1:loopwait1decdxjnesound……7.modeltiny.code.startupcallspeaker_onmovah,1int21hcallspeaker_off.exit0speaker_onprocpushaxinal,61horal,3out61h,alpopaxretspeaker_onendpspeaker_offprocpushaxinal,61handal,0fchout61h,alpopaxretspeaker_offendpend例:Sound程序28printprocnearpushaxpushdxmovdx,378h;数据寄存器outdx,almovdx,379h;状态寄存器again:inal,dxtestal,80h;(dx)7=busyjeagain;=0,打印机忙movdx,37ah;控制寄存器moval,0dhoutdx,al;送选通信号jmp$+2;展宽选通信号moval,0choutdx,alpopdxpopaxretprintendp例:打印机查询输出子程序00001101选通位自动换行初始化选择位中断位37AH9中断源:引起中断的事件外中断(硬中断):外设的I/O请求——可屏蔽中断电源掉电/奇偶错——非屏蔽中断内中断(软中断):INT指令/CPU错(除法错、溢出)/为调试程序设置的中断3.中断传送方式10非屏蔽中断请求中断逻辑INTnINTO除法错单步n401CPU2NMI8259A可编程中断控制器(PIC)IR0系统定时器IR1键盘IR2彩色/图形接口IR3保留IR4串行通讯口IR5保留IR6软盘IR7打印机INTR08090A0B0C0D0E0F80x86中断源:11设置CPU中断允许位:FLAGS中的IF位=1允许中断(STI)=0禁止中断(CLI)设置中断屏蔽位:中断屏蔽寄存器的中断屏蔽位=0允许I/O设备请求中断=1禁止I/O设备请求中断76543210定时器键盘打印机中断屏蔽寄存器21H76543210中断命令寄存器20HEOIMOVAL,20HOUT20H,AL8259A中断的条件:INAL,21HANDAL,0FDHOUT21H,AL12类型0的(IP)类型0的(CS)类型1的(IP)类型1的(CS)类型N的(IP)类型N的(CS)类型255的(IP)类型255的(CS)00000000044*N003FC中断向量—中断处理程序的入口地址(段址):(偏址)中断向量表用户可利用保留的中断类型号扩充自己需要的中断功能。13CPU中断过程:(1)取中断类型:CPU←typeN(2)保护现场:FLAGS、CS、IP入栈(3)IF=0,TF=0(4)取中断向量:(4×N)→IP(4×N+2)→CS(5)转中断处理程序14例:为中断类型N设置中断向量……MOVAX,0MOVES,AXMOVBX,N*4MOVAX,OFFSETINTHANDMOVES:WORDPTR[BX],AX;偏移地址(N*4)MOVAX,SEGINTHANDMOVES:WORDPTR[BX+2],AX;段地址(N*4+2)……INTHAND:;中断处理程序……IRET15DOS功能调用(21H)存取中断向量:设置中断向量:AH=25HAL=中断类型号DS:DX=中断向量INT21H取中断向量:AH=35HAL=中断类型号INT21H返回时送ES:BX=中断向量16MOVAL,NMOVAH,35HINT21H;取原中断向量PUSHESPUSHBX;保存原中断向量PUSHDSMOVAX,SEGINTHANDMOVDS,AXMOVDX,OFFSETINTHANDMOVAL,NMOVAH,25HINT21H;设置新的中断向量POPDS……POPDXPOPDSMOVAL,NMOVAH,25HINT21H;恢复原中断向量……INTHAND:;中断处理程序……IRET例:用DOS功能调用存取中断向量17中断程序的编写步骤:主程序:(1)设置中断向量(2)设置CPU的中断允许位IF(3)设置设备的中断屏蔽位中断处理子程序:(1)保存寄存器内容(2)如允许中断嵌套,则开中断(STI)(3)中断处理功能(4)关中断(5)送中断结束命令(EOI)给中断命令寄存器(6)恢复寄存器内容(7)IRET中断返回18例:编写一个中断处理程序,要求在主程序运行期间,每隔10秒响铃一次,同时显示‘bell’定时器中断18.2次/SEC;INT_TIMER∶∶INT1CH∶∶IRETINT_1CHPROCIRETINT_ICHENDPRINGPROC1.计数182(10秒)2.显示字符串IRETRINGENDP19例:编写一个中断处理程序,要求在主程序运行期间,每隔10秒响铃一次,并显示‘bell’.modelsmall.stack.datacntdw1mesdb'bell',0ah,0dh,'$'.codemainprocfarstart:movax,@datamovds,axmoval,1chmovah,35hint21hpushespushbxpushdsmovdx,offsetringmovax,segringmovds,axmoval,1chmovah,25hint21hpopdsinal,21handal,11111110bout21h,alsti20movdi,30000dly:movsi,60000dly1:decsijnzdly1decdijnzdly;主程序popdxpopdsmoval,1chmovah,25hint21hmovax,4c00hint21hmainendpringprocnear……;保存寄存器movax,@datamovds,axsti;开中断deccntjnzexitmovdx,offsetmesmovah,09int21hcallsoundmovcnt,182exit:cli;关中断……;恢复寄存器iretringendpendstart21例:键盘模拟程序字符码:采用ASCII码表示字母、数字、专用字符和一些非打印字符,键盘上的控制键和功能键的ASCII码为0,必须用扫描码来识别。扫描码:键盘上的每个键都对应一个扫描码,扫描码是按键的位置来排列的。datasegmentscatabdb0,0,'1234567890-=',8,0db'qwertyuiop[]',0dh,0db'asdfghjkl;',0,0,0,0db'zxcvbnm,./',0,0,0db'',0,0,0,0,0,0,0,0,0,0,0,0,0db'789-456+1230',0dataends22mainprocfar……leabx,scatabkey_in:inal,60htestal,80h;通码?jnzkey_inpushaxinal,61horal,80h;置应答位out61h,alandal,7fhout61h,al;复位应答位popaxcmpal,01jzexit;按Esc退出xlatbcmpal,0jzno_dispcalldisp_charno_disp:jmpkey_inexit:……mainendpdisp_charprocnearmovah,2movdl,alint21hretdisp_charendp76543210设备控制寄存器61H键盘23例:从键盘接收字符,同时对32字节的输入缓冲区进行测试;如缓冲区已满,将键盘挂起,由打印机输出一个提示信息MAINBUFFER满CALLCALLIRETNKBD中断32次TYP中断17次KBINTIRETPRINTRETDISPRETINTIP24例:从键盘接收字符,同时对32字节的输入缓冲区进行测试;如缓冲区已满,将键盘挂起,由打印机输出一个提示信息程序包括以下几个部分:main初始化部分kbint键盘中断处理程序intip初始化打印机prtint打印机中断处理程序disp用十六进制显示al中的内容25dsegsegmentaddrdw?;缓冲区指针countdw?bufferdb20hdup('')promptdb'pleaseinput:',0dh,0ah,'$'messagedb'bufferoverflow',0dh,0ahsave_ip9dw?save_cs9dw?save_ipfdw?save_csfdw?dsegendsmainprocfar……movaddr,offsetbuffermovcount,026moval,09;键盘movah,35hint21hmovsave_ip9,bxmovsave_cs9,esmovdx,offsetkbintpushdsmovax,segkbintmovds,axmoval,09movah,25hint21hpopdsinal,21handal,0fdhout21h,almoval,0fh;打印机movah,35hint21hmovsave_ipf,bxmovsave_csf,esmovdx,offsetprtintpushdsmovax,segprtintmovds,axmoval,0fhmovah,25hint21hpopdsmovah,9leadx,promptint21h27stimovdi,8000hdly:movsi,9000hdly1:decsijnzdly1decdijnzdlymovah,2movdl,'$'int21hclipushdsmovdx,save_ip9movax,save_cs9movds,axmoval,09movah,25hint21hpopdspushdsmovdx,save_ipfmovax,save_csfmovds,axmoval,0fhmovah,25hint21hpopdsinal,21handal,0fdhout21h,alsti……mainendp28kbintprocnearpushaxpushbxinal,60hpushaxinal,61hmovah,aloral,80hout61h,al;送键盘应答信号xchgah,alout61h,al;复位键盘popaxtestal,80hjnzret1;通码时处理通码:(60h)7=0断码: