控制科学与工程学院,win10怎么显示文件后缀

后缀 3
控制科学与工程学院 微型计算机原理与应用 实验指导书 控制学院基础实验室微机与单片机原理实验分室耿宝 山东大学二零零九年十月 目 录 汇编语言开发环境实验实验1-1汇编语言程序开发环境实验实验1-2分支程序实验实验1-3循环程序实验实验1-4子程序实验 程序设计实验实验2-1计算机系统时间显示程序设计实验实验2-2计算机键盘字符输入程序设计实验实验2-3键盘模拟电子琴发声实验 简单I/O并行接口实验实验3-1PCI总线接口卡配置资源获取实验实验3-2拨动开关并行接口实验实验3-3发光二极管并行接口实验 8255可编程并行接口实验实验4-1七段数码管显示控制实验实验4-24*4十六进制数键盘控制实验 附录1PWB开发环境使用方法附录2CodeView调试器使用方法附录3汇编语言程序开发步骤附录4PCI总线配置资源简单介绍附录5实验参考程序参考文献
1 汇编语言开发环境实验 实验1-1汇编语言程序开发环境实验 实验目的:通过实验例题掌握MASM6宏汇编语言集成开发环境的使用方法。
实验设备:RPC-500工业控制计算机 1台 SXL-100微型计算机接口实验仪1台 实验内容:实验1-1是实验例题。
在实验程序里对数组X中的数据进行累加运算,结 果存放在变量XSUM中。
下面简要介绍实验程序。
实验程序是一个多模块程序,它由两个模块文件组成。
第1个模块文件只包含主程序, 称为主模块;第2个模块文件只包含子程序,称为子模块。
在主模块文件里的“EXTRNSUMX:FAR”语句表示标识符“SUMX”是外部引用的 标识符,即这个标识符是在子模块文件中出现的,“FAR”表示它是远调用。
.MODEL指出汇编时内存使用模式,在这里使用小模式。
.STACK定义了堆栈段的大小,程序里定义了16个字节的堆栈空间。
.DATA是数据段定义,数据段里定义了4个数据变量:数组
X、数组中数据个数变量 CON、存放累加结果变量XSUM、字符数组MSE。
字符数组里,“0DH”是换行控制符,“0AH” 是回车控制符,“$”表示字符数组结束。
.CODE表示代码段的开始。
.STARTUP是程序运行的起始点,它下面第1条有效的汇编语句是整个程序的执行入 口,使用这条语句后,在主程序的开始不需要进行数据段段寄存器的赋值,主程序末尾的 END语句后面不用写上程序运行起始标号。
下面是实验例题里的主模块文件。
程序送入计算机时,不同的模块文件要分别输入,并 用不同的文件名存盘。
EXTRN XDACONXSUMMSE MAIN SUMX:FAR .MODELSMALL .STACK16H .DATA DB 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 EQU$-XDA DW?
DB 'ShiyanJieshu',0Dh,0AH,'$' .CODE .STARTUP PROCFAR LEASI,XDA ;取数组X的偏移地址 MOVCX,CON ;数组XDA的数据个数送CX寄存器 CALLSUMX ;调用数据累加子程序; MOVXSUM,AX ;结果送结果变量XSUM MOVDX,OFFSETMSE ;取字符串变量MSE的偏移地址
2 EXIT:MAIN MOVINTMOVINTENDPEND AH,921HAH,4CH21H ;INT21H的功能09H,在屏幕上显示字符串;INT21H的功能4CH,返回DOS操作系统 下面是子程序模块文件,在子程序模块里只有一个子程序,在文件的开始处有一条语句“PUBLICSUMX”它表示标识符SUMX是可以让其他模块文件使用的标识符。
在子程序模块文件里没有“.STARTUP”语句,这是因为在一个程序里只能有一个执行程序的入口点,而程序的入口点一般都在主程序模块里面。
PUBLICSUMX .MODELSMALL .CODE SUMXPROCFAR JCXZEXITA PUSHSI PUSHCX SUBAX,AX LOP:ADDAL,[SI] ADCAH,
0 JC LOP1 INCSI LOOPLOP LOP1:POPCX POPSI EXITA:RET SUMXENDP END 实验步骤:
(1)使用PWB开发环境提供的编辑功能将实验程序按模块分别送入计算机并存盘保存。

(2)使用PWB的Project菜单中的NewProject命令建立一个工程,在建立工程的对话框里输入工程名(工程名的默认后缀是.Mak)。
用鼠标或回车键确认后进入另一个对话框,在这个对话框的FileName栏里输入要加入工程的模块文件名或在FileList列表框里双击要加入工程的模块文件名,即可将模块文件加入工程。
用这种方法将所有要加入工程的模块文件都加入到工程里,然后双击对话框左下角的命令按钮,确认并返回编辑界面。

(3)使用Project菜单中的CompileFile命令汇编实验程序并生成目标文件(.OBJ)。
如果没有汇编错误(一般是语法错误),就继续使用同一个菜单中的Build命令生成可执行文件(或者使用RebuildAll命令)。
在生成执行文件的过程中如果有错误(一般是连接错误),可以在BuildResults窗口里找到发生错误的程序行和错误类型。

(4)可以使用Build命令执行后出现的对话框里提供的执行程序按钮,运行实验程序。
也可以用Run菜单中的Execute命令执行实验程序。

3
(5)使用Run菜单中的Debug命令进入CodeView调试器调试程序,如果从Run菜单中的Debug命令不能进入CodeView调试器,可以退出PWB程序,从计算机的桌面上双击CV图标进入CodeView调试器,然后装入执行程序(.EXE程序)。
CodeView调试器的使用方法见实验指导书的相关部分。
下面简单介绍CodeView调试器部分命令使用方法:F10键是单步执行程序键。
F8键是跟踪执行程序键。
在Windows菜单的上半部分是窗口控制命令,下半部分是窗口选择命令。
在Windows菜单中的Sourcel、Register、Memery、ViewOutput命令分别用来打开源程序窗口,寄存器窗口,存储器窗口,观察窗口。
Options菜单前面的选项用来对选中的窗口进行参数设置。
Run菜单里有程序复位命令。
实验1-2分支程序实验 实验目的:在程序设计中分支程序是最常见的程序结构,通过实验学习掌握分支程序 的结构和程序设计的基本原理。
实验设备:RPC-500工业控制计算机 1台 SXL-100微型计算机接口实验仪1台 实验内容:在程序设计中经常需要根据设计要求对不同的情况作出不同的处理,顺序 程厅设计方法不能满足程序设计的要求,在这种情况下就需要使用分支程序结构。
分支程序 结构可以根据程序运行过程中出现的各种条件,有选择的执行不同的处理程序。
分支程序中出现的各种条件是由标志寄存器中的条件标志的各种状态反映出的。
分支程 序设计的主要问题是根据各标志的不同状态选用合适的转移指令。
分支程序结构分为单分支 程序结构、双分支程序结构和多分支程序结构等。
单分支程序结构是分支程序中简单而且基本的一种分支结构。
单分支程序根据条件判 断,条件满足就转移到分支程序段,而条件不满足就顺序执行下面的程序。
实验题目:从键盘上输入一个数字,如果是数字
0,在屏幕上显示数字
0。
ESC键退出程 序。
下面是单分支程序实验参考程序。
.MODELSMALL .STACK100H .CODE .STARTUP START: MOV AH,07H INT 21H MOV AL,1BH ;1BH是ESC键的扫描码。
JZ EXIT CMP AL,30H JNZ LOP1 MOV DL,’0’ MOV AH,
2 INT 21H LOP1: JMP START
4 EXIT: MOV AH,4CH INT 21H END 双分支程序会根据条件满足或条件不满足分别转移到不同的分支程序段处理相应的问 题。
实验题目:有一个数组,数组里有三个数据,编写一个程序,将这三个数据按由大到小 的次序排序并再次存入这个数组里。
下面是双分支程序实验参考程序。
.MODELSMALL .DATA VER DB 23,56,12 .STACK100H .CODE .STARTUP MOV SI,OFFSETVER MOV AL,[SI+0] ;将数组中的数分别存入AL,BL,CL寄存器 MOV BL,[SI+1] MOV CL,[SI+2] CMP AL,BL JAE NEXT1 XCHGAL,BL NEXT1: CMP AL,CL JAE NEXT2 XCHGAL,CL NEXT2: CMP BL,CL JAE NEXT3 XCHGBL,CL NEXT3: MOV [SI+0],AL MOV [SI+1],BL MOV [SI+2],CL MOV AH,4CH INT 21H END 多分支程序有多个条件,每个条件对应一个操作。
程序在运行中对每个条件都进行扫描判断,那一个条件成立,就执行哪个条件对应的程序段。
多分支程序设计有几种基本的方法,如逻辑判断转移方法,地址表转移方法,转移表转移方法。
实验题目:从键盘上输入数字,如果输入的数字在0–3内就在屏幕上显示提示信息,如果不是0--3内的数字或字符,屏幕上不显示提示信息。
分别用三种不同的方法编写实验程序。
下面是多分支程序实验参考程序。
逻辑判断转移方法实验参考程序。

5 DIS0DIS1DIS2DIS3 .MODEL.DATADBDBDBDB SMALL 0DH,0AH,'INPUTDIGIT0!
','$'0DH,0AH,'INPUTDIGIT1!
','$'0DH,0AH,'INPUTDIGIT2!
','$'0DH,0AH,'INPUTDIGIT3!
','$' .STACK100H.CODE.STARTUP START:MOVAH,07H INT 21H CMP AL,1BH ;如果按下ESC键就退出程序。
JZ EXIT CMP AL,30H ;判断是否数字键
0 JNZ LOP1 JMP PROG0 LOP1: CMP AL,31H ;判断是否数字键
1 JNZ LOP2 JMP PROG1 LOP2: CMP AL,32H ;判断是否数字键
2 JNZ LOP3 JMP PROG2 LOP3: CMP AL,33H ;判断是否数字键
3 JNZ LOP4 JMP PROG3 PROG0: MOV DX,OFFSETDIS0 ;数字键0处理程序 JMP PROG PROG1: MOV DX,OFFSETDIS1 ;数字键1处理程序 JMP PROG PROG2: MOV DX,OFFSETDIS2 ;数字键2处理程序 JMP PROG PROG3: MOV DX,OFFSETDIS3 ;数字键3处理程序 PROG: MOV AH,09H INT 21H LOP4: JMP START EXIT: MOV AH,4CH ;退出正在运行的程序,返回操作系统 INT 21H END 地址表转移方法实验参考程序。
.MODELSMALL.DATA
6 DIS0DIS1DIS2DIS3TAB DB 0DH,0AH,'INPUTDIGIT0!
','$' DB 0DH,0AH,'INPUTDIGIT1!
','$' DB 0DH,0AH,'INPUTDIGIT2!
','$' DB 0DH,0AH,'INPUTDIGIT3!
','$' DW PROG0,PROG1,PROG2,PROG3 ;地址表 .STACK.CODE.STARTUP 100H START: MOV AH,07H INT 21H CMP AL,1BH JZ EXIT CMP AL,30H JB LOP1 CMP AL,33H JA LOP1 MOV AH,00H AND AL,0FH SHLAL,
1 ;地址表中每个指令占2个字节,需要乘
2 LEA BX,TAB ADD BX,AX JMP WORDPTR[BX] PROG0: MOV DX,OFFSETDIS0 JMP PROG PROG1: MOV DX,OFFSETDIS1 JMP PROG PROG2: MOV DX,OFFSETDIS2 JMP PROG PROG3: MOV DX,OFFSETDIS3 PROG: MOV AH,09H INT 21H LOP1: JMP START EXIT: MOV AH,4CH INT 21H END 转移表转移方法实验参考程序。
.MODELSMALL .DATA DIS0 DB 0DH,0AH,'INPUTDIGIT0!
','$' DIS1 DB 0DH,0AH,'INPUTDIGIT1!
','$' DIS2 DB 0DH,0AH,'INPUTDIGIT2!
','$'
7 DIS3 DB 0DH,0AH,'INPUTDIGIT3!
','$' .STACK100H.CODE.STARTUP START: MOV AH,07H INT 21H CMP AL,1BH JZ EXIT CMP AL,30H JB LOP1 CMP AL,33H JA LOP1 MOV AH,00H AND AL,0FH SHLAL,
1 ;转移表中每个指令占2个字节,需要乘
2 LEA BX,TAB ADD BX,AX JMP BX TAB: JMPSHORTPROG0 ;转移表 JMP SHORTPROG1 JMP SHORTPROG2 JMP SHORTPROG3 PROG0: MOV DX,OFFSETDIS0 JMP PROG PROG1: MOV DX,OFFSETDIS1 JMP PROG PROG2: MOV DX,OFFSETDIS2 JMP PROG PROG3: MOV DX,OFFSETDIS3 PROG: MOV AH,09H INT 21H LOP1: JMP START EXIT: MOV AH,4CH INT 21H END 实验步骤:同实验
一。
实验报告要求: 实验报告要求有实验目的,实验设备,实验内容。
最重要的是实验结果和对实验的分析。
本次实验要求在对实验结果和实验过程的分析基础上,选择一个多分支实验程序,画出程序框图并给出具体的程序设计思想的分析。

8 实验1-3循环程序实验 实验目的:循环程序在程序设计中是一种非常重要的程序结构,通过实验学习和掌握循 环程序的设计方法和原理。
实验设备:RPC-500工业控制计算机 1台 SXL-100微型计算机接口实验仪1台 实验内容:在解决一些实际问题的时候,程序中有一些代码段需要重复执行,这就需要 在程序设计中使用循环程序结构。
不同于顺序程序结构和分支程序结构,循环程序结构由几 个部分组成,分别为循环控制初值设置,循环体,修改循环控制值和控制转移四个部分。
控 制循环过程是循环程序设计中的一个重要环节,有多种循环控制方法,其中常用的两种循环 控制方法分别是计数控制循环和条件控制循环。
程序题目:统计AX寄存器中的1的位数,并将统计数据存放在BL寄存器里。
要求循 环控制方法采用计数控制循环方法。
下面是计数控制循环方法实验参考程序。
VER LOP1:LOP2:EXIT: .MODELSMALL .DATA DB 23H .STACK100H .CODE .STARTUP MOVBL,
0 MOVCX,16 SALAX,
1 JNCLOP2 INCBL DECCX JNZLOP1 MOVAH,4CH INT21H END ;设置循环控制初值;循环体 ;修改循环控制值;控制转移 程序题目:统计AX寄存器中的1的位数,并将统计数据存放在BL寄存器里。
要求循环控制方法采用条件控制循环方法。
下面是条件控制循环方法实验参考程序。
VERLOP1: .MODELSMALL .DATA DB 23H .STACK100H .CODE .STARTUP MOVBL,
0 ANDAX,AX JZ EXIT
9 SALAX,1JNCLOP1INCBLJMPLOP1EXIT:MOVAH,4CHINT21HEND实验步骤:同实验1-
1。
实验报告要求:实验报告要求有实验目的,实验设备,实验内容。
最重要的是实验结果和对实验的分析。
本次实验要求在对实验结果和实验过程的分析基础上,选择一个程序,画出程序框图并给出具体的程序设计思想的分析。
实验1-4子程序实验 实验目的:进一步学习子程序的调用方法。
重点在子程序调用过程中的参数传递方法。
实验设备:RPC-500工业控制计算机 1台 SXL-100微型计算机接口实验仪1台 实验内容:在实验1-2里,主程序同子程序之间传递参数是采用寄存器传递参数方法, 除此之外,常用的传递参数方法还有使用堆栈传递参数的方法和内存传递参数的方法。
实验题目:使用堆栈传递参数的方法实现子程序调用。
实验程序包括主程序和累加子程 序,而显示子程序见实验1-
2。
下面是堆栈传递参数调用子程序实验 主程序模块: EXTRNADD2:NEAR EXTRNDISP:NEAR .MODELSMALL .STACK .DATA XX1DB 1,2,3,
4 CONEQU$-X1 MESDB 0DH,0AH,'ShiyanJieshu','$' .CODE MAINPROCFAR MOVAX,@DATA MOVDS,AX LEAAX,XX1 ;取数组变量地址 PUSHAX ;压入堆栈 MOVAX,CON ;取数组元素个数 PUSHAX ;压入堆栈 CALLADD2 CALLDISP MOVDX,OFFSETMES MOVAH,
9 10 MAIN INTMOVINTENDPEND 21HAH,4CH21H MAIN 子程序模块: PUBLICADD2 PUBLICDISP.MODEL.CODE SMALL SUBPROGPROCNEARADD2:MOVBP,SP MOVCX,[BP+2]MOVSI,[BP+4]MOVAX,
0 CLCLOP1:ADC AL,[SI+0] DAA INCSI LOOPLOP1 RET4 DISP:MOVDL,AL MOVCL,
4 ROLDL,CL CALLDISP1 MOVDL,AL CALLDISP1 RET DISP1:ANDDL,0FH ADDDL,30H CMPDL,3AH JL DISP2 ADDDL,07H DISP2:PUSHAX MOVAH,
2 INT21H POPAX RET SUBPROGENDP END ;堆栈指针送BP寄存器;通过BP寄存器里的堆栈指针取数 ;返回时调整堆栈指针,SP+
2,然后SP+4;显示程序 11 程序分析:在主程序里,参数压入堆栈后堆栈指针加
4,调用子程序后堆栈指针再加
2。
如果在子程序返回时不调整堆栈指针,在堆栈里就会残留有4个字节的内容,多次使用堆栈传递参数后会发生堆栈溢出。
在子程序返回时使用RET4指令,首先从堆栈里弹出子程序返回地址,然后在将堆栈指针调整到传递参数以前的指针值上。
子程序的第1条指令将SP的内容送基地址寄存器BP里,用来保护堆栈指针。
实验题目:使用内存传递参数的方法实现子程序调用。
实验程序包括主程序和累加子程序,显示子程序见实验1-
2。
下面是内存传递参数调用子程序实验 实验参考程序,下面给出主程序和累加子程序,显示子程序见实验1-
2。
EXTRN MESMAIN; DISPA: ;ADD3:CS:LOP1: DISP:FAR .MODELSMALL .STACK .DATA DB 'ShiyanJieshu',ODH,OAH,'$' .CODE PROCFAR MOVAX,@DATA MOVDS,AX CALLDWDBCALLMOVMOVINTMOVINT ADD3DISPA-$-21,2,3,4DISPDX,OFFSETAH,921HAH,4CH21H MES ;由主程序向子程序传递的参数 MOVMOVMOV BP,SPSI,[BP+0]CX,CS:[SI+0] ;数据放在代码段,取数需要加段前缀 MOVCLCADCDAAINCLOOPMOVPOPMOV AX,
0 AL,CS:[SI+2] SILOP1BX,AXAXAX,OFFSET DISPA ;调整堆栈指针;取子程序返回地址 12 MAIN PUSHMOVRETENDPEND AXAX,BX MAIN 程序分析:在主程序里主程序向子程序传递的参数放在子程序的调用指令后面。
在调用子程序的时候,存放在堆栈指针寄存器SP里的子程序的返回地址,实际上是指向参数的地址指针。
在子程序里,这个地址指针送到BP寄存器里,以读取传递给子程序的参数。
在子程序返回之前,将子程序真正的返回地址(由标号DISPA指出的符号地址)压入堆栈,使子程序正确返回主程序。
实验步骤:同实验1-1实验报告要求:实验报告要求有实验目的,实验设备,实验内容。
最重要的是实验结果 和对实验的分析。
本次实验要求在对实验结果和实验过程的分析基础上,选择一个程序,画出程序框图并给出具体的程序设计思想的分析。
13 程序设计实验 实验2-1计算机系统时间显示程序设计实验 实验目的:掌握使用宏汇编语言设计程序和解决问题的方法。
实验设备:RPC-500工业控制计算机 1台 SXL-100微型计算机接口实验仪1台 实验内容:在计算机上有一个时钟电路,使用BIOS中断功能可以读出系统时钟的时间 值。
用来读取系统时间的BIOS中断是中断功能INT1AH。
它有3个功能参数,即0号,
1 号,2号功能参数。
0号功能用来读当前时钟值,没有入口参数,出口参数CX:DX=时钟 计数值;1号功能用来设置当前时钟值,入口参数CX:DX=时钟计数值,没有出口参数;
2 号功能读电池供电时钟值,没有入口参数,出口参数CH:CL:DH=从电池供电时钟读出的 当前时间的时:分:秒。
下面的程序段可以用来读取系统时间参数。
MOV AH,
2 INT 1AH 读出的内容自动存放在CX,DH寄存器里(BCD码,24小时制)。
实验题目:设计一个程序,读出计算机的系统时间值,并将它显示在计算机的屏幕上。
程序设计提示:在数据段定义一个变量,变量即可以保存读出的时间值,也可以作为在 屏幕上显示的字符串。
读出时间值以后先将它转换成ASCII码,再将它存放到变量里。
在读 出全部时间值以后,再在屏幕上显示读出的系统时间。
将读出的以BCD码表示的时间值转换成ACSII码可以使用HEX码到ASCII码转换程序(只 使用HEX数里的0---9数码)。
将数字的HEX码转换成对应的ASCII码只要将HEX码加上30H。
放在寄存器里等待转换的HEX码的格式应该是高4位是
0,低4位是等待转换的HEX码。
下面的程序是以子程序的形式给出。
假设在AH寄存器存放2个HEX码,一个在高4位, 一个在低4位。
转换后的结果存放在AX寄存器里。
MOV AL,AH MOV CL,
4 SHR AL,CL ;取低4位。
ADDAL,30H ;转换成ASCII。
CMP AL,3AH JL LOP1 ;小于3AH,是0-9数字。
ADD AL,07H ;大于3AH,是A-F数字,需要加
7。
LOP1:AND AH,0FH ;取高4位。
ADD AH,30H CMP AH,3AH JL LOP2 ADD AH,07H LOP2:RET 14 实验步骤:
(1)按照实验题目的要求,参考实验程序框图(图3-1,3-2,3-3),使用宏汇编语言设计和编写程序(可参考实验参考程序)。

(2)使用宏汇编语言开发环境编辑和汇编实验程序,直到实验程序无语法错误为止。

(3)使用宏汇编语言开发环境运行和调式程序,直到程序正常运行为止。
实验程序框图: 主程序开始 #建立数据段#设置系统时钟数据存储单元(用ASCII码方式)和屏幕显示字符串数据:2DUP
(0),':',2DUP
(0),':',2DUP
(0),0DH,0AH,'$' 使用中断INT1AH的功能
2,读系统时间值。
将系统时间字符数据串首地址送SI寄存器 将读出的小时值从CH寄存器里送到AH寄存器 调用BCD码到ASCII码转换程序。
将转换后的数据存到待显示字符串的相应位置,地址为[SI+0]。
将读出的分钟值从CL寄存器里送到AH寄存器 调用BCD码到ASCII码转换程序。
将转换后的数据存到待显示字符串的相应位置,地址为[SI+3]。
将读出的秒值从CH寄存器里送到AH寄存器 调用BCD码到ASCII码转换程序。
将转换后的数据存到待显示字符串的相应位置,地址为[SI+6]。
使用INT21H中断功能9在屏幕上显示系统时间值 程序结束 15 实验2-2计算机键盘字符显示程序设计实验 实验目的:掌握使用宏汇编语言设计程序和解决问题的方法。
实验设备:RPC-500工业控制计算机 1台 SXL-100微型计算机接口实验仪1台 实验内容:读取计算机键盘字符并将其显示在计算机屏幕上。
为了识别PC机键盘上的 按键,每个键都有扫描码或扩充扫描码,而数字键和字母键还都有对应的ASCII码。
扩充扫 描码主要是用来识别键盘组合键。
在系统的BIOS中断里的INT16H中断调用的功能用来处 理键盘输入的字符,它有3个功能,分别是0号,1号,2号功能。
INT16H中断调用的
0 号功能可以读键盘字符,没有入口参数,它的出口参数在AX里。
其中,AL≠
0,表示在AL 寄存器里是ASCII码;AL=
0,表示相应字符无ASCII码;AH寄存器里是字符的扫描码。
下 面的程序段利用INT16H的0号功能读键盘。
INT16H功能0程序段 MOVAH,
0 INT 16H CMP AL,
0 JNELOP1 CMP AH,02H JE LOP2 ;功能号0放在AH寄存器里。
;AL≠
0,AL里存放的是键的ASCII码,AH存放的是扫描码。
;AL=
0,AH存放的是扫描码。
系统中断INT16H的0号功能读出的值在AX寄存器里,如果AL≠
0,则AL里存放的是按下的键对应的ASCII码,AH里存放的是对应的扫描码。
如果AL=
0,则表示按下的键没有对应的ASCII码,但在AH里有对应的扫描码(或扩充扫描码)。
通过比较判断AX寄存器里的值,程序就可知道是那一个键按下。
实验题目:设计一个程序,从键盘上读键,并将读出的字母键(a---z)的值显示在计算机屏幕上。
将除a---z以外的键值屏蔽,不显示屏幕上。
a---z的键对应的ACSII是61H—7AH 编程提示:读键使用系统中断INT16H的0号功能,显示字符使用系统中断INT21H的2号功能(要显示的字符的ACSII码放在DL寄存器里,功能号放在AH寄存器里,执行INT21H指令)。
实验步骤:
(1)按照实验题目的要求,使用宏汇编语言设计和编写程序。

(2)使用宏汇编语言开发环境编辑和汇编实验程序,直到实验程序无语法错误为止。

(3)使用宏汇编语言开发环境运行和调式程序,直到程序正常运行为止。
16 实验2-3键盘模拟电子琴发声实验 实验目的:掌握PC机扬声器驱动系统电路原理。
学习PC机上的8255可编程外围接口 芯片和8254定时器与扬声器有关的控制方法。
实验设备:RPC-500工业控制计算机 1台 SXL-100微型计算机接口实验仪1台 实验内容:大多数的比较老式的PC机都有一个扬声器,用来发出声音,提示系统操作。
用户也可以用它做一些其他工作。
扬声器驱动电路见图2-3-
1。
76543210 8255(61H) 1.19MHz 去CPU 8254定时器 与门 驱动器 扬声器 图3-3-1扬声器驱动系统电路图 8255的输出寄存器(61H)的第0位,第1位控制扬声器。
第0位为“1”时控制8254定时器驱动扬声器。
第1位为“1”时,控制扬声器的门电路与门打开并一直保持到第1位变为“0”。
扬声器的发声受8254定时器驱动。
连接到扬声器的8254的2#定时器,实际是一个震荡电路,向扬声器发送指定频率的脉冲。
当8255的输出寄存器(第0,1位)控制扬声器为接通状态时,扬声器发出一定频率的声音。
实验题目:使用键盘上的数字键1---8模拟电子琴的键盘。
在键盘上按下数字键1,2,3,4,5,6,7,8时,让扬声器分别发出1,2,3,4,5,6,7,i的音调。
按“ESC”键结束程序。
编程提示:8255的输出寄存器(61H)控制扬声器的开始发声与停止发声,将8255的输出寄存器(61H)逻辑或03H可以打开扬声器,逻辑与0FCH可以关闭扬声器。
定时器的控制寄存器是43H,通过43H可以重新初始化8254的2#定时器。
8254的2#定时器的时间常数寄存器地址是42H,16位时间常数分成两个8位,分两次写入,第一次为低8位,第二此为高8位。
在数据段定义一个数表,字类型数据,对应“1----i”8个音调的发声频率的计数初值。
这8个音调的计数初值是:
1 9108
4 6818
7 4831
2 8116
5 6088 i 4554
3 7231
6 5432 17 PC机键盘上的按键ESC的ASCII码是1BH,数字键1—8的ASCII码是31H---38H。
实验参考框图: 程序开始 建立数据段.DATA ……DATAENDP 使用INT16H系统中断从键盘读键。
Y是ESC键?
N N是1---8键值? 退出程序
Y ASCII转换成数字值,乘2建立表索引值。
查表,取得相应音调的定时值。
通过8255,打开扬声器 重新初始化2#计数器,0B6H送端口43H。
音调时间常数值低8位送2#计数寄存器42H。
音调时间常数值高8位送2#计数寄存器42H。
18 简单I/O并行接口实验 实验3-1PCI总线接口卡配置资源获取实验 实验目的:学习和掌握PCI总线设备资源获取方法。
实验设备:RPC-500工业控制计算机 1台 SXL-100微型计算机接口实验仪1台 实验原理:PCI总线接口规范包含有一系列的寄存器,这些寄存器位于PCI接口上的
个配置内存区上,包含了主板的所有信息。
寄存器中的这些信息允许计算机自动配置PCI 卡。
这个特性就是即插即用特性。
可以使用汇编语言编程的方法获取PCI总线配置资源。
实验内容:实验程序要在DOS操作系统的支持下运行,应用PCIBIOS提供的功能,获 得SXL-100微型计算机接口实验仪的PCI接口卡在PC机里分配的系统资源。
然后将获得的 系统资源(基地址寄存器地址和中断内容等)显示在计算机的屏幕上。
获取PCI接口卡信息需要使用INT1AH中断调用,而INT1AH中断调用只能在DOS 操作系统或WINDOWS98操作系统的DOS环境下使用而不能在WINDOWS2000, WINDOWSXP操作系统下工作。
因此程序只能运行在DOS环境下。
图3-1是获取PCI配置空间资源实验程序的参考程序框图,下面是实验参考程序。
.386 .MODELSMALL .DATA ;提示信息定义 DIS0 DB 'PCICONFIGINFORMATION!
$' DIS1 DB 'PCII/OADDRESS0$' DIS2 DB 'PCII/OADDRESS1$' DIS3 DB 'PCIMEMORYADDRESS$' DIS4 DB 'PCIINTERRUPTLINE$' DIS5 DB 'BIOSNOTSUPPER!
$' DIS6 DB 'READPCIBOARDFAIL!
$' ;PCI配置空间寄存器地址定义 PCI_CS_VENDOR_ID EQU 00H PCI_CS_DEVICE_ID EQU 02H PCI_CS_COMMAND EQU 04H PCI_CS_STATUS EQU 06H PCI_CS_REVISION EQU 08H PCI_CS_CLASS_CODE EQU 09H PCI_CS_CACHE_LINE_SIZE EQU 0CH size) ;数据段定义 ;“PCI卡配置信息”;“PCI卡I/O地址0”;“PCI卡I/O地址1”;“PCI卡存储器地址”;“PCI卡中断号”;“BIOS不支持”;“读PCI卡失败” ;生产商识别ID(vendorID);设备ID(DeviceIdentifcation);PCI命令寄存器(Command);PCI状态寄存器(Status);修正识别码寄存器(REVID);类代码寄存器(ClassCODE);cache线大小寄存器(cacheLINE 19 PCI_CS_MASTER_LATENCY EQU PCI_CS_HEADER_TYPE EQU PCI_CS_BIST EQU PCI_CS_BASE_ADDRESS_
0 EQU REGISTER) PCI_CS_BASE_ADDRESS_
1 EQU PCI_CS_BASE_ADDRESS_
2 EQU PCI_CS_BASE_ADDRESS_
3 EQU PCI_CS_BASE_ADDRESS_
4 EQU PCI_CS_BASE_ADDRESS_
5 EQU PCI_CS_EXPANSION EQU (ExpansionRomBaseAddress) PCI_CS_INTERRUPT_LINE EQU PCI_CS_INTERRUPT_PIN EQU PCI_CS_MIN_GNT EQU PCI_CS_MAX_LAT EQU ;工作变量数据定义 ADDRESS_IO_
0 DW ADDRESS_IO_
1 DW ADDRESS_MEM_
L DW ADDRESS_MEM_
H DW INTERRUPT_LINE DB .STACK100H .CODE.STARTUP;;设置显示方式 MOV AL,
3 MOV AH,
0 INT 10H ; ;显示提示信息 MOV DX,OFFSETDIS0 MOV AH,
9 INT 21H ; 0DH ;主控延时时间(LATENCYTIMER) 0EH;头类型(HEADERTYPE) 0FH ;自我测试(BIST) 10H;基地址寄存器(BASEADDRESS 14H 18H 1CH 20H 24H 30H ;扩展ROM基地址 3CH;中断线(INTERRUPTLINE) 3DH;中断引脚(INTERRUPTPIN) 3EH ;MinimumGrant 3FH ;最大延时 ?
;存储读出的I/O地址
0 ?
;存储读出的I/O地址
1 ?
;存储读出的存储器低位地址 ?
;存储读出的存储器高位地址 ?
;存储读出的中断号 ;堆栈段定义 ;代码段定义;程序开始 20 ;设置屏幕上光标的位置 MOV AH,2H MOV BH,
0 MOV DH,
1 MOV DL,
0 INT 10H ; ;测试PCIBIOS是否存在 MOV AH,0B1H MOV AL,01H INT 1AH .IFAH!=00 MOV DX,OFFSETDIS5 ;屏幕输出显示“BIOSNOTSUPPER!
” JMP m_EXIT .ENDIF;;测试计算机原理接口实验仪是否存在 MOV AH,0B1H MOV AL,02H MOV CX,8376H MOV DX,10EBH MOV SI,
0 INT 1AH JNC LOOP_
0 ;返回值CF=00H,表示读PCI卡成功,程序 转移。
MOV DX,OFFSETDIS6 ;屏幕输出显示“READPCIBOARDFAIL!
” MOV AH,
9 INT 21H JMP m_EXIT ;返回值CF=01H,表示读PCI卡失败,程序 转结束。
; ;读PCI卡地址空间0的起始地址。
LOOP_0: MOV AH,0B1H MOV AL,09H MOV DI,PCI_CS_BASE_ADDRESS_
1 21 INT 1AH .IFAH!=
0 MOV DX,OFFSETDIS6 ;屏幕输出显示“READPCIBOARDFAIL!
” MOV AH,
9 INT 21H JMP m_EXIT .ENDIF AND CX,0FFFCH MOV AX,CX MOVADDRESS_IO_
0,AX ;存储读出的PCI卡I/O空间地址
0 ; ;读PCI卡地址空间1的起始地址。
MOV AH,0B1H MOV AL,09H MOV DI,PCI_CS_BASE_ADDRESS_
3 INT 1AH .IFAH!=
0 MOV DX,OFFSETDIS6 ;屏幕输出显示“READPCIBOARDFAIL!
” MOV AH,
9 INT 21H JMP m_EXIT .ENDIF AND CX,0FFFCH MOV AX,CX MOVADDRESS_IO_
1,AX;;读PCI卡存储器空间起始地址的低位地址。
;存储读出的PCI卡I/O空间地址
1 MOV AH,0B1H MOV AL,09H MOV DI,PCI_CS_BASE_ADDRESS_
2 INT 1AH .IFAH!=
0 MOV DX,OFFSETDIS6 ;屏幕输出显示“READPCIBOARDFAIL!
”。
MOV AH,
9 INT 21H 22 JMP m_EXIT .ENDIF AND CX,0FFFCH MOV AX,CX MOV ADDRESS_MEM_
L,AX ; ;读PCI卡存储器空间起始地址的高位地址 MOV AH,0B1H ;存储读出的存储器空间的低位地址。
MOV AL,09H MOV DI,PCI_CS_BASE_ADDRESS_
2 ADD DI,
2 INT 1AH .IFAH!=
0 MOV DX,OFFSETDIS6 ;屏幕输出显示“READPCIBOARDFAIL!
”。
MOV AH,
9 INT 21H JMP m_EXIT .ENDIF MOV AX,CX MOV ADDRESS_MEM_
H,AX ; ;读PCI卡中断号IRQ。
;存储读出的存储器空间的高位地址。
MOV AH,0B1H MOV AL,09H MOV DI,PCI_CS_INTERRUPT_LINE INT 1AH .IFAH!=
0 MOV DX,OFFSETDIS6 ;屏幕输出显示“READPCIBOARDFAIL!
”。
MOV AH,
9 INT 21H JMP m_EXIT .ENDIF MOV AX,CX MOVINTERRUPT_LINE,AL ;存储读出的中断号IRQ。
; ;****************显示从PCI卡读出的配置信息************ 23 ;;显示PCI卡I/O地址
0 MOV DX,OFFSETDIS1 MOV AH,
9 INT 21H MOV AX,ADDRESS_IO_
0 CALLDISPLAY CALLHDIS;;显示PCI卡I/O地址
1 MOV AH,2H MOV BH,
0 MOV DL,
0 MOV DH,
2 INT 10H MOV DX,OFFSETDIS2 MOV AH,
9 INT 21H MOV AX,ADDRESS_IO_
1 CALLDISPLAY CALLHDIS;;显示存储器空间起始地址高位 MOV AH,2H MOV BH,
0 MOV DL,
0 MOV DH,
3 INT 10H MOV DX,OFFSETDIS3 MOV AH,
9 INT 21H MOV AX,ADDRESS_MEM_
H CALLDISPLAY MOV AX,ADDRESS_MEM_
L CALLDISPLAY CALLHDIS ;屏幕输出显示“PCII/OADDRESS0”;显示读出的I/O地址信息。
;调整屏幕光标位置。
;屏幕输出显示“PCII/OADDRESS1”;显示读出的I/O地址信息。
;调整屏幕光标位置。
;屏幕输出显示“PCIMEMORYADDRESS”;显示读出的存储器空间起始地址高位;显示读出的存储器空间起始地址低位 24 ;;显示PCI卡中断号。
MOV AH,2H ;调整屏幕光标位置。
MOV BH,
0 MOV DL,
0 MOV DH,
4 INT 10H MOV DX,OFFSETDIS4 ;屏幕输出显示“PCIINTERRUPTLINE” MOV AH,
9 INT 21H MOV AH,
0 MOV AL,INTERRUPT_LINE ;显示读出的中断号 CALLDISPLAY CALLHDIS JMP m_EXIT ; ;***********************显示子程序************** ; DISPLAYPROCNEAR PUSHCX PUSHBX MOV CL,
4 MOV CH,
4 DISPH1: ;数字转换为ASCII码输出 ROL AX,CL PUSHAX AND AL,0FH ADD AL,30H CMP AL,'9' JBE DISPH2 ADD AL,
7 DISPH2: ;显示输出 MOV AH,
2 MOV DL,AL INT 21H 25 POP AX DEC CH JNZ DISPH1 POP CX POP BX RET DISPLAYENDPHDISPROC NEAR MOV DL,'H' MOV AH,
2 INT 21H RET HDISENDP ;;*******************************;m_EXIT: MOVAX,4C00H INT21H END ;如果显示16进制地址,在后面加“H”程序结束***************** 实验步骤:
(1)使用PWB进入MASM6宏汇编语言集成开发环境,然后输入并编辑实验程序。

(2)使用PWB开发环境里的Project菜单命令汇编和连接实验程序。
如果出现程序错误则改正错误,重新汇编连接程序直到没有错误为止。

(3)运行实验程序并观察程序运行结果。
26 程序开始 设:AH=0B1H,AL=01H调用中断INT1AH 存在PCIBIOS的支持? 设置以下参数:AH=0B1H,AL=02H CX=8376H,DX=10EBH,SI=00H 执行中断调用:INT1AH 显示PCIBIOS不存在的信息“BIOSNOTSUPPER!
” 存在计算机原理实验仪? 读取PCI卡的地址空间0的起始地址(I/O空间0) 读取PCI卡的地址空间1的起始地址(I/O空间1) 读取PCI卡的地址空间2的起始地址(存储器空间) 读取PCI卡的中断号(IRQ号) 显示读取的PCI卡的I/O地址存储器地址和IRQ号 显示PCIBIOS不存在的信息“BIOSNOTSUPPER!
” 程序结束 图4-1获取PCI配置空间资源实验程序框图 实验3-2拨动开关并行接口实验 27 实验目的:学习和掌握使用三态门锁存器构成的简单I/O端口的原理及应用。
实验设备:RPC-500工业控制计算机 1台 SXL-100微型计算机接口实验仪1台 实验内容:实验仪有一个由74ALS273锁存器和74LSA244总线缓冲器组成具有输出输入 功能的并行接口电路。
输出接口电路控制8位LED发光二极管,输入接口电路连接到8位拨 动开关,见实验电路图3-2-
1。
并行接口电路的输出锁存器和输入缓冲器共同使用一个选通 信号控制。
选通信号的读操作是通过缓冲器读拨动开关的状态,写操作是将8位二进制数字 写入锁存器,控制发光二级管的亮灭。
从实验电路图可以看到,IOR,W3信号组合读拨动开 关的状态,IOW,W3信号组合控制发光二级管状态。
74ALS273和74ALS244的选通端被选通地址线控制,它的选通地址为60H,这是实验仪 通过译码电路分配的地址。
从运行实验程序的控制计算机的角度看,锁存器的选通地址的真实地址是由插在计算机里的实验仪PCI接口板提供的的用户I/O基地址(由计算机自动分配),加上实验仪分配给并行接口电路的地址(60H)形成的。
需要注意的是PCI板卡分配了2块I/O空间,I/O空间0的地址是分配给接口板自身的内部寄存器专用的,空间大小为64字节。
I/O空间1的地址是分配给连接到实验仪PCI接口板的用户电路使用的,其大小为4K字节。
发光二级管的(LED1~LED8)连接方式是共阴极连接,74ALS273锁存器的输出端控制 发光二极管的阳极。
输出端口输出逻辑1电平,使相应的发光二极管点亮,输出端口输出逻 辑0电平使发光二极管熄灭。
8位拔动码开关从左到右分别为K1到K8。
拔动开关是由74ALS244锁存器控制。
拨码 开关拨向上方是“H”状态,拨向下方是“L”状态。
实验要求:设计一个程序,能够通过并行接口读取拔动开关的状态,并将状态显示在计算机的屏幕上,当读取的状态是“33H”的时候,再增加显示一个“ok”字符串。
编程提示:程序由两部分组成。
第一部分是检测实验仪的接口卡并读取计算机自动分配的用户基地址,将用户基地址和实验仪分配给并行接口电路的地址相加,形成完整的并行接口电路的选通地址。
程序的第二部分是通过并行接口电路读取拨动开关的状态,将其显示在计算机屏幕上。
如果读出的状态是“33H”,再显示一个“ok”字符串。
读并行电路输入数据的时候使用INAL,DX指令,寄存器DX里存有通过计算得到的并行接口电路的选通地址。
实验步骤:
(1)实验仪的实验电路连接采用缺省方式,不需要进行硬件电路连线。

(2)设计和编写实验程序。
使用宏汇编语言生成执行程序。

(3)运行实验程序并观察实验结果。
观察计算机屏幕显示的内容,如果不符合实验要 求,寻找问题并解决。
28 数据总线D0 W3是锁存器选 D1 通地址,由PCI D2 卡用户地址和 D3 实验仪译码地 D4 址决定。
D5 D6 74ALS32IC18B D7 IOW
5 6
4 W310 8W1 IOR
9 IC18C VCC 74ALS32 VCC R×
8 IC1774ALS273 D1 Q1 D2 Q2 D3 Q3 D4 Q4 D5 Q5 D6 Q6 D7 Q7 D8 Q8 CLKCLR 数据锁存器 电阻排 J15 J63 圆孔插座 短路插座 发光二极管 J88 1K×8LED 圆孔插座限流电阻 IC1574ALS244 1G2G1A11Y11A21Y21A31Y31A41Y42A12Y12A22Y22A32Y32A42Y4总线缓冲器J64ON1OFF1ON2OFF2ON3OFF3ON4OFF4ON5OFF5ON6OFF6ON7OFF7ON8OFF8 拨码开关 D0D1D2D3D4D5D6D7数据总线 图3-2-1实验电路图 实验3-3发光二极管并行接口实验 29 实验目的:学习和掌握使用三态门锁存器构成的简单I/O端口的原理及应用。
实验设备:RPC-500工业控制计算机 1台 SXL-100微型计算机接口实验仪1台 实验内容:关于实验电路的相关内容见实验3-2的实验内容介绍。
下面是发光二极管 并行接口实验的实验题目。
实验题目:设计一个程序,能够读计算机的键盘,当读出的扫描码处于02H---0BH区间(对应数字1---9,0)的时候,将其显示在发光二极管上。
发光二极管连接在并行接口上,向并行接口的写操作就可以控制发光二极管的亮灭。
编程提示:程序由两部分组成。
第一部分是检测实验仪的接口卡并读取计算机自动分 配的用户基地址,将用户基地址和实验仪分配给并行接口电路的地址相加,形成完整的并行 接口电路的选通地址。
程序的第二部分是通过并行接口电路控制发光二极管电路。
写并行电路输出数据的时候使用OUTDX,AL指令,寄存器DX里存有通过计算得 到的并行接口电路的选通地址。
实验参考程序除主程序不同,其它与实验3-2实验程序基本一样。
从键盘读出键值(扫 描码)后,用排除法确定扫描码范围。
可以使用如下伪指令: .IF AH<=01H (汇编指令) .ENDIF 其它汇编指令 .IF AH>=0CH (汇编指令) .ENDIF 其它汇编指令 实验步骤:
(1)实验仪的实验电路连接采用缺省方式,不需要进行硬件电路连线。

(2)设计和编写实验程序。
使用宏汇编语言生成执行程序。

(3)运行实验程序并观察实验结果。
观察计算机屏幕显示的内容,如果不符合实验要 求,寻找问题并解决。
30 8255可编程并行接口实验 实验4-1七段数码管显示控制实验 实验目的:通过控制动态数码管显示方式的编程实验,学习和掌握8255并行接口的使 用原理。
实验设备:RPC-500工业控制计算机 1台 SXL-100微型计算机接口实验仪1台 实验内容:实验电路如图6-
1,图6-2所示。
实验仪的动态数码管显示原理:8255的
A 口通过74ALS240以输出方式输出段数据(输出1:段亮,输出0:段灭)。
8255的B口的PB0~ PB3设置为输出方式,分别控制4个数码管的公共端(0:数码管亮,1:数码管灭),从而 构成动态七段数码管显示器,每一位都可以显示数字0~
F。
实验题目是设计一个加法计数器,要求计数器能够完成0~9999的十进制加法的加
1 计数(计数到9999,计数器自动复位到0)。
使用实验仪的4位数码管显示器显示计数器从 0~9999的加1计数过程。
要求在主程序中有检测计算机键盘的功能,如果有键按下就中 止程序运行并退回操作系统。
程序分析:实验程序设置有一个计数变量,能做0~9999的十进制加法计数。
程序里 有4位动态数码管显示器显示子程序,计数器加1子程序,延时子程序,扫描计算机键盘子 程序等。
在主程序里调用这些子程序,完成实验题目的要求。
实验程序框图给出了实验程序 的结构。
实验仪地址译码电路分配给8255并行接口的控制寄存器和并行接口A口、B口的地址 是:控制寄存器地址是03H,并行接口A口的地址是00H,B口地址是01H。
实验程序需要首 先获得实验仪PCI卡提供的用户基地址,并将PCI卡用户基地址和实验仪的8255地址相加, 得到一个完整的地址。
实验仪数码管显示器的HEX码与七段码的对应关系由表6-1给出: 表6-1BCD码 012345 HEX码与七段码的对应关系 七段码 BCD码 0c0H
9 0f9H
A 0a4H
B 0b0H
C 99H
D 92H
E 七段码98H88H83H0c6H0a1H86H 31
6 82H
F 8eH
7 0f8H
8 80H 实验步骤:
(1)实验仪硬件电路连接。
实验仪电路板上数码管显示电路部分由G与B两部分电路 组成。
电路连接有短路块连接和跳线连接两种方式。
短路块连接为缺省方式,在本次实验中 使用短路块缺省连接方式,也就是在实验中不再做硬件电路的连接。

(2)编写实验程序或参考附录的实验参考程序。

(3)编辑和汇编实验程序。
如果有错误,则改正错误,重复汇编直到没有错误为止。

(4)运行实验程序。
如果运行程序时发现程序错误,使用调试程序调试程序,直到能够正确运行。

(5)观察实验仪上的数码管显示。
(8255)PA0(8255)PA1(8255)PA2(8255)PA3 (8255)PA4(8255)PA5(8255)PA6(8255)PA7 IC5 1A1 1Y1 1A2 1Y2 1A3 1Y3 1A4 1Y4 2A1 2Y1 2A2 2Y2 2A3 2Y3 2A4 2Y4 1G 2G 74ALS240 R×
8 ABCIC6ADIC6B EIC6CFIC6DGDP 七段数码管 PB3(8255)PB2(8255)PB1(8255)PB0(8255) 实验5-1数码管显示器驱动电路 32 gfba 109876109876109876109876 七段数码管 12345 12345 12345 12345 dpcde IC6A7407 IC6B7407 IC6C7407 IC6D7407 位驱动电路 (8255)PB3 (8255)PB2 (8255)PB1 (8255)PB0 图6-2七段数码管与位驱动电路 33 程序开始获取PCI卡配置资源计算实验仪8255芯片选通地址 设置8255芯片控制字 计数单元COUNT=10H 调用十进制加1子程序 YPC机键盘是否按下
N #调用显示子程序# #个位显示控制#取个位数并转换成显示段码,送8255PA口。
个位控制码送8255PB口,使个位数码管显示。
调用延时子程序,然后关个位数码管显示。
#十位显示控制#取十位数并转换成显示段码,送8255PA口。
十位控制码送8255PB口,使十位数码管显示。
调用延时子程序,然后关十位数码管显示。
#百位显示控制#取百位数并转换成显示段码,送8255PA口。
百位控制码送8255PB口,使百位数码管显示。
调用延时子程序,然后关百位数码管显示。
#千位显示控制#取千位数并转换成显示段码,送8255PA口。
千位控制码送8255PB口,使千位数码管显示。
调用延时子程序,然后关千位数码管显示。
NCOUNT-1=0?
Y 图6-3实验参考程序框图 34 退出实验程序 实验4-24*4十六进制数键盘控制实验 实验目的:通过学习使用8255可编程并行口芯片,掌握扫描式键盘的工作原理。
学习扫 描式键盘输入的编程方法 实验设备:RPC-500工业控制计算机 1台 SXL-100微型计算机接口实验仪1台 实验内容:扫描式4×4键盘的原理见图4-2-
1。
键盘的8根端口线连接到可编程并行 口芯片8255的PC口。
其中PC0–PC3设置为输入线,连接到横向扫描线上,PC4--PC 7设置为输出线,连接到纵向扫描线上(由于键盘端口没有极性,可随意定义端口的输入, 输出)。
组成4×4的扫描式键盘。
图4-2-
1 实验题目:设计一个程序,能够对实验仪的4*4键盘进行扫描。
通过8255PC口读出的数据,确定按下的键和键值。
将按下的键所对应的数值显示到计算机屏幕上。
编程提示:可以参考实验参考程序框图。
键盘是按矩阵方式排列,键盘的输入端口输入扫描码,在键盘的输出断口读到输出值。
将这两个值组合,通过查表方法确定按下的键所对应的数值。
35 键扫描框图如下: 扫描值=10H 输出扫描值到8255C口从8255C口读入键位值 扫描值左移1位
N 扫描值=1Y 键值=0FFFH 键位值>0查表获取键值 返回 36
四、实验参考程序框图提示 初始化8255的C口,PC4~PC7为输出,PC0~PC3为输入键缓冲值=0FFH键扫描 键值!=键缓冲值AND键值!=0FFH键缓冲值=键值显示键值 延时PC键按下 退出 37 附录1PWB开发环境使用方法 MASM6宏汇编语言同以前的宏汇编语言不同,MASM6宏汇编语言包里提供了一个开发环境,将源程序的编辑,汇编,连接和调试集成到一个界面里,使用非常方便。
MASM6宏汇编语言一个开发环境名为PWB,在安装了MASM6以后,计算机的桌面窗口上会出现一个名为PWB的图标,双击该图标就可以运行MASM6宏汇编语言的开发环境。
PWB开发环境以菜单的形式提供开发过程中的各步骤的命令选项。
(一)使用PWB开发汇编程序的步骤
(1)编辑源程序。
进入PWB界面以后,出现的是菜单栏和文本编辑器,菜单栏中的文件,编辑,搜索3个菜单主要服务于PWB的文本编辑器。
通过这3个菜单命令可以完成源程序文件的文本编辑工作。
汇编源程序的文件扩展名应取为.asm,即汇编源程序的文件名是*.asm。
“*”为文件名,“.asm”是文件扩展名。

(2)建立工程项目。
使用Project菜单里的NewProject命令选项可以建立工程。
在使用多模块文件方法编写程序的时候,需要建立工程以便编译源程序。
执行NewProject命令后会打开一个对话框,在对话框里输入工程名,选择“OK”以后进入另一个对话框,在这个对话框里将要加入工程的汇编文件加入工程,然后选择“SaveList”。
工程项目建立以后就可以工程为单位进行编译。
使用OpenProject命令选项可以打开已经存在的工程文件。
使用EditProject命令选项可以编辑已经存在的工程文件。

(3)汇编源程序(.ASM文件)。
使用Project菜单里的CompileFile命令选项汇编源程序以生成目标程序。
汇编源程序分为单模块程序的汇编和多模块程序的汇编。
单模块程序汇编可以不用建立工程,直接使用CompileFile命令选项生成目标程序。
如果是多模块程序,可以使用CompileFile命令选项将每一个模块都单独汇编成目标程序,然后再将模块程序加入工程。
也可以先建立工程,将模块程序加入工程后使用Build命令选项自动生成可执行程序(汇编和连接一次完成)。
源程序在汇编过程中通常会产生语法错误,使用编辑器改正语法错误后再进行汇编,直到没有语法错误为止。

(4)连接目标程序(.OBJ文件)。
分为单模块程序的连接和多模块程序的连接。
对于单模块程序连接,直接使用Build命令选项连接生成目标程序。
对于多模块程序连接,可以先将各个模块单独汇编然后加入工程,再用Build命令选项连接生成目标程序。
也可以先将各个模块加入工程,然后将各个模块单独汇编以后再用Build命令选项连接生成目标程序。
连接过程有时会产生连接错误。
连接错误有时是程序语法错误引起,有时是程序结构错误引起。

(5)执行可执行程序(.EXE文件)。
使用Run菜单的Execute命令选项可以运行程序并在PWB的输出窗口看到输出结果。
在正确连接目标程序以后PWB会给出对话框,使用对话框给出的命令按钮,也可以直接执行程序。

(6)调式可执行程序(.EXE文件)。
在开发环境PWB的Run菜单里用Debug命令选项可以进入CodeView调式器,使用CodeView调式器提供的各种调式功能对程序进行调式。
通常在调式程序的过程中会发现程序设计时的逻辑错误。
当程序不能按设计要求输出正确结果的时候,就要用调式器分析程序的运行情况,找出错误的原因。
(二)PWB开发环境选项设置在使用PWB开发环境以前要进行选项设置。
一般是在安装宏汇编器的时候进行选项设置,设置只要进行1次即可。
选项设置是通过Options菜单提供的命令选项进行。

(1)在Options菜单里使用Build命令,在对话框里选择:()UseDebugOptions 38 然后选

(2)在Options菜单里使用LanguageOptions命令,继续单击“MASMOptions”,然后在 出现的对话框里按如下要求进行设置: 在CaseSensitivity选择框里选中:()PreserveCaseofNamesinobjectFile 在对话框里选中:[]WarningsTreatedasErrors []MASM5.1Compatibility 在WarnLevel选择框里选中:()Level2 然后单击进入另一个对话框,按如下要求进行设置: 在Listing选择框里选择除“[]IncludeAllSourceLine”以外的所有选项。
在DebugInformation选择框里选中:()CodeView 然后选,回到上一个对话框再继续选

(3)在Options菜单里的BrowseOptions命令选项对话框里选中前4个选项: []GenerateBrowseInformation []ExcludeMacroExpandedSymbols []ExcludeSystemIncludeFiles []IncludeUnreferencedSymbols 然后选

(4)在Options菜单里的LINKOptions命令选项的对话框里选择: 在GlobalOptions选择框里选中:[]StackSize[ ]bytes 在对话框中间的选择框里选中:()DebugOptions 然后选
(三)除了PWB的开发环境选项设置以外,还有两个文件需要改动,这两个文件的改动在安装宏汇编器的时候只需要进行一次:
(1)按MASM的安装路径,进入BINR子目录可以看到一个名为“NEW-VARS”的批处理文件,这个文件提供了MASM在计算机里的运行环境。
需要将这个文件加入C盘根目录下的EXECAUTO.BAT文件里。
在C盘根目录下打开EXECAUTO.BAT文件,加入下面的内容: X:\MASM611\BINR\NEW-VARS.BAT上面的“X”是安装宏汇编器的磁盘盘符,“\MASM611\BINR\”是存放NEW-VARS.BAT文件的路径。
这样,在WIN98启动时自动建立MASM的运行环境。

(2)按MASM的安装路径,进入INIT子目录,在这个子目录下有一个名为“TOOLS.PRE”的文件,将这个文件的文件名改为“TOOLS.INI”。
39 附录2CodeView调试器使用方法 CodeView是一个源代码调试器,可在源代码级调试程序(包括高级语言程序)。
对于用汇编语言编写的程序,在汇编和连接时使用适当的选项参数,在调试器里可以看到完整的汇编语言源代码和注解,并可以按源语句行跟踪调试程序。
CodeView调试器提供了全屏幕的调试界面,使用下拉菜单和调试命令控制汇编语言或高级语言的调试过程。
在使用PWB编辑器编辑汇编源程序的时候,启动PWB程序同时也启动了CodeView调试器(需要在PWB中设置相关环境参数)。
但也可以单独启动CodeView调试器。
CodeView调试器的屏幕主要分为三个部分。
提供菜单命令的菜单条,显示要调试程序代码的显示窗口和在屏幕下面的命令对话窗口。
在CodeView调试器里可以使用热键来控制显示寄存器内容,单步执行程序等。
标志寄存器的值显示在寄存器列表的下面。
在标志寄存器值的下面一块区域显示当前指令使用的内存单元内容。
在屏幕底部对话窗口中,用户可以用命令控制调试过程。
用户程序的执行结果在CodeView的输出屏幕显示。
这是因为CodeView调试器有两个显示屏幕,一个用于显示用户程序,寄存器和存储器内容的屏幕(调试器启动时提供的屏幕)。
另一个是用于显示用户程序执行结果的屏幕,用F4键可以在两个屏幕之间进行切换。
退出CodeView调试器并返回PWB编辑器,可以使用File菜单命令,也可以在对话窗口中输入q命令并执行。
CodeView的File,Edit,Seatch菜单命令的用法同一般视窗的相同菜单的用法基本相同。
在调试程序期间,可以使用CodeView提供的各种命令调式程序。
使用Data菜单的AddWatch...命令选项加入观察变量,在程序调试过程中观察某些变量或某些表达式的值。
选择AddWatch...命令选项的时候,会出现一个对话框。
在对话框中要求输入观察变量的表达式。
表达式可以是一个变量名或一个简单表达式,表达式可以包含程序中使用的变量和寄存器。
填加观察变量以后,进入调试状态后,在CodeView的调试屏幕上面出现一个小窗口。
在程序调试过程中,这个窗口会显示要观察的变量或表达式的值。
可以设置多个观察变量表达式。
DeleteWatch...命令选项用来删除一个观察变量或观察表达式。
CodeView在缺省情况下以十进制形式显示观察表达式的值(在Watch窗口)。
如果要以16进制形式显示观察表达式的值,应在命令窗口中输入“16”命令。
CodeView观察窗口按16进制形式显示内容时,在数值前面加有前缀Ox,用以表示数值是16进制数。
使用Data菜单的SetBreakpoint命令选项在程序调试前或程序调试过程中设置程序断点,当程序运行到程序断点时自动停止程序运行,以便观察程序断点处的程序运行结果(用户程序涉及到的寄存器、存储器的值和进入程序分支的运行情况等当前状态)。
在汇编语言中,断点实际是一条指令的第一个操作码的地址。
有两种设置程序断点的方法,一是使用Data菜单命令中的Setbreackpoint命令选项,二是使用F9键。
在设置断点之前,将光标移到源程序显示窗口,然后将光标放置在需要设置断点的源程序行上,执行Setbreackpoint命令选项或按下F9键,断点即被设置在该行。
设置完断点以后,断点所在的程序行变成高亮度显示。
可以设置多个程序断点。
编辑和清除程序断点可以使用Data菜单命令中的Editbreackpoint命令选项。
使用F9键清除程序断点,可以将光标放置在要清除的程序断点处然后按下F9键,即可清除该处的断点。
可以选择连续,单步或跟踪方式执行程序。
使用Run菜单的Restart命令选项复位CPU,使用Animate命令选项慢速执行程序。
可以使用F5,F7,F8,F10键执行程序。
40 F5键和F7键是连续执行程序命令键。
使用F5键可以连续执行程序。
如果程序里设置了断点,那么程序执行到断点时,在CodeView屏幕中会显示出要观察的变量表达式的值。
如果没有设置程序断点,则被调试的程序会一直执行到程序的结束。
使用F7键可以连续执行程序直到当前光标所在程序行。
这种方法可以使程序执行到一个光标指定的指令处。
使用这种方法要先用箭头键或鼠标将光标放置在指定的指令上,然后按下F7键,此时程序会进入连续执行并一直执行到当前光标处,然后停止程序指令的执行。
F8键是跟踪执行命令键,F10键是单步执行命令键。
使用F8,F10键可以跟踪或单步执行程序,在执行程序的过程中观察寄存器和变量值的变化。
单步执行程序和跟踪执行程序是不同的概念。
单步执行程序遇到CALL指令,LOOP循环,中断调用指令(INTXX)时将CALL指令,LOOP循环,中断调用指令作为一条指令,一次连续执行完然后直接执行下一条指令。
跟踪执行程序是遇到CALL指令,LOOP循环,中断调用指令时,进入子程序,循环体内和中断服务程序内继续单步执行程序指令直到遇到子程序返回指令或循环体执行完。
使用跟踪执行程序的方法执行中断调用指令是危险的,特别是系统的中断调用。
因为中断调用(INTXX)指令的执行结果是不确定的,因此在调试程序时,执行中断调用指令必须使用连续执行程序方法或单步执行程序方法,而不能使用跟踪执行程序方法。
如果能够确认被调用的子程序或LOOP循环过程是正确的,可以不用跟踪调试子程序和循环过程里的指令,而使用F10键调试程序。
使用Windows菜单中的Close命令选项可以关闭当前打开的窗口,使用Tile,Arrange命令选项可以排列当前打开的窗口位置。
Windows菜单中的Help到Command之间的命令选项可以打开相应的窗口。
其中,Watch是观察窗口,Source是源代码窗口(程序窗口),Memory是存储器窗口,Register是寄存器窗口。
使用Options菜单中的Source1Windows...命令选项可以设置源代码窗口显示方式,可以只显示反汇编以后的源程序,也可以将机器码程序和源程序一起显示等。
Memory1Windows...命令选项可以选择存储器窗口显示的内存范围,使用DS:SI,DS:DI,SS:SP,DS:0x0000等参数给出所要显示的内存范围的起始地址。
TraceSpeed命令选项给出使用Run->Animate命令执行指令的速度(高,中,低)。
使用CodeView调试器调试程序的步骤:
(1)进入调试器可以在PWB的DEBUG菜单进入CodeView调试器,也可以在计算机的屏幕窗口中双击CodeView调试器的图标进入CodeView调试器。

(2)使用文件菜单命令选项装入等待调试的可执行程序(.EXE程序)。
打开需要使用的窗口(如寄存器窗口,存储器窗口等,并设置好相应窗口的参数)。
如果需要,设置观察变量和程序断点。
选择运行程序的方式(连续,单步,跟踪)。

(3)运行程序,通过各个窗口观察程序运行情况。
如果程序出项错误,需要分析错误的原因,然后回到PWB的编辑窗口改正程序错误,重新汇编连接程序并重新调式程序。
直到程序能够正确运行为止。
有关CodeView调试器的其它功能的使用方法,可以参考有关资料也可以在实践中探索。
41 附录3汇编语言程序开发步骤 设计和开发汇编语言程序,通常包括以下几个步骤: 1使用文本编辑软件编辑汇编语言源程序文本编辑软件(又称文本编辑器)提供文本的编辑环境,有多种文本编辑器可供使用,但现在常用的是可以在DOS操作系统支持下运行的EDIT编辑器和在WINDOWS操作系统支持下运行的记事本编辑器。
由于宏汇编语言程序提供多模块程序的编程方式,因此完整的汇编语言源程序,可以是单模块的程序结构.也可以是多模块的程序结构。
在编辑汇编语言源程序的时候,每个程序模块都是单独的汇编语言源程序文件,文件的扩展名必须是.ASM。
在宏汇编语言程序里,文件扩展名为.ASM的文件就是汇编语言源程序文件。
单模块的汇编语言源程序对应一个汇编语言源程序文件,而多模块的汇编语言源程序对应多个汇编语言源程序文件。
由于宏汇编语言程序只能在DOS操作系统(或WINDOWS操作系统的DOS窗口)的支持下运行,因此实验里使用EDIT编辑器编辑汇编语言源程序。

2.使用宏汇编器MASM对汇编语言源程序进行汇编对编辑好的,由一个或多个模块文件组成的汇编语言源程序,使用宏汇编器MASM对每个模块文件单独进行汇编并且生成目标文件(文件后缀名.OBJ)。
如果汇编语言源程序里存在语法错误,宏汇编器MASM在汇编过程中会检查出语法错误并显示错误信息。
对语法错误的处理方法是使用文本编辑器,再次编辑出现错误信息的汇编语言源程序模块,根据语法错误信息修改有语法错误的语句。
重新汇编,直到没有语法错误为止。
在进行宏汇编时,每一个汇编语言源程序模块(汇编语言源程序文件)都要独立生成目标文件。
在宏汇编的过程中,还可以生成列表文件(文件后缀名.LST)和交叉引用文件(文件后缀名.CRF)。
列表文件提供汇编过程中生成的的所有汇编信息,交叉引用文件提供调试时使用的信息。

3.使用连接程序LINK对目标文件进行连接在汇编阶段生成的目标文件需要使用连接程序LINK(目标程序连接器)生成可执行文件(文件后缀名.EXE)。
通常,可执行文件的生成过程中除了需要目标文件以外,有时可能还需要库文件(文件后缀名.LIB)。
在目标程序的连接过程中,如果出现错误,错误信息会显示在计算机屏幕上,这时就要对汇编语言源程序重新进行编辑、修改错误,然后再次进行程序的汇编和连接,直到没有错误,正确生成可执行文件。
在目标程序连接过程中,可以选择是否生成内存映像文件(文件后缀名.MAP),内存映像文件是在程序调试时使用。

4.使用调试程序调试可执行程序有多种调试工具(CODEVIEW软件,DEBUG软件等)提供的调试环境可以对可执行程序进行调试。
对于一个程序设计项目,要使程序能够正确运行就必须对程序进行调试,程序调试阶段可以发现程序设计阶段对程序处理问题的方案是否完善,程序是否存在逻辑结构错误等。
如果设计方案不完善或程序逻辑结构不正确,不能满足设计要求就必须对程序重新进行设计和修改逻辑错误,然后重新编辑、汇编、连接和调试,直到满足设计要求为止。
程序里的错误一般有两种:语法错误和逻辑错误。
语法错误在汇编的过程中就可以发现,修改语法错误的方法是对照指令表和宏汇编语言的规则,用正确的语法规则书写程序指令,伪指令和程序语法结构。
而逻辑错误就比较复杂,逻辑错误一般来源于对所设计的项目的理解,建立的模型和算法,程序设计中所需要的某些控制条件不正确以及在程序里的数据、参数传递不正确和程序流程结构错误。
在调试程序的过程中为了发现错误,一般要求根据所设计的项目、程序和程序将要运行的环境有所了解并且建立程序调试运行过程中的测试数据、条件等。
建立合理的测试数据和 42 测试条件是非常重要的工作,常常决定了程序调试的成功和失败。
文本编辑器EDIT的使用方法 EDIT编辑器是一个捆绑在MS-DOS操作系统或WINDOWS操作系统里的全屏幕文本编辑器。
EDIT编辑器在MS-DOS操作系统(或WINDOWS操作系统的DOS窗口)的任何子目录下都可以直接启动。
下面是启动EDIT编辑器的方法: C:\MASM\EDITfilename C:为盘符,\MASM\是路径,EDIT是编辑器文件名,filename是启动编辑器时带的参数,指明需要编辑的文件的文件名。
在启动编辑器时带有参数则同时装入这个需要编辑的文本文件。
如果启动编辑器时不带文件名参数,可以使用编辑器的文件菜单命令装入需要编辑的文件。
下面简单介绍EDIT编辑器的使用方法。
EDIT编辑器是由菜单栏,文本编辑区和状态栏组成。
菜单栏给出编辑器的主要命令,状态栏显示当前工作状态和命令提示以及文本编辑区光标位置。
菜单栏里的菜单命令及简要说明见表
1,DEIT编辑器的键盘命令简要说明见表
2。
在编写汇编语言源程序时,有几点需要注意:
(1)汇编语言源程序通常是多程序模块的结构,每个程序模块都是一个汇编语言源程序文件。
每一个文件里都包含有伪指令,汇编语言指令和注释内容。

(2)汇编语言源程序文件的文件扩展名必须是.ASM。

(3)汇编语言源程序文件每一行书写一条语句,同一行语句的格式是: 标号: 指令助记符 操作数 ;注释 从左到右分别是标号或标识符字段,伪指令或指令助记符字段,操作数字段,注释字段。
不同行的语句中相同字段应按列对齐。

(4)汇编语言源程序文件的结构分为数据段
1,数据段
2,…,堆栈段,代码段。
表1命令名 EDIT编辑器的菜单命令简要说明 File(文件菜单) 快捷键 简要说明 命令名 Edit(编辑菜单) 快捷键 简要说明 New 建立一个新的文件 Open 打开一个文件 Save 存储当前文件 SaveAs… 另存为… Close 关闭当前文件 Print 打印 Exit 退出编辑器 Searce(搜索菜单) 命令名 快捷键简要说明 CutCopyPasteClear Ctrl+XCtrl+CCtrl+VDel 剪切操作拷贝操作粘帖操作删除操作 命令名 View(观察菜单) 快捷键 简要说明 Find…RepeatLastFindF3Replace… 寻找操作重复寻找替换操作 SplitWindowSizeWindowCloseWindow1untitled1 Ctrl+F6Ctrl+F8Ctrl+F4Alt+
1 分割窗口调整窗口尺寸关闭窗口当前已经装入编辑器 43 命令名 Settings…Colors… Options…选项菜单 快捷 简要说明 键 设置制表键 设置编辑环境颜色 2filename13filename2 命令名 Alt+2的文件,用Atl+i选择, Alt+3i=1,
2,… Help帮助菜单 快捷键 简要说明 Commands….About 命令说明EDIT编辑器版本说明 表
2 HomeEndUpDownPgUpPgDnCtrl+PaUpCtrl+PaDnCtrl+HomeCtrl+EndCtrl+LeftCtrl+Right EnterDelecteBackspaceTabInsertCtrl+YCtrl+VCtrl+
P ShiftCtrl+CCtrl+XDelete Ctrl+Q+FCtrl+Q+AF3 F6F8Ctrl+F6 EDIT编辑器键盘命令光标移动命令 移动到当前行的起始位置移动到当前行的结束位置向上滚动一行向下滚动一行滚动到当前屏幕的上边滚动到当前屏幕的下边滚动到当前屏幕的左边滚动到当前屏幕的右边滚动到当前文档的起始位置滚动到当前文档的结束位置向左移动一个单词向右移动一个单词 编辑命令开始新的一行删除当前光标处的字符删除当前光标左边的字符移动光标到下一个制表位在插入和改写模式之间切换删除当前行粘贴缓冲器内容到文件允许插入特殊字符 工作区选择命令使用Shift键关联当前光标,以实现区域选择功能把当前选择的区域内容拷贝到缓冲区删除当前选择的区域内容并把当前选择的区域内容拷贝到缓冲区删除当前选择的区域内容 寻找和替换文本命令寻找文本命令寻找文本并替换它重复寻找下一个 窗口管理命令切换到下一个编辑窗口切换到下一个正在工作的文件打开第二个编辑窗口 44 Ctrl+F4Ctrl+F8 F1 关闭第二个编辑窗口调整编辑窗口 其它命令打开帮助窗口 宏汇编软件包使用方法 (一)宏汇编器MASM5.0的使用方法 宏汇编器MASM5的功能是把用x86系列的微处理器的汇编语言程序汇编成可重定位 的目标代码程序。
MASM5宏汇编器以软件包的形式存放在计算机磁盘里。
不同版本的软件 包,包含的文件不同。
MASMV5.0版本以前的软件包使用方法基本一样,而MASMV6.0 以后版本的软件包提供了集成开发环境PWB,并且将CodeView调试器集成在开发环境里。
在集成开发环境中,可以进行汇编语言程序的文本编辑,汇编,连接和调试。
首先介绍MASMV5.0的使用方法。
假设MASMV5.0软件包存放在C盘的C:\MASM50\ 子目录下。
在DOS操作系统下,用下面的方法启动MASM程序: C:\>CD\MASM50 按回车键,进入MASM50子目录 C:\MASM50>MASMfilename 按回车键,执行MASM程序 在命令中,MASM是宏汇编器名,filename是等待汇编的汇编语言源程序文件名。
设ex1.asm 是汇编语言源程序文件名,执行以下命令: C:\MASM50>MASMex1.asm 在屏幕上出现以下信息: Microsoft(R)MacroAssemblerVersion5.00Copyright(C)MicrosoftCorp1981-1985,1987.Allrightsreserved. Objectfilename[ex1.OBJ]:Sourcelisting[NUL.LST]:ex1Cross-reference[NUL.CRF]: 按回车键输入EX1文件名,要求生成列表文件按回车键,不要求生成交叉引用文件 48918+433354Bytessymbolspacefree0WarningErrors0SeversErrors 提示信息“Objectfilename[ex1.OBJ]:”表示生成的目标文件名为EX1.OBJ。
如果要修改目标文件名,可以在后面输入新的文件名。
提示信息“Sourcelisting[NUL.LST]:”表示是否生成列表文件,如果需要列表文件,可以在出现提示的时候输入文件名。
提示信息Cross-reference[NUL.CRF]:表示是否生成交叉引用文件,如果需要交叉引用文件,可以在出现提示的时候输入文件名。
在提示信息里的NUL是空文件名,表示不生成相应的文件。
如果在前面的提示信息处输入文件名并在文件名的后面紧跟分号“;”,那么后面的提示信息将不再出现,而直接显示汇编信息。
后面的三行是汇编后产生的汇编信息,这三行中的第一行表示剩余的符号空间数量,在“+”号前面的数值表示剩余的NEAR符号空间,在“+”后面的数值表示剩余的FAR符号 45 空间,两个数值表明了汇编时内存空间使用状况。
第二行表示在汇编时产生的警告错误信息的数量,第三行表示在汇编时产生的严重错误信息的数量。
列表文件里包含了汇编中产生的全部信息(其中包括错误的类型和错误出现的位置),在汇编以后如果发现有语法错误,需要从这个文件里找出错误原因。
如果错误信息都是
0,表示汇编已经正确完成,可以进行下一步的工作。
汇编的时候产生的错误信息内容在附录中给出。
如果执行了不带文件名参数的命令:C:\MASM50>MASM会在屏幕上显示以下信息: Microsoft(R)MacroAssemblerVersion5.00Copyright(C)MicrosoftCorp1981-1985,1987.Allrightsreserved. Sourcefilename[.ASM]:ex1Objectfilename[ex1.OBJ]:Sourcelisting[NUL.LST]:ex1Cross-reference[NUL.CRF]: 输入汇编语言源程序名,按回车键按回车键,不改变目标程序文件名输入EX1文件名,要求生成列表文件按回车键,不要求生成交叉引用文件 48918+433354Bytessymbolspacefree0WarningErrors0SeversErrors 上面第一个提示信息“Sourcefilename[.ASM]:”要求输入汇编语言源程序名,这是因为在启动MASM程序的时候没有带文件名参数。
宏汇编器生成的文件是文件扩展名为.OBJ的目标文件,当目标文件正确生成后就可以进行目标文件的连接。
(二)目标程序连接器LINK的使用方法用户的汇编语言源程序,不论是单模块还是多模块的程序文件,在用宏汇编器汇编以后生成的目标程序都是代码可浮动的二进制目标程序文件,这种程序文件不能在计算机上运行。
如果要生成在计算机上能够运行的可执行文件,就需要用连接程序LINK将目标程序文件连接成可执行程序文件。
连接程序LINK的功能是将一个或多个模块程序(扩展名为.OBJ)和库文件(扩展名为.LIB)连接装配成可以重新定位的可执行程序文件(扩展名为.EXE)。
库文件里的内容通常是经常使用的子程序等公共程序。
将在程序里经常使用的公共程序编译成库文件,可以减少编写程序的工作量。
LINK程序要在DOS操作系统的支持下运行。
在DOS操作系统环境下,输入以下命令并执行(假设有EX.OBJ,EX2.OBJ,EX3.OBJ目标程序):C:\MASM50\LINKEX1.OBJ+EX2.OBJ+EX3.OBJ程序执行以后屏幕显示: Microsoft(R)OverlayLinkerVersion3.65Copyright(C)MicrosoftCorp1983-1988.Allrightsreserved. RunFile[EX1.EXE]: 按回车键,不修改可执行程序文件名 46 ListFile[NUL.MAP]:Libraries[.LIB]: 按回车键,不生成内存映像文件(扩展名.MAP)按回车键,不连接库文件 C:\MASM50\ 如果要更改可执行程序文件名以及需要内存映像文件,在提示信息的后面输入需要的文件名。
到此时,可执行程序文件即已经生成,直接在DOS操作系统提示符后输入可执行程序文件名(可以不加扩展名),按回车键就可以运行可执行程序文件。
如果是单模块的目标程序文件,在LINK命令后将模块文件名作为命令参数写上。
如果是多模块目标程序文件,在LINK命令后,将每个模块名用“+”连接起来,写在命令参数里。
如果在运行连接程序LINK的时候不带参数,则要求在提示信息的提示下输入目标程序名。
由于在汇编源程序的编写和汇编过程中,一些不确定性的原因可能会导致目标程序在连接过程中产生错误。
应根据产生的错误信息,寻找产生错误的原因,然后修正错误,重新汇编、连接,直到正确生成可执行程序。
(三)DEBUG调试器的使用方法DEBUG程序运行以后在计算机上形成一个调试程序运行的环境,在这个环境里可以使用DEBUG提供的各种调试命令完成程序调试工作。
DEBUG的命令分为文件操作命令,查看和修改寄存器命令,查看和修改内存命令,连续和带断点运行程序命令以及单步和跟踪运行程序命令等。
DEBUG程序的命令是以一个字母开头,后面带有一个或多个参数。
命令和参数之间,参数和参数之间用空格或逗号隔开。
按下回车键,计算机执行命令。
如果命令执行后显示^Error,表示命令执行过程出现错误,“^”指示出现错误的地方。
要对程序进行调试,需要将被调试的文件装入计算机内存。
有两种方法加载程序文件:
(1)用带文件参数的DEBUG命令装载文件,命令格式为:格式:DEBUGfilename命令中的filename是被调试的可执行程序文件名。
DEBUG程序在运行的时候将可执行程序文件装入内存。

(2)使用
N,L命令装载可执行程序文件,命令格式为:格式:Nfilenamefilename参数是将要装载或存储到磁盘的文件的文件名。
N命令并没有真实的将文件装载或存储到计算机上,而是告诉计算机要对这个文件进行处理。
格式:L[addr]命令参数addr表示装入文件的起始地址,忽略这个参数,则默认文件的装入地址为CS:0100。
在BX:CX里存放的是读入文件的字节数。
L命令将文件名参数filename指定的文件装入内存。
L命令是真实的将文件装载或存储到计算机上。
例:设有一个可执行程序文件,文件名为EX1.EXE,将这个文件装入内存进行调试。
假设宏汇编语言软件包存放在C:\MASM50子目录下。
方法
1,启动DEBUG程序的时候,将文件装入内存,执行下面的命令:C:\MASM50\DEBUGEX1.EXE 命令执行后在屏幕上显示“-”,表示已经进入到DEBUG的调试环境。
EX1.EXE文件已经装入到内存的调试环境之中。
47 方法
2,先启动DEBUG程序,执行以下的命令:C:\MASM50\DEBUG进入到DEBUG的调试环境,再执行以下的两个命令:-NEX1.EXE-L两个命令都被执行后计算机进入DEBUG的调试环境而且EX1.EXE文件被装入内存的调试环境里。
对于可执行程序.EXE,在装入内存以后计算机中的CPU寄存器被初始化。
标志寄存器的各位被复位。
CS:IP给出了程序运行的入口地址,其中CS是代码段的段基地址,IP是可执行的第一条指令的偏移地址。
SS是程序定义的堆栈段的段基地址,SP是堆栈指针,SS:SP指向堆栈栈底地址+2的地址处。
程序的段前缀PSP的段基地址装入DS、ES。
下面依次介绍DEBUG里使用的命令。
查看和修改寄存器命令R在程序调试过程中需要查看和修改寄存器的内容。
查看和修改寄存器的内容使用R命令,使用R命令可以查看全部寄存器,查看和修改指定寄存器内容,查看和修改标志寄存器内容。
命令格式如下:格式1:R例:执行下面命令,屏幕显示: -
R AX=0000BX=0000CX=0000DX=0000SP=FFEEBP=0000SI=0000 DI=0000 DS=0AEFES=0AEFSS=0AEFCS=0AEFIP=0100NVUPEIPLNZNAPONC 0AEF:01008B0EE199 MOVCX,[99E1] DS:99E1=0000 在显示内容里,第一行通用显示寄存器内容,第二行显示段寄存器内容和标志寄存器内容, 第三行显示当前CS:IP寄存器指定的指令反汇编内容。
从左到右分别是地址,机器码指令,汇编指令,而DS:99E1=0000表示是在指令中涉及的间接寻址单元里的内容。
格式2:R[registername]其中registername是AX,BX,……等寄存器名。
例:执行下面命令显示AX寄存器的内容并修改寄存器内容,屏幕显示: -RAX -AX0000:1234 在“:”的后面输入新的数值1234H,按回车键,新的数值被送入AX寄存器。
再次执行R命令: -RAX -AX1234: - 48 格式3:RFRF命令用来显示标志寄存器的内容,各个标志位状态的含义如下: 标志位溢出位OF方向位DF中断位IF符号位SF零值位ZF辅助进位位AF奇偶位PF进位位CF 置位 复位 OV NV DN UP EI DI NG PL ZR NZ AC NC PE PO CY NC 例:执行下面命令显示F寄存器的内容并修改F寄存器内容,屏幕显示:-RFNVUPEIPLNZNAPONC显示的内容是当前F寄存器的各个标志状态。
如果要修改当前F寄存器内容,在“-”的后面写上要修改的标志的值(用符号表示)。
如:要将进位位改为置位状态,用下面的方法: -RFNVUPEIPLNZNAPONC-CY再次执行RF命令:-RFNVUPEIPLNZNAPOCY可以看到进位位已经改变。
查看内存内容命令D程序调试过程中经常需要查看内存内容。
查看内存内容使用D命令。
D命令格式如下:格式:D[range]range参数指定了要显示的内存范围。
范围参数有两种格式,分别是:
(1)Daddr1addr2addr1是准备显示的内存单元的首地址(段地址:偏移地址),addr2是末地址(偏移地址)。

(2)DaddrLValueaddr是所要显示的内存的首地址,L表示后面的参数是内存单元的字节长度数据,Value表示内存单元的字节数。
如果缺省LValue,则显示内容单元的内容是从DS:addr单元开始的128个字节内容。
如果缺省addrLValue,即不带参数的D命令,显示的内存内容将是从DS:0100开始的128个字节内容。
如果继续使用不带参数的D命令,则紧接上一次显示的内容的后面再显示128个字节的内容,依此类推。
例:使用D命令显示内存单元内容。
-D0AEF:01008B0EE1998B16DF99-8BC10BC27421B800............t!
..0AEF:011042CD2133C9B440CD-21803EE33400DE0AB.!
3..@.!
.>.4...0AEF:012041BAE399B440CD21-B43ECD21E96AFAB4A....@.!
.>.!
.j..0AEF:01303ECD21BABC98B441-CD21C606D19600E9>.!
....A.!
......0AEF:014057FAE9AEFE240C7A-10502408A2D49958W....$.z.P$....X 49 0AEF:01502404A2D8990806D2-99A0D8990AC0C3800AEF:01603EB798FF750CBFE1-94BDB798E81101E80AEF:017074E432C086061699-0AC07503E98C008B 继续使用D命令显示内容: -D0AFE:0180434649FEC48A073C-207401AA43E2BCC30AFE:0190F646040275438BD5-83C20557B8006CBB0AFE:01A0400033C98BF2BA01-01CD215F7315E88C0AFE:01B0DB3D020074233D03-00741E3D050074190AFE:01C0E9ABD88BD8B80044-CD21B43ECD21F6C20AFE:01D0807553F646040474-4D8B560580FA00740AFE:01E00580FE3A7402B240-80CA2080EA60E83C0AFE:01F0E47306E847DBE975-D88BD583C2058A7E 使用D[range]命令显示内容: -D1200:0100014F1200:01000000000000000000-00000000000000001200:01100000000000000000-00000000000000001200:01200000000000000000-00000000000000001200:01300000000000000000-00000000000000001200:01400000000000000000-0000000000000000 使用DrangeLValue命令显示内容: -D1234:0300L301234:03000000000000000000-00000000000000001234:03100000000000000000-00000000000000001234:03200000000000000000-0000000000000000 - $...............>...u...........t.2.......u..... CFI...._s....=..t#=..t.=..t........D.!
.>.!
...uS.F..tM.V....t...:t..@....`.<.s..G..u.......~ ................................................................................ ................................................ 修改内存单元命令E程序调试期间可以修改指定内存单元的内容,用来修改内存单元内容的命令是E命令,E命令的格式为:格式:Eaddr[1ist]addr是要修改的内存单元的首地址,参数List是可选项,是由替换数据(字节)组成的列表。
E命令有两种使用方法,不带List参数的E命令和带List参数的E命令。

(1)不带参数List的E命令在执行以后,给出要修改内容的内存单元起始地址,并等待键入新的数值。
在这种方式下用“spsce”空格键,“-”减号键,“Enter”回车键控制数据的输入,其中“spsce”空格键使当前内存地址加1并将数据存入内存,“-”减号键使当前内存地址减1并将数据存入内存,“Enter”回车键将数据存入内存并退出E命令。
如果没有输入数据而按下空格键和减号键,则当前地址单元的内容不变而单元地址加1或减
1。
如果没有输入数据而直接按下回车键,当前单元内容保持不变并结束E命令。

(2)带参数List的E命令在执行以后,将参数表里的字节数据依次存入addr地址指定的内存单元。
例:使用不带List的E命令修改内存单元内容。
执行以下命令: 50 -EDS:0100 0AEF:010012.3412.5612.7812.- 0AEF:010278.89 - 在显示的第一行里按空格键并输入数据,最后按减号键自动进入第二行,返回到前一地址单 元输入数据,然后按回车键结束E命令。
例:使用带列表参数的E命令修改内存单元内容。
执行以下命令: -EDS:01001234567890 - 使用D命令查看内存内容: -DDS:0100L0F 0AEF:0100123456789016DF99-8BC10BC27421B8 .4Vx........t!
. 填充内存单元命令F对指定的内存单元进行填充操作的命令
F,F命令的格式为:格式:Frangelistrange是地址范围,地址范围有两种表示形式,[addr1addr2]和[addr1LValue];list是字节数据列表。
在进行填入操作时,如果指定地址范围大于列表中的字节数,则反复使用字节列表 内容填充内存单元,直到指定内存单元填满。
如果指定地址范围小于列表中的字节数,则字 节列表中的多余内容将被略去。
例:将DS:0100单元到013F单元内容用列表内容填充。
-FDS:0100013F102030405060 显示相应单元内容: -DDS:0100013F0AEF:01001020304050601020-3040506010203040 .0@P`.0@P`.0@ 0AEF:01105060102030405060-1020304050601020P`.0@P`.0@P`. 0AEF:01203040506010203040-50601020304050600@P`.0@P`.0@P` 0AEF:01301020304050601020-3040506010203040.0@P`.0@P`.0@ 例:将DS:0200单元到0206单元内容用列表内容填充。
-FDS:0200L06010203040506070809显示相应单元内容:-DDS:0200L0F0AEF:02000102030405064F89-3ED596BBBA9780 ......O.>...... 输入和汇编指令命令A汇编命令A可以在DEBUG环境下输入汇编指令和修改.EXE程序,汇编命令的格式是:格式:A[addr]addr是输入存放汇编指令目标代码的起始地址,地址由代码段段地址和偏移地址(CS:IP)组成,不含段地址时,使用默认段地址。
使用A命令输入的汇编指令,会直接汇编成目标代码并存放在相应的内存单元中。
内存单元地址从起始地址开始自动依次排列。
使用A命令输入的汇编指令中除DB,DW伪指令以外,不能使用其它的所有伪指令和标号(转移标号, 51 符号变量,符号地址等)。
转移指令的目的操作数只能使用目的指令的偏移地址(16进制数)。
例:用A命令编写一段汇编程序,并存放在CS:0100开始的地址单元。
-ACS:01000AEF:0100MOVAX,00000AEF:0103MOVBX,00020AEF:0106MOVCX,00030AEF:0109- 当出现新的地址时,不输入汇编指令而直接按回车键,即可结束A命令。
反汇编命令U内存单元中的目标代码能够使用反汇编命令U反汇编成相对应的汇编指令。
调试程序的过程中使用反汇编命令U可以观察汇编指令在内存存放情况。
反汇编命令U的格式为:格式:U[range]range是地址范围,有两种表示形式,[addr1addr2]和[addr1LValue]。
U命令能够将命令的地址参数指出范围内的目标代码反汇编成汇编指令形式的程序并在屏幕上显示。
反汇编出的 指令格式按地址,目标代码和汇编指令的顺序显示。
第一次使用不带参数的U命令从默认的CS:0100地址开始反汇编32个字节的目标代码,当再次使用不带参数的U命令时,将从上次反汇编的目标代码后面再反汇编32个字节的目标代码,依此类推。
带地址参数的反汇编命令
U,会将地址范围内的目标代码全部反汇编成汇编指令格式。
如果屏幕显示满,会自动向上卷屏。
反汇编命令的一个特点是在给定的反汇编地址范围内的代码,不论是否是用户的目标代 码,都会反汇编成汇编指令,这就要求使用反汇编命令时给出合理的地址范围。
例:从当前默认地址处反汇编目标代码。
-
U 0AEF:01001234 ADC DH,[SI] 0AEF:010256 PUSHSI 0AEF:010307 POP ES 0AEF:01048B16DF99 MOV DX,[99DF] 0AEF:01088BC1 MOV AX,CX 0AEF:010A0BC2 OR AX,DX 0AEF:010C7421 JZ 012F 0AEF:010EB80042 MOV AX,4200 0AEF:0111CD21 INT 21 0AEF:011333C9 XOR CX,CX 0AEF:0115B440 MOV AH,40 0AEF:0117CD21 INT 21 0AEF:0119803EE33400CMP BYTEPTR[34E3],00 0AEF:011EDE0A FIMULWORDPTR[BP+SI] 例2:将给定地址范围内的目标代码反汇编成汇编指令。
-UCS:02000210 0AEF:020096 XCHGSI,AX 0AEF:0201F2 REPNZ 0AEF:0202AE SCASB 52 0AEF:020307 POP ES 0AEF:02047505 JNZ 020B 0AEF:02064F DEC DI 0AEF:0207893ED596 MOV [96D5],DI 0AEF:020BBBBA97 MOV BX,97BA 0AEF:020E803EC79600CMP BYTEPTR[96C7],00 调试运行程序命令
G,T,P在DEBUG调试程序里有3个命令可以用来运行程序,它们是连续运行程序命令
G,单步运行程序命令T和
P。
G命令可以连续运行程序直到程序结束或执行到一个有效的程序断点,T命令和P命令每次只运行一条指令或数条指令,然后显示指令运行完成后CPU各个寄存器的内容和下一条指令。

(1)连续运行程序命令G格式:G[=addr[,addr1[,addr2[,...]]]]G命令中的“=”后面的地址参数是程序起始地址,第一个逗号后面是断点列表,断点列表里面允许设置10个断点地址。
执行G命令是从起始地址处运行程序,命令中的“=”是区分起始地址与断点地址的标志。
如果G命令不指定起始地址参数,就从CS:IP指定的地址处执行程序。
如果G命令中有断点地址,则G命令连续运行到断点地址处停止程序的运行,然后显示断点处指令运行完成后CPU寄存器内容和要执行的下一条指令。
G命令允许设置10个断点地址,但每次执行带断点G命令的时候,断点列表中只有一个断点被执行。
当需要继续运行程序并需要使用断点时,应该在G命令中再次指定断点地址。
当屏幕显示“Programterminatednormall”信息时,表明程序运行结束。
在程序里设置程序断点的目的是为了测试程序的运行情况,如程序的分支情况,循环程序能否正确退出等。

(2)跟踪运行程序命令T格式:T[=addr][value]T命令是跟踪执行程序命令,每次执行一条或数条指令,然后显示CPU寄存器的内容和要执行的下一条指令。
T命令中的参数“=addr”是程序运行起始地址。
如果T命令中不指定地址参数则以CS:IP的内容为起始地址参数。
参数“value"是T命令要执行的指令条数(用16进制数表示),如果命令里不指定“value"参数,则默认值为
1。
T命令用来踪程序指令的运行过程。
当程序运行到CALL,LOOP和INTn指令时,会进入子程序,LOOP循环或INTn中断程序跟踪运行。

(3)单步运行程序命令P格式:P[=dddr][value]P命令是单步执行程序命令,每次执行一条或数条指令,然后显示CPU寄存器内容和要执行的下一条指令。
P命令中的参数“=addr”是程序运行起始地址。
如果P命令中不指定地址参数则以CS:IP的内容为起始地址参数。
参数“value"是P命令要执行的指令条数(用16进制数表示),如果命令里不指定“value"参数,则默认值为
1。
P命令不同于T命令。
P命令在单步运行时遇到CALL,LOOP和INTn指令的时候,将一次执行完子程序,循环体或INTn的中断程序,再显示CPU寄存器中的内容和下一条要执行的指令。
T命令和P命令的区别,T命令是按CS:IP指定的指令序列执行指令,P命令是按程序指令序列执行指令。
53 例:设有一个可执行程序S0.EXE,在DEBUG环境下带断点连续执行程序。
-G=CS:0000ShiYANChengXvProgramterminatednormally在上面的显示中,“ShiYANChengXv”是程序运行时输出的结果,提示信息“Programterminatednormally”表示程序正常结束。
例:使用带断点的G命令执行S0.EXE程序。
-g=cs:0,08 AX=0B02BX=0000DS=0B47ES=0B370B4B:000802060100-g0c CX=0067SS=0B49 ADD DX=0000SP=0020CS=0B4BIP=0008 AL,[0001] BP=0000SI=0000DI=0000NVUPEIPLNZNAPONC DS:0001=03 AX=0B05BX=0000DS=0B47ES=0B370B4B:000CA20200-g,15 CX=0067DX=0000SP=0020SS=0B49CS=0B4BIP=000C MOV[0002],AL BP=0000SI=0000DI=0000NVUPEIPLNZNAPENC DS:0002=00 AX=0B10BX=0000DS=0B47ES=0B370B4B:0015FEC0-g23ShiYANChengXvAX=0924BX=0000DS=0B47ES=0B370B4B:0023B44C-g27 CX=0003SS=0B49 INC DX=0000CS=0B4B AL SP=0020IP=0015 CX=0000DX=0007SP=0020SS=0B49CS=0B4BIP=0023 MOVAH,4C BP=0000SI=0000DI=0000NVUPEIPLNZNAPENC BP=0000SI=0000DI=0000NVUPEIPLNZNAPONC Programterminatednormally 例题说明:
(1)命令g=cs:0,08给出了起始地址“=cs:0”和断点地址“08”。

(2)命令g0c里没有直接给出执行地址,而是使用当前CS:IP地址,即0B4B:0008。
“0c”是断点地址。

(3)命令g,15同
(2)
只有一个断点参数,逗号可以省略。
例:设有一个可执行程序S0.EXE,在DEBUG环境下用跟踪命令执行程序。
-t=cs:
0 AX=0B47DI=0000 DS=0B37 BX=0000CX=0067DX=0000SP=0020BP=0000SI=0000ES=0B37SS=0B49CS=0B4BIP=0003NVUPEIPLNZNAPONC 54 0B4B:00038ED8-t MOVDS,AX AX=0B47BX=0000CX=0067DX=0000SP=0020BP=0000SI=0000 DI=0000 DS=0B47ES=0B37SS=0B49CS=0B4BIP=0005NVUPEIPLNZNAPONC 0B4B:0005A00000 MOVAL,[0000] DS:0000=02 -t2 AX=0B02BX=0000CX=0067DX=0000SP=0020BP=0000SI=0000 DI=0000 DS=0B47ES=0B37SS=0B49CS=0B4BIP=0008NVUPEIPLNZNAPONC 0B4B:000802060100 ADD AL,[0001] DS:0001=03 AX=0B05BX=0000CX=0067DX=0000SP=0020BP=0000SI=0000 DI=0000 DS=0B47ES=0B37SS=0B49CS=0B4BIP=000CNVUPEIPLNZNAPENC 0B4B:000CA20200 MOV[0002],AL DS:0002=00 - 55 附录4PCI总线配置资源简单介绍 目前使用奔腾(Pentium)微处理器系列的微型计算机在体系结构上都采用PCI总线结构。
虽然在部分计算机里(特别是控制计算机)还存在ISA总线,但它是为兼容早期的8位和16位的接口卡而保存的。
一个PCI总线接口规范包含有一系列的寄存器,这些寄存器位于PCI接口上的一个配置内存区上,包含了主板的所有信息。
寄存器中的这些信息允许计算机自动配置PCI卡。
这个特性就是即插即用特性。
下面简单介绍PCI卡资源获取的一些基本概念。
⒈即插即用原理(PlugandPlay)早期的PC机里使用的板卡中,每种板卡上都有许多跳线和拨动开关。
用户用它们来设置各种计算机资源(地址空间,中断号,DMA通道等)。
为防止板卡之间的资源冲突,需要用户对板卡的功能和性能有很深的了解。
为此,在Pentium级处理器以上的PC机推出了由计算机自动配置各种资源的方法,这就是即插即用(PlugandPlay)方法。
最大限度的避免了人工干预计算机资源配置。
即插即用(PnP)的原理,就是在每块支持PnP的板卡上都有一组称为配置空间的寄存器,在这些寄存器里保存有计算机板卡对系统资源的需求参数。
当windowsXX启动时,计算机的BIOS引导程序首先读出这些参数,然后综合每块板卡对系统资源的需求,统一分配整个系统的资源。
在这个过程里不需要人工干预。
为了BIOS引导程序能正确的对板卡所需的资源进行动态配置,在配置空间寄存器中存储的是相对资源信息,不是绝对的资源信息。
对于不支持PnP的板卡,仍需要人工进行手动配置资源。
⒉PCI配置空间PCI配置空间是长度为256字节的一段内存空间,前64个字节包含有PCI接口的信息,可以通过它访问PCI接口。
在前64个字节里,地址为00H的32位的双字包含了单元识别码和销售商识别码。
单元识别码是一个16位的数,占用了00H单元的32位字的高16位(D31----D16位)。
如果单元识别码没有安装,在计算机启动时就会显示0FFFFH;如果安装了,计算机就会显示一个范围在0000H----0FFFFH之间的一个确定的数据,这个数据是单元识别码。
这是一个类码,用来区分PCI接口的类。
销售商识别码是由PCISIG分配的,它占用了第一个32位字的低16位(D15----D0位)。
状态字位于配置空间内存地址04H单元的D31----D16位,命令字位于04H单元的D15----D0位。
基地址空间包含内存的基地址,I/O的地址空间和扩展ROM地址空间。
配置空间内存详细分布及说明分别如表4-1和表4-2所示。
表4-1PCI配置寄存器 D31 D15 D16 D0 DEVICEID VENDORID STATUS COMMAND CLASSCOOE REVID BIST HEADERTYPE=0LATENCYTIMR CACHELINE SIZE BASEADDREESREGISTER#
0 BASEADDREESREGISTER#
1 地址 00H04H08H0CH 10H14H 56 BASEADDREESREGISTER#
2 BASEADDREESREGISTER#
3 BASEADDREESREGISTER#
4 BASEADDREESREGISTER#
5 RESERVED=0’s RESERVED=0’s EXPANSIONROMBASEADDRESS RESERVED=0’s RESERVED=0’s MAX_LAT MIN_GNT INTERRUPTPIN 注:地址是以双字递增。
18H1CH20H24H28H2CH30H34H38HINTERRUPTLINE3CH 表4-2PCI配置空间说明 配置空间偏移量(字节地 寄存器名称和寄存器说明 址) 00H----01H VendorID 生产商识别ID 02H----03H DeviceID 设备ID 04H----05H Command PCI命令寄存器 06H----07H Status PCI状态寄存器 08H RevID 修正识别码寄存器 09H----0BH ClassCode 类代码寄存器 0CH CacheLineSize cache线大小寄存器 0DH LatencyTimer 主控延迟时间 0EH HeadreType 头类型 0FH BIST 自我测试 10H----27H BaseAddressRegister基地址寄存器 28H----2FH 保留 30H ExpansionRomBaseAddress 扩展ROM基地址 34H----3BH 保留 3CH InterruptLine 中断线 3DH InterruptPin 中断引脚 3EH MinimumGrant 3FH 最大延迟 注:地址是以字节递增。
⒊在DOS下获取PCI配置空间参数在80X86类型的处理器系统中,可以通过中断调用号1AH,在BIOS里读取PCI的配置空间参数,调用时,寄存器AH=0B1H,AL=功能号。
下表列出了PCIBIOS的相关函数: 表4-
3 PCI函数调用(中断调用是INT 函数 累加器 AH PCI_BIOS_PRESENT0B1H 1AH)累加器AL01H 说明PCI_BIOS是否存在 57 FIND_PCI_DEVICEFIND_PCI_CLASS_CODEGENERATE_SPECIAL_CYCLE READ_CONFIG_BYTEREAD_CONFIG_WORDREAD_CONFIG_DWORDWRITE_CONFIG_BYTEWRITE_CONFIG_WORDWRITE_CONFIG_DWORD SEG_PCI_IRQ 0B1H0B1H0B1H0B1H0B1H0B1H0B1H0B1H0B1H0B1H 02HPCI设备查找03HPCI类码查找06H产生特殊周期08H配置字节读入09H配置字读入0AH配置双字读入0BH写配置字节0DH写配置字0EH写配置双字0FH设置PCI中断号 表4-4中断调用的返回值的返回代码表 返回代码 累加器AH 说明 SUCCESSFUL 01H 成功 FUNC_NOT_SUPPORTED 81H 不支持的函数 BAD_VENDOR_ID 83H 错误的厂商ID值 DEVICE_NOT_FOUND 86H 设备未发现 BAD_REGISTER_NUMBER 87H 错误的寄存器号 SET_FAILOD 88H 设置失败 BUFFER_TOO_SMALL 89H 缓冲区太小 注:中断调用的返回值存入AH,CL,CF里。
[CL]:在系统中最大的PCI总线号 [CF]:存在状态:1:没有BIOS 0:如果EDX中有PCI字符,则BIOS存在函数。
⒋PCIBIOS函数介绍
(1)PCI_BIOS_PRESENTPCI_BIOS_PRESENT是查看PCIBIOS是否存在,如果存在则板本号为多少的函数。
入口:[AH]=0B1H [AL]=01H出口:[EDX]=“PCI”ACSII字符串 [AH]=存在状态:00H=BIOS存在01H=BIOS不存在 [AL]=硬件[BX]=板本号
(2)FIND_PCIDEVICE用来查找指定厂商和设备号的PCI板卡的位置。
调用该函数后,用户可以利用该函数返回的总线号去调用READ_CONFIG和WRITE_CONFIG函数去访问设备配置空间。
入口:[AH]=0B1H[AL]=02H[CX]=设备ID值(0….65535)[DX]=厂商ID值(0….65535)[SI]=索引号(0….N)出口:[AH]=返回代码:SUCCESSFUL 58 DEUICE_NOT_FOUNDBAD_VENDOR_ID[BH]=总线号(0…255)[BL]=设备号(高5位),功能号(低3位)[CF]=完成状态:01H=错误00H=成功
(3)FIND_PCI_CLASS_CODE用来查找指定类代码和索引的PCI设备的位置。
其后可用调用READ_CONFIG和WRITE_CINFIG来访问设备和配置空间。

(4)GENERATE_SPECIAL_CYCLE在PCI总线上用来产生特殊的周期。
入口:[AH]=0B1H[AL]=06H[BH]=总线号(0…255)[EDX]=特殊周期数据出口:[AH]=返回代码:SUCCESSFULFUNCTION_NOT_SRPPORTED[CF]=完成状态:01H,错误00H,成功
(5)READ_CONFIG_BYTE按字节读取配置空间数据。
入口:[AH]=0B1H[AL]=08H[BH]=总线号(0…255)[BL]=设备号(高5位),功能号(低3位)[DI]=寄存器号(0…255)出口:[AH]=返回代码:SUCCESSFUL[CL]=读到的字节[CF]=完成状态:01H,错误00H,成功
(6)READ_CONFIG_WORD/READ_CONFIG_DWORD按字/双字读取配置空间。
入口:[AH]=0B1H[AL]=09H/0AH[BH]=总线号(0…255)[BL]=设备号(高5位),功能号(低3位)[DI]=寄存器号(0,2,
4,…254)/(0,4,
8,…252)出口:[AH]=返回代码:SUCCESSFUL BAD_REGISTER_NUMBER[CX]/[ECX]=读取的字/双字[CF]=完成状态:01H,错误 00H,成功
(7)WRITE_CONFIG_BYTE/WRITE_CONFIG_WORD/WRITE_CONFIG_DWORD设备配置空间按字节/字/双字进行写。
59 入口:出口: [AH]=0B1H [AL]=0BH/0CH/0DH[BH]=总线号(0…255)[BL]=设备号(高5位),功能号(低3位)[DI]=寄存器号(0…255)[CL]/[ECX]/[ECX]=要写的字节/字/双字[AH]=返回代码:SUCCESSFUL BAD_REGISTER_NUMBER[CF]=完成状态:01H,错误 00H,成功 ⒌PCI设备资源寄存器地址分布 #definePCI_CS_VENDOR_ID 0x00 #definePCI_CS_DEVICE_ID 0x02 #definePCI_CS_COMMAND 0x04 #definePCI_CS_STATUS 0x06 #definePCI_CS_REVISION_ID 0x08 #definePCI_CS_CLASS_CODE 0x09 #definePCI_CS_CACHE_LINE_SIZE 0x0c #definePCI_CS_MASTER_LATENCY 0x0d #definePCI_CS_HEADER_TYPE 0x0e #definePCI_CS_BIST 0x0f #definePCI_CS_BASE_ADDRESS_
0 0x10 #definePCI_CS_BASE_ADDRESS_
1 0x14 #definePCI_CS_BASE_ADDRESS_
2 0x18 #definePCI_CS_BASE_ADDRESS_
3 0x1c #definePCI_CS_BASE_ADDRESS_
4 0x20 #definePCI_CS_BASE_ADDRESS_
5 0x24 #definePCI_CS_EXPANSION_ROM 0x30 #definePCI_CS_INTERRUPT_LINE 0x3c #definePCI_CS_INTERRUPT_PIN 0x3d #definePCI_CS_MIN_GNT 0x3e #definePCI_CS_MAX_LAT 0x3f 60 附录5实验参考程序 实验2-1计算机系统时间显示程序设计实验 .MODELSMALL .STACK32H .DATA EESC DB01H TIM DB2DUP
(0),':',2DUP
(0),':',
2 .CODE .STARTUP MAINPROCFAR MOV AH,0BH INT 21H INC AL JNZ J_TIME MOV AX,4C00H INT 21H J_TIME:CALLTIME_
A JMP MAIN MAINENDP ; TIME_APROCNEAR MOV AH,
2 INT 1AH MOV SI,OFFSETTIM MOV AH,CH CALLDTOA MOV [SI+0],AX MOV AH,CL CALLDTOA MOV [SI+3],AX MOV AH,DH CALLDTOA MOV [SI+6],AX MOV DX,OFFSETTIM MOV AH,09H INT 21H RET FF3 ENDP ; DTOAPROCNEAR PUSHCX MOV AL,AH DUP
(0),0DH,0AH,'$' 61 DTOA MOVSHRADDANDADDPOPRETENDPEND CL,4AL,CLAL,30HAH,0FHAH,30HCX 实验2-2计算机键盘字符输入程序设计实验 实验2-3键盘模拟电子琴发声实验 STACKSTACK SEGMENTDB256DUP
(0)ENDS DATANOTES DATA SEGMENT DW 9108,8116,7231,6818,6088,5432,4831,4554 ;8个字类型数据分别对应于1,2,3,4,5,6,7,i发声频率的计数初值。
ENDS CODEBEGIN:NEXT: SEGMENTASSUMEMOVMOVMOVINTCMPJZSUBMOVMULMOVMOVINOROUTMOVOUTMOVOUT CS:CODE,DS:DATA,SS:STACK AX,DATA DS,AX AH,
0 16H ;等待键入字符 AL,30H EXIT ;判断为0则转结束 AL,31H ;将键入字符转换为数字1,2,3,
4,---,
8 CL,
2 CL ;转换后的数字乘以
2 SI,AX DX,NOTES[SI];根据计算结果查表取出计时器计数初值 AL,61H AL,
3 61H,AL ;打开扬声器 AL,0B6H ;重新初始化计数器
2 43H,AL AL,DL 42H,AL 62 EXIT:CODE MOVOUTJMPINANDOUTMOVINTENDSEND AL,DH42H,ALNEXTAL,61HAL,0FCH61H,ALAH,4CH21H BEGIN 实验3-2拨动开关并行接口实验 .MODELSMALL .DATA PCI_CS_BASE_ADDRESS_
3 EQU 1CH;实验仪PCI接口卡用户基地址寄存器地址 IOADD DW60H ;实验仪并行接口选通地址 MES DB‘PressK1----K4$’ MSEOK DB ‘OK’,0d,‘$’ .CODE .STARTUP;****************初始化程序 MOV AH,0B1H MOV AL,1H INT 1AH .IF AH!
=00 JMP EXIT .ENDIF MOV AH,0B1H MOV AL,02H MOV CX,8376H MOV DX,10EBH MOV SI,
0 ******************;测试PCIBIOS是否存在 ;查找PCI 63 INT 1AH JNC LOP JMPLOP: EXIT MOV AH,0B1H ;读取配置寄存器的用户基地址 MOV AL,09H MOV DI,PCI_CS_BASE_ADDRESS_
3 INT 1AH .IFAH!
=
0 JMP EXIT .ENDIF AND CX,0FFFCH MOV AX,CX ADD IOADD,AX ;计算并行接口选通地址,存入变量 IOADD;设置显示器显示方式,显示提示信息 MOV AH,
0 ;显示器显示方式为80*25彩色文本 MOV AL,
3 INT 10H MOV MOV INT;****************SCAN: MOVINTCMPJNEJMP DX,OFFSETMES ;显示提示信息 AH,
9 21H主程序********************* AH,016HAL,1BHLOP1EXIT LOP1:MOVMOVINTMOVMOVIN DL,‘K’AH,02H21HAX,0DX,IOADDAL,DX ;扫描拨码开关的输入信号;并行接口地址送DX寄存器 64 .IFAL==01H MOV DL,31H ;K1键按下,显示“K1” CALL DISP2 .ENDIF .IF AL==02H MOV DL,32H ;K2键按下,显示“K2” CALL DISP2 .ENDIF .IF AL==04H MOV DL,33H ;K3键按下,显示“K3” CALL DISP2 .ENDIF .IF AL==08H MOV DL,34H ;K4键按下,显示“K4” CALL DISP2 .ENDIF .IF AL==55H ;读出的键值是“55H”,显示“OK”字符串 MOV DX,OFFSETMSEOK;被显示字符串的首地址放在DX寄存器里 MOV AH,09H ;功能号9放在AH寄存器里 INT 21H JMP SCAN ;;*******************子程序 DISP2 PROCNEAR MOV AH,02H INT 21H MOV DL,0DH MOV AH,02H INT 21H DISP2 ENDP ********************** ;********************退出实验程序*********************** EXIT: MOV AX,4C00H INT 21H END 65 实验3-3发光二极管并行接口实验 .MODELSMALL .DATA PCI_CS_BASE_ADDRESS_
3 IOADD DW MES DB EQU1CH ;实验仪PCI接口卡用户基地址寄存器地址 60H ;实验仪并行接口选通地址 'Press1----
9,A,
B,C,
D,F',ODH,OAH,'$' .CODE .STARTUP ;****************初始化程序****************** MOV AH,0B1H ;测试PCIBIOS是否存在 MOV AL,1H INT 1AH .IF AH!
=00 JMP EXIT .ENDIF MOV AH,0B1H ;查找PCI MOV AL,02H MOV CX,8376H MOV DX,10EBH MOV SI,
0 INT 1AH JNC LOP JMP EXIT LOP: MOV AH,0B1H ;读取配置寄存器的用户基地址 MOV AL,09H MOV DI,PCI_CS_BASE_ADDRESS_
3 INT 1AH .IF AH!
=
0 JMP EXIT .ENDIF AND CX,0FFFCH MOV AX,CX ADDIOADD,AX ;计算并行接口选通地址,存入变量IOADD ;设置显示器显示方式,显示提示信息 MOV AH,
0 ;显示器显示方式为80*25彩色文本 MOV AL,
3 INT 10H MOV DX,OFFSETMES ;显示提示信息 66 MOV AH,
9 INT 21H ;****************主程序********************* SCAN: MOV AH,
0 INT 16H CMP AH,01H JNE LOP1 JMP EXIT LOP1:.IF AH<=01H JMP LOP2 .ENDIF .IF AH>=0CH JMP LOP2 .ENDIF MOV DX,IOADD OUT DX,AH LOP2:JMP SCAN ;********************退出实验程序*********************** EXIT: MOV AX,4C00H INT 21H END 实验4-1七段数码管显示控制实验 .MODELSMALL .DATA COUNT1 DB 00H ;循环次数 I8255ADDA DW 00H ;实验仪8255的A口地址 I8255ADDB DW 01H ;实验仪8255的B口地址 I8255TYPE DW 03H ;实验仪8255的控制寄存器地址 DLYC1 EQU
1 COUNT_DATA DB 4DUP
(0) ;定义显示缓冲区 COUNT DB 00H DISC DB 0C0H,0F9H ;七段码表 DB 0A4H,0B0H,99H,92H DB 82H,0F8H,80H,98H DIS0 DB 'PRESSANYOFTHEKEYSTOQUIT!
$';提示信息 67 PCI_CS_BASE_ADDRESS_
3 EQU 1CH ;PCI卡配置寄存器地址 .STACK 100H .CODE .STARTUP MOV AH,0B1H ;查看PCIBIOS是否存在 MOV AL,1H INT 1AH .IFAH!
=00 JMP m_EXIT .ENDIF MOVAH,0B1H ;查找PCI卡的位置 MOVAL,02H MOVCX,8376H MOVDX,10EBH MOVSI,
0 INT1AH JNC LOPA JMPm_EXIT LOPA: MOVAH,0B1H ;读取配置寄存器的用户基地址 MOVAL,09H MOV DI,PCI_CS_BASE_ADDRESS_
3 INT1AH .IFAH!
=
0 JMPm_EXIT .ENDIF AND CX,0FFFCH MOV AX,CX ;计算实验仪的8255并行接口芯片地址 ADD I8255TYPE,AX ADD I8255ADDA,AX ADD I8255ADDB,AX ;设置计算机屏幕显示模式 MOV AH,
0 ;INT10H功能0为设置屏幕显示方式 68 MOV AL,
3 ;AL=
3,设屏幕显示方式为80*25彩色文本 INT 10H ;显示提示信息 MOV DX,OFFSETDIS0 ;显示提示信息“PRESSANYOFTHEKEYSTOQUIT!
” MOV AH,09H INT 21H ;8255并行接口初始化 MOVDX,I8255TYPE ;写控制字,设置
A,B口输出 MOV AL,80H ;控制字为10000000B OUT DX,AL MOV DX,I8255ADDA ;8255的A口输出0FFH(熄灭码) MOV AL,0FFH OUT DX,AL MOV DX,I8255ADDB ;8255的B口输出0FFH,数码管不显示 MOV AL,0FFH OUT;主程序LOP0: MOV DX,ALCOUNT1,10H ;送循环次数 CALLPLUS1 ;调用10进制加1子程序 LOP1: CALLDISPLAY ;调用显示子程序 CALLPCKEY ;判键盘是否按下 MOV AL,COUNT1 DEC AL ;循环次数减
1 MOV COUNT1,AL JZ LOP0 ;循环10次,调用加1子程序1次 JMP LOP1 ; ;************************子程序******************* ;DISPLAYPROCNEAR ;显示子程序 MOV SI,OFFSETCOUNT_DATA ;从显示缓冲区取数 MOV BH,
0 ;取个位 MOV DX,I8255ADDA 69 MOV BL,[SI] MOV DI,BX MOV AL,[DI+DISC] OUT DX,AL MOV DX,I8255ADDB MOV AL,0FEH OUT DX,AL CALLTIME MOV AL,0FFH OUT DX,AL INC SI MOV DX,I8255ADDA MOV BL,[SI] MOV DI,BX MOV AL,[DI+DISC] OUT DX,AL MOV DX,I8255ADDB MOV AL,0FDH OUT DX,AL CALLTIME MOV AL,0FFH OUT DX,AL INC SI MOV DX,I8255ADDA MOV BL,[SI] MOV DI,BX MOV AL,[DI+DISC] OUT DX,AL INC DX MOV AL,0FBH OUT DX,AL CALLTIME MOV AL,0FFH OUT DX,AL ;建立索引值;取对应的七段码值;显示个位;调用延时程序;关显示;缓冲区地址加1;取十位数 ;显示十位数 ;取百位数 ;显示百位数 70 INC SI MOV DX,I8255ADDA MOV BL,[SI] MOV DI,BX MOV AL,[DI+DISC] OUT DX,AL MOV DX,I8255ADDB MOV AL,0F7H OUT DX,AL CALLTIME MOV AL,0FFH OUT DX,AL RETDISPLAYENDP ;PC机键盘扫描子程序PCKEYPROCNEAR MOV AH,
6 MOV DL,0FFH INT 21H JE LOPP1 MOV DX,I8255ADDA MOV AL,0FFH OUT DX,AL MOV AX,4C00H INT 21H LOPP1: RET PCKEYENDP ;延时子程序TIMEPROC NEAR MOVLOPT2: AX,08FH DEC AX MOV BX,0FFFFH LOPT1: ;取千位数;显示千位数 71 DEC BX JNZ LOPT1 .IFAX!
=
0 JMP LOPT2 .ENDIF RET TIMEENDP ;四位十进制数加1子程序 PLUS1PROCNEAR MOV SI,OFFSETCOUNT_DATA MOV CX,0004H LOPD0: MOV AL,[SI] INC AL CMP AL,0AH JNE LOPD1 MOV AL,
0 MOV [SI],AL INC SI LOOPLOPD0 LOPD1: MOV [SI],AL RET PLUS1ENDP ;程序结束 m_EXIT: MOV AX,4C00H INT 21H END 实验4-24*4十六进制数键盘控制实验.MODELSMALL.DATA 72 I8255TYPEI8255addAI8255addBI8255addCKEY_SV DW 0003H ;8255控制字的地址 DW 0000H ;8255的A口地址 DW 0001H ;8255的B口地址 DW 0002H ;8255的C口地址 DB 0,0,1,0,2,0,0,0,
3 KEY_V_BUF DB SCAN_
V DB KEY_HV DB DIS0 DB PCI_CS_BASE_ADDRESS_
3 ?
?
?
'PRESSANYOFTHEKEYSTOQUIT!
$';提示信息 EQU 1CH ;用户基地址 .STACK100H .CODE .STARTUP: MOVAH,0B1H MOV AL,1H INT 1AH .IF AH!
=00 JMP m_EXIT .ENDIF ;看PCIBIOS是否存在 MOV AH,0B1H MOVAL,02H MOVCX,8376H MOVDX,10EBH MOVSI,
0 INT1AH ;查找PCI卡的位置 JNC LOP JMPm_EXIT LOP:MOV AH,0B1H ;读取配置寄存器的用户基地址 MOVAL,09H MOV DI,PCI_CS_BASE_ADDRESS_
3 INT1AH .IF AH!
=
0 JMPm_EXIT .ENDIF AND CX,0FFFCH MOV AX,CX ADD I8255TYPE,AX 73 ADD I8255addA,AX ADD I8255addB,AX ADD I8255addC,AX ;*****************8255初始化 MOV AL,
3 MOV AH,
0 INT 10H MOV DX,OFFSETDIS0 MOV AH,
9 INT 21H MOV AH,0FFH MOV DX,I8255TYPE MOV AL,81H OUT DX,AL MOV KEY_V_BUF,0FFH *****************;显示提示;初始8255的C口 pc4~pc7为输出,pc0~3为输入 MAIN_LP:CALL.IFMOVCALL.ENDIFCALLCALLJMP KEYSCANAL!
=KEY_V_BUF&&(AL!
=0FFH)KEY_V_BUF,ALDISPLAY TIMEPCKEYMAIN_LP DISPLAY DISP_H:DISPLAY PROCNEAR .IF AL>=10H RET .ENDIF ADDAL,30H CMP AL,'9' JBEDISP_
H ADD AL,
7 MOVAH,
2 MOV DL,AL INT 21H RET ENDP ;显示键盘输入字符 ;将输入数字转换成ASCII码;输入小于等于字符9则直接输出,大于9则输出字母 ;用PC机显示器输出 KEYSCANPROCMOVMOV SCAN_LP: NEARKEY_HV,0SCAN_V,10H ;扫描键盘 74 KEYSCAN MOVMOVOUTINMOVANDMOV.IFMOVMOVMOVMOVADDRET.ENDIFADDROL.IFMOVRET.ENDIFJMPENDP AL,SCAN_VDX,I8255addCDX,ALAL,DXBL,ALBL,0FHAL,BLAL>0BX,OFFSETKEY_SVAH,0SI,AXAL,[BX+SI]AL,KEY_HV KEY_HV,4SCAN_V,1SCAN_V==1AL,0FFH SCAN_LP PCKEYPROC MOV MOV INT JE MOV INT P1: RET PCKEYENDP NEARAH,6DL,0FFH21HP1AX,4C00H21H TIMET2:T1: PROCMOVDECMOVDECJNZ.IFJMP.ENDIFRET NEARAX,0FFHAXBX,0FFFHBXT1AL!
=0T2 ;得c口0-3位数据;处理键盘输入数据 75 TIMEENDP m_EXIT:MOVINTEND AX,4C00H21H ;退出程序 参考文献 1赵长得《工业用微型计算机》北京机械工业出版社2000年10月2沈美明温冬婵《IBM-PC汇编语言程序设计》北京清华大学出版社1994年3月3武新《微机接口与汇编语言实训》北京高等教育出版社2001年4湘潭胜西电子科技有限公司《SXL-100型微机接口实验仪组成及安装及实验指导书》 76

标签: #怎么回事 #好友 #后缀名 #视频文件 #格式文件 #程序 #怎么看 #压缩文件