MFI讲义D微机接口技术实验(上)
- 格式:ppt
- 大小:3.16 MB
- 文档页数:5
实验三数据串传送和查表程序实验目的:通过实验掌握下列知识:1.执行串操作指令前要做哪些准备工作(设置哪些寄存器)?2.串传送、串比较、串扫描等指令及重复前辍REP、REPZ、REPNZ等。
实验内容及步骤:一、利用查表方法把DX的内容(16进制数)转换成ASCII码:1. 用A命令键入下列程序:MOV BX,1000MOV DI,2000MOV CX,4LOP: PUSH CXMOV CL,4ROL DX,CLPOP CXMOV AL,DLAND AL,OFXLATCLDSTOSBLOOP LOPINT 202. 用A命令在1000H处键入下列ASCII码并用D命令检查之:DB `0 1 2 3 4 5 6 7 8 9 A B C D E F'用D命令检查时注意左边的ASCII码值和右边的字符。
3. 用R命令给DX送一个四位的16进制数(例7F8E)。
4. 用T命令逐条运行这程序到LOOP指令处,观察并记录每次运行结果,特别是SP和堆栈内容(用D命令检查)5. 用G命令将此程序运行到结束,并用D命令检查2000H处所转换的结果。
可注意屏幕右边的ASCII字符与DX是否一致。
二、数据串搬家程序:1. 用A命令键入下列程序:MOV SI,1000MOV DI,1500MOV CX,0FLOP: MOV AL,[SI]MOV [DI],ALINC SIINC DILOOP LOPINT 202. 用A命令DB伪指令在1000H键入下列字符串:‘IBM_PC COMPUTER'3. 用G命令运行此程序,并用D命令检查目的地址处的字符与源串是否一致。
4. 若此程序中的目的地址改为1002H,再运行此程序,看能不能把1000H开始的字符串搬到1002H开始的地方去?修改程序以做到这一点。
三、段寄存器概念及字符串传送指令练习:1. 用A命令键入下列程序:MOV SI,0MOV DI,0MOV AX,1000MOV DS,AXMOV AX,1500MOV ES,AXMOV CX,0FCLDREP MOVSBINT 202. 用A命令DB伪指令在1000:0000处键入字符串'IBM_PC COMPUTER',并用D命检查之3. 用D命令检查0F00:1000处内容,看是否一样。
微机接口技术实验报告并行接口实验系别: 计算机科学与技术完成时间:2012-5-15一、实验目的1.熟悉并行接口电路;2.掌握8255并行接口芯片及8253定时器的应用及其编程技术。
二、实验内容及要求通过对8255芯片的编程,使得实验台上的步进电机按顺时针或逆时方向转动,同时扬声器(模拟电子琴)做高8度和低8度循环发音:1. 控制步进电机转动和电子琴发音;2.使用K0控制步进电机顺逆时针转动和电子琴发高低音;3.使用K1控制步进电机和电子琴速度(分快和慢两种速度);4.使用K2启动和停止步进电机转动和电子琴发音。
三、实验原理1、可编程并行芯片8255A并行接口即同时在多根I/O线上,以数据字节或字为单位实现CPU通过I/O端口与I/O 设备或被控制对象之间的信息传递,如计算机与打印机,A/D和D/A转换器,开关量接口等。
8255及其改进型8255A是最广泛应用的并行I/O接口。
8255A的主要性能参数如下:(1)8255A内共有4个端口,分别为口A、口B、口C和控制端口。
前三个端口为8位并行I/O端口,常用于传送数据信息;控制端口是用于接收CPU送来的控制命令,即控制字。
(2)8255A芯片可以三种不同的工作方式与I/O设备进行数据传输,具体方式由控制字来设定。
(3)8255与CPU之间交互信息可以使用中断方式进行。
它内部有三个中断源,分别产生与方式1(1个)和方式2(2个)中。
(4)8255A所有信号与TTL信号兼容,可直接与CPU的三总线连接使用。
(5)8255A使用单一的+5V电源,单项时钟。
8255A的三种工作方式:方式0——基本的输入/输出方式,方式1——选通的输入/输出方式,方式2——双向的输入/输出方式。
本次实验采用方式0,将口A和口B作为输出,分别控制步进电机的旋转和电子琴的发音,口C作为控制输入端。
根据端口编址及寻址方式,设定端口A的地址为288H,端口B地址为289H,端口C地址为28AH,控制端口的地址为28BH。
微机接口技术与应用课程设计学校名称:院系:班级:小组成员:一.实验名称交通灯设计二.实验目的用软件模拟交通灯并在硬件设备实现。
三.实验环境四.实验说明交通灯分南北向和东西,一边三个,分别是绿红黄,红绿黄灯交替有四种情况,依次为:0--东西绿灯,南北红灯1--东西黄灯,南北红灯2--东西红灯,南北绿灯3--东西红的,南北黄灯。
当有黄灯亮时停顿1000s,其余的停顿2000s。
五.连接试验箱8255与280~28f连接,PA0,PA1,PA2,PA3,PA4,PA5口分别与L0,L1,L2,5,L6,L7相连接。
六.实验代码#include<stdio.h>#include<conio.h>#include "ApiExusb.h"#pragma comment(lib,"ApiExusb.lib")#include <windows.h>// 回调函数声明LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);// 初始化窗口类声明BOOL InitWindowsClass(HINSTANCE hInstance, char *lpszClassName);// 初始化窗口声明BOOL InitWindows(HINSTANCE hInstance, int nCmdShow, char *lpszClassName, char *lpTitle);WNDCLASS wndclass; // 定义一个窗口类HWND hwnd; // 定义一个窗口句柄int nNum=0; // 为灯的状态赋初值,记录交通灯的状态,0--东西绿灯,南北红灯1--东西黄灯,南北红灯//2--东西红灯,南北绿灯3--东西红的,南北黄灯int status[4]={0x21,0x11,0x0c,0x0a}; //控制试验箱灯的状态POINT pt[6]={{20,20},{80,20},{140,20},{20,80},{80,80},{140,80}}; //六盏灯的圆心坐标上面为东西,下面为南北,从左到右依次为绿黄红int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow){MSG Msg; // 定义消息char lpszClassName[] = "交通灯"; // 窗口的类名char lpTitle[] = "基本绘图-交通灯"; // 窗口标题名if(!Startup()) /*打开设备*/{//printf("ERROR: Open Device Error!\n");return 0;//exit(0);}printf("Enter any key will return:\n");PortWriteByte(0x28b,0x80); //向控制口写命令,控制c口输出// 初始化窗口类if (!InitWindowsClass(hInstance, lpszClassName)){return FALSE;}// 初始化窗口if (!InitWindows(hInstance, nCmdShow, lpszClassName, lpTitle)){return FALSE;}//消息循环while(GetMessage(&Msg, NULL, 0, 0)){TranslateMessage(&Msg);DispatchMessage(&Msg);}Cleanup(); /*关闭设备*/return Msg.wParam; // 程序终止时将信息返回系统}// 初始化窗口类定义BOOL InitWindowsClass(HINSTANCE hInstance, char *lpszClassName){//1、窗口类定义wndclass.style = 0; // 窗口类型为默认类型wndclass.lpfnWndProc = WndProc; // 窗口处理函数为WNDPROCwndclass.cbClsExtra = 0; // 窗口类无扩展wndclass.cbWndExtra = 0; // 窗口实例无扩展wndclass.hInstance = hInstance; // 当前实例句柄wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); // 窗口的最小化图标为默认图标wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); // 窗口采用箭头光标wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); // 窗口采用白色背景wndclass.lpszMenuName = NULL; // 窗口中无菜单wndclass.lpszClassName = lpszClassName; //类名为lpClassName//2、注册窗口类if (!RegisterClass(&wndclass)){ // 如果注册失败则发出警告声音MessageBeep(0);return FALSE;}return TRUE;}// 初始化窗口声明BOOL InitWindows(HINSTANCE hInstance, int nCmdShow, char *lpszClassName, char *lpTitle)//3、创建窗口hwnd = CreateWindow(lpszClassName,lpTitle,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,0,600,450,NULL,NULL,hInstance,NULL);//4、显示窗口ShowWindow(hwnd, nCmdShow);UpdateWindow(hwnd);return TRUE;}// 回调函数定义LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){HDC hDC; // 定义设备环境句柄HPEN hPen; // 定义画笔句柄HBRUSH hBrush; // 定义画刷句柄PAINTSTRUCT PtStr; // 定义包含绘制信息的结构体变量int R = 10;// 定义圆的半径switch(message){case WM_KEYDOWN: //响应按键消息//----未完待续break;case WM_PAINT:{ // 处理绘图消息hDC = BeginPaint(hwnd, &PtStr); // 得到设备句柄SetMapMode(hDC, MM_ANISOTROPIC); // 设置映像模式SetWindowExtEx(hDC, 400, 300, NULL); // 设置窗口区域(逻辑单位)400,300SetViewportExtEx(hDC, 600, 450, NULL); // 设置视口区域(物理单位)SetViewportOrgEx(hDC, 200, 200, NULL); // 设置视口原点坐标为(300,200)hPen = (HPEN)GetStockObject(BLACK_PEN);SelectObject(hDC, hPen);// 绘制六盏交通灯外圆int i=0;if(status[nNum]&0x20)hBrush = CreateSolidBrush(RGB(0, 255, 0)); //东西为绿灯elsehBrush = CreateSolidBrush(RGB(255, 255, 255));SelectObject(hDC, hBrush);Ellipse(hDC,pt[i].x-R,pt[i].y-R,pt[i].x+R,pt[i].y+R);i++;//东西为黄灯if(status[nNum]&0x10)hBrush = CreateSolidBrush(RGB(255, 255, 0));elsehBrush = CreateSolidBrush(RGB(255, 255, 255));SelectObject(hDC, hBrush);Ellipse(hDC,pt[i].x-R,pt[i].y-R,pt[i].x+R,pt[i].y+R);i++;//东西为红灯if(status[nNum]&0x08)hBrush = CreateSolidBrush(RGB(255, 0, 0));elsehBrush = CreateSolidBrush(RGB(255, 255, 255));SelectObject(hDC, hBrush);Ellipse(hDC,pt[i].x-R,pt[i].y-R,pt[i].x+R,pt[i].y+R);i++;//南北为绿灯if(status[nNum]&0x04)hBrush = CreateSolidBrush(RGB(0, 255, 0));elsehBrush = CreateSolidBrush(RGB(255, 255, 255));SelectObject(hDC, hBrush);Ellipse(hDC,pt[i].x-R,pt[i].y-R,pt[i].x+R,pt[i].y+R);i++;//南北为黄灯if(status[nNum]&0x02)hBrush = CreateSolidBrush(RGB(255, 255, 0));elsehBrush = CreateSolidBrush(RGB(255, 255, 255));SelectObject(hDC, hBrush);Ellipse(hDC,pt[i].x-R,pt[i].y-R,pt[i].x+R,pt[i].y+R);i++;//南北为红灯if(status[nNum]&0x01)hBrush = CreateSolidBrush(RGB(255, 0, 0));elsehBrush = CreateSolidBrush(RGB(255, 255, 255));SelectObject(hDC, hBrush);Ellipse(hDC,pt[i].x-R,pt[i].y-R,pt[i].x+R,pt[i].y+R);i++;PortWriteByte(0x28a,status[nNum]);if(kbhit())exit(0);if((status[nNum]&0x02)||(status[nNum]&0x10)) //有黄灯亮,则睡1000,否则睡2000Sleep(1000);elseSleep(2000);nNum=(++nNum)%4; //控制交通灯循环InvalidateRect(hwnd, NULL, 1); // 重绘窗口区域DeleteObject(hPen);DeleteObject(hBrush);EndPaint(hwnd, &PtStr);break;}case WM_DESTROY:{PostQuitMessage(0);}default:{return DefWindowProc(hwnd, message, wParam, lParam);}}return 0;}七.实验现象试验箱上红绿灯与Win32执行出来的图形界面上的模拟红绿灯交替亮现象是同步的。
最新微机接口实验报告实验目的:1. 熟悉微机接口的基本原理和功能。
2. 掌握微机接口的编程和操作技巧。
3. 通过实验加深对微机接口技术的理解。
实验环境:- 微机接口实验箱- 个人电脑- 相关软件和驱动程序实验内容:1. 实验一:了解微机接口的基本结构和工作原理。
- 学习微机接口的基本概念,包括数据总线、地址总线、控制总线等。
- 观察实验箱中的微机接口模块,识别各部分的功能。
2. 实验二:编写简单的输入输出程序。
- 使用汇编语言或C语言编写程序,实现对微机接口的控制。
- 通过程序实现LED灯的点亮和熄灭,以及按键的读取。
3. 实验三:中断和DMA操作。
- 学习中断的基本概念和处理流程。
- 实现一个基于中断的键盘输入程序。
- 了解DMA的工作原理,并编写相应的数据传输程序。
实验步骤:1. 准备实验环境,确保所有设备和软件均已正确安装和配置。
2. 按照实验指导书的要求,逐步完成各个实验项目。
3. 在实验过程中记录关键步骤和结果,以便撰写实验报告。
4. 对遇到的问题进行分析和解决,记录解决方案。
实验结果:1. 成功理解微机接口的基本结构和功能。
2. 编写的输入输出程序能够正确控制LED灯和读取按键状态。
3. 中断和DMA操作实验顺利完成,实现了预期的功能。
实验结论:通过本次实验,加深了对微机接口技术的理解,掌握了基本的编程和操作技能。
实验中遇到的问题和挑战也有助于提高解决问题的能力。
通过实践,更加明确了理论知识与实际应用之间的联系。
建议和反思:- 在实验过程中,应更加注重对理论知识的应用,以提高实验效率。
- 对于复杂的问题,应采取分步解决的策略,避免在实验中出现混乱。
- 未来应加强实验前的准备工作,确保实验能够顺利进行。
《微机接口技术及实验》教学大纲课程编号:学时数:72学时学分数:4学分适用专业:计算机科学与技术执笔者:周红明编写日期:2009年2月一、课程的性质、目的与任务《微机接口技术及实验》是计算机科学与技术专业一门必修课程,本课程从计算机的硬件接口、软件接口两个方面对计算机接口技术进行介绍,并使用C及汇编语言作为硬件接口控制程序,用高级语言对硬件进行I/O操作及中断处理。
通过本课程的学习使学生掌握80X86及主要支持芯片的功能、结构、编程方法以及基本外部设备的接口技术,具备对微机系统的设计、维护与软硬件开发能力。
二、课程各教学环节的基本要求本课程的教学环节包括理论讲授环节、实践教学环节、作业环节三个方面。
理论讲授环节:充分利用多媒体技术等现代化教学手段,采用电子教案教学,讲授过程中结合实例分析和演示。
实践教学环节:要求利用汇编语言及C语言完成验证性和综合实验作业环节:平均每章布置一次作业,要求学生认真解答,通过作业来检验学生对知识的掌握情况,促进学生保持学习的动力。
三、与其它课程的联系先修课程:微机原理、汇编语言程序设计四、本课程与人才培养方案的联系及学生能力培养该课程的特点是综合性和实践性,,所以教师要深入浅出地讲透,学生要深思熟虑地去复习弄懂,从而获得计算机硬件接口和软件接口方面的基础知识、基本思想和基本方法技能,培养学生利用硬件与软件相结合的方法分析解决问题的能力,由于本课程实践性较强,要注重实验教学及效果。
五、考核方式采用闭卷形式考核,要求学生掌握基本概念,并具备信息系统开发的基本能力,对当今的系统开发的新概念、新技术和新思想有所了解期末成绩=20%平时+20%X实验+期末考试成绩×60%六、教学参考书目参考教材:《微型计算机接口技术及应用》刘乐善等编华中科大出版社参考书目:《现代计算机接口技术》洪志全等编电子工业出版社七、各章节教学的基本要求(一)学时分配本课程建议教学时数为72学时,具体分配如下表:(二)各章节教学的内容及要求第一章微机接口概述教学内容:1.接口功能2.接口的组成3.接口电路的结构形式4.CPU 与接口交换数据的方式5.分析与设计接口电路的基本方法6.接口技术的发展趋势教学要求:理解:接口的功能及组成掌握:CPU 与接口交换数据的方式第二章I/O 端口地址译码技术教学内容:1. I/O 端口及编址方式2. I/O 端口地址分配3. I/O 端口地址译码教学要求:了解:PC机中端口的分配理解:I/O 端口地址分配及编址方式第三章定时/ 计数技术教学内容:1.基本概念2.可编程定时 / 计数器 8253-5/8254-23.8253-5/8254-2 的应用举例教学要求:了解:8253内部结构掌握:8253编程控制字、各种工作方式、波形特点、8253初始化编程及分频、计数等应用第四章DMA 技术教学内容:1.DMA 传送的特点2. DMA 传送的过程3. DMA 传送的方式4. DMA 控制器5. DMA 系统教学要求:了解:8237A内部结构理解:8237A的各种工作方式掌握:8237A的控制字和初始化编程第五章中断技术教学内容:1.中断的基本概念2. IBM-PC 微机中断系统3.可编程中断控制器 8259A4.8259A 在微机系统中的应用教学要求:了解:中断系统、中断请求、中断源、中断判优等概念理解:8259A的基本框图和工作原理,及主要功能掌握:8259A的端口地址,控制字及初始化编程第六章存储器接口教学内容:1.半导体存储器2. 存储器接口技术3.主存储器接口4.高速缓冲器接口教学要求:了解:存储器的分类及性能理解:存储器的接口设计第七章并行接口教学内容:1、并行接口的特点2、可编程并行接口8255A3、8255A 的0 方式及其应用4、8255A 的 1 、2方式及其应用教学要求:了解:8255A内部结构、方式1、2理解:8255A的各种工作方式、联络控制信号线定义掌握:8255A的典型方式0应用第八章人机交互设备接口教学内容:1、键盘接口2、CRT 显示器接口3、打印机接口4、鼠标器接口5、多媒体设备及其接口教学要求:了解:键盘、显示器、打印机接口原理理解:LED的接口设计第九章串行通信接口教学内容:1、串行传送的基本概念2、串行通信的数据格式3、串行通信接口标准4、串行通信接口标准5、可编程串行接口芯片8251A教学要求:了解:RS-232C接口的特点及常用引脚、8251A对外信号以及连接关系理解:8251A的初始化编程及其应用掌握:串行通信的基本概念、8251A方式选择命令字、控制命令字、状态字第十章A/D 与D/A 转换器接口教学内容:1、D/A 转换器的接口方法2、D/A 转换器接口电路设计3、A/D 转换器接口及基本原理与方法4、A/D 转换器接口电路设计教学要求:理解:A/D、D/A转换原理及技术指标掌握:A/D、D/A的接口设计及编程第十一章总线与接口标准教学内容:1、总线与接口标准2、系统总线3、PCI 局部总线4、高性能串行总线接口标准IEEE1394教学要求:了解:总线的规范理解:PCI总线及USB总线的基本性能第十二章windows环境下的接口编程教学内容:1、Windows端口操作2、动态链接库DLL3、API系统功能接口4、WinSock接口控制5、NetBIOS网络接6、数据库编程接口教学要求:了解:windows的线程控制技术、实时控制和虚拟设备、WDM驱动程序的开发方法理解:NetBIOS网络接口及数据库编程接口掌握:Windows环境下动态链接库DLL的创建和调用,API函数的调用方法、WinSock接口的编程控制。
《微机原理与接口》课程上机操作实验报告姓名:王自胜学号: 12212162指导教师:付文秀时间: 2014年12月I/O地址译码与交通灯控制实验一、实验目的通过并行接口8255实现十字路口交通灯的模拟控制,进一步掌握对并行口的使用。
二、实验内容如图5-3,L7、L6、L5作为南北路口的交通灯与PC7、PC6、PC5相连,L2、L1、L0作为东西路口的交通灯与PC2、PC1、PC0相连。
编程使六个灯按交通灯变化规律燃灭。
十字路口交通灯的变化规律要求:(1)南北路口的绿灯、东西路口的红灯同时亮3秒左右。
(2)南北路口的黄灯闪烁若干次,同时东西路口的红灯继续亮。
(3)南北路口的红灯、东西路口的绿灯同时亮3秒左右。
(4)南北路口的红灯继续亮、同时东西路口的黄灯亮闪烁若干次。
(5)转(1)重复。
三、程序流程图四、程序清单DATA SEGMENTX DB ?DATA ENDSSTACK1 SEGMENT STACKDW 100H DUP(0)STACK1 ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA,SS:STACK1 START: MOV AX,DATAMOV DS,AX;---------------INIT---------------- MOV DX,0EC0BH ;写控制字MOV AL,80HOUT DX,ALL3: MOV DX,0EC0AHMOV AL,24H ;南北绿灯,东西红灯亮OUT DX,ALCALL DELAYCALL DELAY ;长延时,3s左右CALL DELAYCALL DELAYCALL DELAYCALL DELAYCALL DELAYMOV BL,8MOV AL,04HL0: XOR AL,40H ;南北黄灯闪,东西红灯亮OUT DX,ALCALL DELAY ;延时CALL DELAYDEC BL ;闪烁几次JNZ L0CALL DELAYMOV AL,81H ;南北红灯亮,东西绿灯亮OUT DX,ALCALL DELAYCALL DELAYCALL DELAY ;长延时,3s左右CALL DELAYCALL DELAYCALL DELAYCALL DELAYMOV BL,9MOV AL,80HL1: XOR AL,02H ;南北红灯亮,东西黄灯闪OUT DX,ALCALL DELAY ;延时CALL DELAYDEC BLJNZ L1 ;闪烁几次CALL DELAYMOV DL,0FFHMOV AH,06HINT 21HJZ L3 ;六号功能判断若无字符输入ZF=1继续循环;------------------------------MOV AH,4CHINT 21H;-----------延时函数------------DELAY : PUSH CXPUSH DXMOV CX,1FFFHLOP1: MOV DX,0FFFFHLOP2: DEC DXJNZ LOP2LOOP LOP1POP DXPOP CXRETCODE ENDSEND START可编程定时时钟/计数器(8253)一、实验目的掌握8253的基本工作原理和编程方法。
微机接口技术实验实验五保护模式下的中断处理姓名:胡诣嵩学号:20053449日期:2008-5-30一实验名称保护模式下的中断处理二实验目的1.通过本实验了解、熟悉保护模式下的中断以及它的处理方式。
2.巩固微机接口课程学习的80386DX在保护模式下相关的知识点。
三简述程序执行过程1、作切换到保护方式的准备2、切换到保护方式3、程序循环等待,当有键盘和时钟中断时,调用中断服务程序显示字符4、切换回实模式四实验源程序;功能:演示保护方式下的中断处理过程.386P;----------------------------------------------------------------------------;存储段描述符结构类型定义;----------------------------------------------------------------------------Desc STRUCLimitL DW 0 ;段界限(BIT0-15)BaseL DW 0 ;段基地址(BIT0-15)BaseM DB 0 ;段基地址(BIT16-23)Attributes DB 0 ;段属性LimitH DB 0 ;段界限(BIT16-19)(含段属性的高4位)BaseH DB 0 ;段基地址(BIT24-31)Desc ENDS;----------------------------------------------------------------------------;伪描述符结构类型定义(用于装入全局或中断描述符表寄存器);----------------------------------------------------------------------------PDesc STRUCLimit DW 0 ;16位界限Base DD 0 ;32位基地址PDesc ENDS;----------------------------------------------------------------------------;门描述符结构类型定义;----------------------------------------------------------------------------Gate STRUCOffsetL DW 0 ;32位偏移的低16位Selector DW 0 ;选择子DCount DB 0 ;双字计数GType DB 0 ;类型OffsetH DW 0 ;32位偏移的高16位Gate ENDS;----------------------------------------------------------------------------;存储段描述符类型值说明;----------------------------------------------------------------------------ATDR EQU 90h ;存在的只读数据段类型值ATDW EQU 92h ;存在的可读写数据段属性值ATDWA EQU 93h ;存在的已访问可读写数据段类型值ATCE EQU 98h ;存在的只执行代码段属性值ATCER EQU 9ah ;存在的可执行可读代码段属性值ATCCO EQU 9ch ;存在的只执行一致代码段属性值ATCCOR EQU 9eh ;存在的可执行可读一致代码段属性值DA_386IGate EQU 8Eh ;386 中断门类型值;----------------------------------------------------------------------------DSEG SEGMENT USE16 ;16位数据段;----------------------------------------------------------------------------_SavedIMREG_M db 0 ; 中断屏蔽寄存器值_SavedIMREG_S db 0 ;DB 512 dup (0)TopOfStack LABEL BYTEGDT LABEL BYTE ;全局描述符表DUMMY Desc <> ;空描述符Code Desc <0ffffh,,,ATCER,,> ;代码段描述符DataV Desc <0ffffh,,,ATDW,,> ;源数据段描述符DataP Desc <0ffffh,,,ATDWA,,> ;目标数据段描述符Code32 Desc <0ffffh,,,ATCER,40h,> ;代码段描述符;----------------------------------------------------------------------------GDTLen = $-GDT ;全局描述符表长度VGDTR PDesc <GDTLen-1,> ;伪描述符;----------------------------------------------------------------------------Code_Sel = Code-GDT ;代码段选择子DataV_Sel = DataV-GDT ;源数据段选择子DataP_Sel = DataP-GDT ;目标数据段选择子Code32_Sel = Code32-GDT ;目标数据段选择子;----------------------------------------------------------------------------; IDTALIGN 32IDT LABEL BYTEIDT_00_1F Gate 32 dup (<offset SpuriousHandler, Code32_Sel, 0, DA_386IGate, 0>)IDT_20 Gate 1 dup (<offset ClockHandler, Code32_Sel, 0, DA_386IGate, 0>)IDT_21 Gate 1 dup (<offset EscHandler, Code32_Sel, 0, DA_386IGate, 0>) ;<键盘中断服务程序的中断门>IDT_21_7F Gate 94 dup (<offset SpuriousHandler, Code32_Sel, 0, DA_386IGate, 0>)IDT_80 Gate 1 dup (<offset UserIntHandler, Code32_Sel, 0, DA_386IGate, 0>)IDTLen = $-IDT ;中断描述符表长度VIDTR PDesc <IDTLen-1,> ;伪描述符_wSSValueInRealMode dw 0_wSPValueInRealMode dw 0_SavedIDTR dd 0 ; 用于保存IDTRdd 0;----------------------------------------------------------------------------DSEG ENDS ;数据段定义结束;----------------------------------------------------------------------------;打开A20地址线;----------------------------------------------------------------------------EnableA20 MACROpush axin al,92hor al,00000010bout 92h,alpop axENDM;----------------------------------------------------------------------------;关闭A20地址线;----------------------------------------------------------------------------DisableA20 MACROpush axin al,92hand al,11111101bout 92h,alpop axENDM;----------------------------------------------------------------------------;16位偏移的段间直接转移指令的宏定义(在16位代码段中使用);----------------------------------------------------------------------------JUMP16 MACRO Selector,OffsetDB 0eah ;操作码DW Offset ;16位偏移量DW Selector ;段值或段选择子ENDM;----------------------------------------------------------------------------CSEG SEGMENT USE16 ;16位代码段ASSUME CS:CSEG,DS:DSEG;----------------------------------------------------------------------------Start PROCmov ax,DSEGmov ds,axmov _wSSValueInRealMode,ss ;堆栈段mov _wSPValueInRealMode,sp ;堆栈指针;准备要加载到GDTR的伪描述符mov bx,16mul bxadd ax,OFFSET GDT ;计算并设置基地址adc dx,0 ;界限已在定义时设置好mov WORD PTR VGDTR.Base,axmov WORD PTR VGDTR.Base+2,dx;准备要加载到IDTR的伪描述符mov ax,SEG IDTmov bx,16mul bxadd ax,OFFSET IDT ;计算并设置基地址adc dx,0 ;界限已在定义时设置好mov WORD PTR VIDTR.Base,axmov WORD PTR VIDTR.Base+2,dx;设置代码段描述符mov ax,csmul bxmov WORD PTR Code.BaseL,ax ;代码段开始偏移为0mov BYTE PTR Code.BaseM,dl ;代码段界限已在定义时设置好mov BYTE PTR Code.BaseH,dhmov ax,seg SpuriousHandlermul bxmov WORD PTR Code32.BaseL,ax ;代码段开始偏移为0mov BYTE PTR Code32.BaseM,dl ;代码段界限已在定义时设置好mov BYTE PTR Code32.BaseH,dhmov ax,8000hmov dx,000BHmov WORD PTR DataV.BaseL,axmov BYTE PTR DataV.BaseM,dlmov BYTE PTR DataV.BaseH,dh;设置目标数据段描述符mov ax,dsmul bx ;计算并设置目标数据段基址mov WORD PTR DataP.BaseL,axmov BYTE PTR DataP.BaseM,dlmov BYTE PTR DataP.BaseH,dh; 保存中断屏蔽寄存器(IMREG)值in al, 21hmov _SavedIMREG_M, al ;主片IMR=21hin al, 0A1hmov _SavedIMREG_S, al ;从片IMR=A1h; 保存IDTRsidt QWORD PTR _SavedIDTR;加载GDTRlgdt QWORD PTR VGDTRcli ;关中断EnableA20 ;打开地址线A20lidt QWORD PTR VIDTR ;加载IDT;切换到保护方式mov eax,cr0or eax,1mov cr0,eax;清指令预取队列,并真正进入保护方式JUMP16 Code_Sel,<OFFSET Virtual>ALIGN 32Virtual: ;现在开始在保护方式下运行mov ax,DataV_Selmov gs,ax ;加载源数据段描述符mov ax,DataP_Selmov ds,ax ;加载源数据段描述符mov ss,ax ; 堆栈段选择子mov sp,offset TopOfStackcall Init8259Amov ah, 0Ch ; 0000 黑底1100 红字mov al, '!'mov gs:[((80 * 0 + 72) * 2)], ax ; 屏幕第0 行, 第72 列。