windows下对hid设备interrupt端口读写_读《汇编语言》第三版 第十七章 使用BOIS进行键盘输入和磁盘读写...

大多数有用的程序都需要处理用户的输入,键盘输入时最基本的输入。程序和数据通常需要长期存储,磁盘是最常用的存储设备。BOIS为这两种外设的I/O提供了最基本的中断例程,本章对它们的应用和相关问题进行讨论。

键盘输入将引发9号中断,BOIS提供了int9中断例程。CPU在9号中断发生后,执行int9中断例程,从60h端口读出扫描码,并将其转化为相应的ASCII码或者状态信息,存储在内存的指定空间(键盘缓冲区或状态字节)中。键盘缓冲区是用环形结构管理内存区,这里不过多深入,以几个键为例子看看int9中断例程对键盘输入的处理方法。

780fff1da939be75b43a932ee56b3abf.png

9e245a7ce757520442c56c0ce4109343.png

使用int16h中断例程读取键盘缓冲区。BOIS提供了int 16h中断例程供程序员调用。

int 16h中断例程包含一个最重要的功能是从键盘缓冲区读取一个键盘输入,该功能编号为0。下面的指令从缓冲区中读取一个键盘输入,并且将其从缓冲区删除:

8050bba09584d34a34e4e815f056630f.png

接下来看看int 16h如何读取键盘缓冲区。

ce8a78139bc0acc588db316756f709ce.png

从上面可以看出,int 16h中断例程的0号功能,进行如下工作。

(1) 检测到键盘缓冲区是否有数据;

(2) 没有继续做第一步;

(3) 读取缓冲区第一个字单元中的键盘输入;

(4) 将读取的扫描码送入ah,ASCII码送入;

(5) 将已读取得键盘输入从缓冲区中删除。

于是我们就知道BOIS的int9中断例程和int 16h中断例程是一对相互配合的程序。int 9中断例程键盘缓冲区写入,int 16h中断例程从缓冲区中读出。它们写入与读出的时机不同,int 9中断例程是在有键盘按下的时候向键盘缓冲区中写入数据;而int 16h中断例程是在应用程序对其进行调用的时候,将数据从键盘缓冲区中读出。

字符串的输入,用户通过键盘输入的通常不仅仅是单个字符而是字符串。我们初步的了解一下。最基本的字符串输入程序,需要具备下面的功能。

(1) 在输入的同时需要显示这个字符串;

(2) 一般在输入回车符后,字符串输入结束;

(3) 能够删除已经输入的字符。

编写一个接收字符串输入的子程序,实现上面3个基本功能。因为在输入过程中需要显示,子程序的参数如下:

cbc8c047b2f6be38975818d5d9e30fa3.png

实际代码略。

应用int 13h中断例程对磁盘进行读写。3.5英寸软盘分为上下两面,每面有80个磁道,每个磁道又分为18个扇区,每个扇区的大小为512字节。

则:2面*80磁道*18扇区*512字节=1440KB≈1.44MB

磁盘的实际访问由磁盘控制器进行,我们可以通过磁盘控制器来访问磁盘。只能以扇区为单位对磁盘进行读写。在读写扇区的时候,要给出面号,磁道号和扇区号。面号和磁道号从0开始,而扇区从1开始。如果我们直接通过磁盘控制器来访问磁盘,则需要涉及许多硬件细节。BOIS提供了对扇区进行读写的中断例程,这些中断例程完成了许多复杂的和硬件相关的工作。我们可以通过调用BOIS中断例程来访问磁盘。

BOIS提供的访问磁盘的中断例程为int 13h.读取0面0道1扇区的内容到0:200的程序例:

20a421f7b89004ffc47b4f08da3d1657.png

入口参数:

(ah)=int 13h的功能号(2表示扇区)

(al)=读取的扇区数

(ch)=磁道号

(cl)=扇区号

(dh)=磁头号(对于软盘面号,因为一个面用一个磁头来读写)

(dl)=驱动器号 软驱从0开始,0:软驱A,1:软驱B;磁盘从80h开始,80h:硬盘C,81h:磁盘D

es:kx指向接收从扇区读入数据的内存区

返回参数:

操作成功: (ah)=0,(al)=读入的扇区数

操作失败:(ah)=出错代码

dbe95313ebbf0c9e6decc244d9d406b4.png

入口参数:

(ah)=int 13h的功能号(3表示扇区)

(al)=写入的扇区数

(ch)=磁道号

(cl)=扇区号

(dh)=磁头号(面)

(dl)=驱动器号 软驱从0开始,0:软驱A,1:软驱B;磁盘从80h开始,80h:硬盘C,81h:磁盘D

es:bx指向将写入磁盘的数据

返回参数:

操作成功: (ah)=0,(al)=写入的扇区数

操作失败: (ah)=出错代码

如果要使用int 13h中断例程对软盘进行读写。直接向磁盘扇区写入数据是很危险的,很可能覆盖掉重要的数据。如果向软盘的0面0道1扇区中写入了数据,要使用软盘在现有的操作系统下可以使用,必须要重新格式化。

用面号,磁道号,扇区号来访问磁盘不太方便。可以考虑对位于不同的磁道,面上的所有扇区进行统一编号。编号从0开始一直到2879,我们称这个编号为逻辑扇区编号。逻辑扇区号和物理扇区号的关系如下:

逻辑扇区号=(面号*80+磁道号)*18+扇区号-1

根据逻辑扇区号算出物理编号方法如下:

int():描述性运算符,取商

rem():描述性运算符,取余数

逻辑扇区号=(面号*80+磁道号)*18+扇区号-1

面号=int(逻辑扇区号/1440)

磁道号=int(rem(逻辑扇区号/1440)/18)

扇区号=rem(rem(逻辑扇区号/1440)/18)+1

本章结束,也是最后一章结束。当屏幕前的你看到这里的时候相信你对汇编语言已经有了一个全面基础的了解,如果你学过其他语言C,C++,JAVA都能看到汇编语言的影子。虽然现在在我们大多数人身边用到汇编的不多,但不影响汇编的思想在其他语言上一步步的继承发展。学无止境,如果你想知道更多的知识还是要坚持加油快乐的学习。

附注1

Intel系列微处理器的3种工作模式

(1) 实模式:工作方式相当于一个8086。

(2) 保护模式:提供支持多任务环境的工作方式,建立保护机制(这与VAX等小型机 类似)

(3) 虚拟模式:可从保护模式切换至其中一种8086工作方式。这种方式的提供使用户可以方便地在保护模式下运行一个或多个原8086程序。

任何一台Intel系列的CPU的PC只要一开机,CPU就是在工作在实模式下。如果是以前古老的DOS加载后CPU仍然是在保护模式下工作,因为windows是多任务系统,它必须在保护模式下运行,如果windows中运行一个DOS下程序,那么windows将CPU切换到虚拟的8086模式下运行该程序。

附注2补码

既然表示的书有符号,则必须要能够区分正负。采用一种称为补码的编码方式,这种思想是:先确定用00000000b~01111111b表示0~127,然后再用它们按位取反加1后的数据表示负数,

989c97c85f5ede0c243f2fddf5e33984.png

(1) 最高位为1,表示负数;

(2) 正数的补码反加1后,为其对于的负数的补码;负数的补码取反后加1后,为其绝对值。

补码为有符号数的运算提供了方便,运算后的结果依旧满足补码规则。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
HID 设备读写 #include //! Defines the maximum length of a serial number #define SERNUM_LEN 40 //! Defines the maximum number of physical devices #define MAX_PHYS_DEVICES 6 //! \name HID Device return codes //! @{ // //! HID action/transfer was successful #define HID_DEVICE_SUCCESS 0x00 //! HID device was not found #define HID_DEVICE_NOT_FOUND 0x01 //! HID device is not opened #define HID_DEVICE_NOT_OPENED 0x02 //! HID device is allready opened #define HID_DEVICE_ALREADY_OPENED 0x03 //! Timeout occurs during transfer #define HID_DEVICE_TRANSFER_TIMEOUT 0x04 //! HID transfer failed #define HID_DEVICE_TRANSFER_FAILED 0x05 //! Invalid handle #define HID_DEVICE_HANDLE_ERROR 0x06 //! Unknown error #define HID_DEVICE_UNKNOWN_ERROR 0xFF //! @} // Enabled only when debugging HID connection issues //#define DEBUG_MODE //****************************************************************************** // //! \brief Device information structure. // //****************************************************************************** struct strHidDevice{ //! Handle for hid device HANDLE hndHidDevice; //! Indicator if device is opened BOOL bDeviceOpen; //! Timeout for GetReport requests UINT uGetReportTimeout; //! Timeout for SetReport requests UINT uSetReportTimeout; //! Asynchronous I/O structure OVERLAPPED oRead; //! Asynchronous I/O structure OVERLAPPED oWrite; //! Maximum length of InReport's WORD wInReportBufferLength; //! Maximum length of OutReport's WORD wOutReportBufferLength; //! InBuffer contains data, if InReport provides more data then the application actual need BYTE inBuffer[8192]; //! Number of current used bytes in inBuffer WORD inBufferUsed; }; //****************************************************************************** // //! A structure that tracks the number of serial numbers // //****************************************************************************** struct strTrackSerialNumbers { //! Index number DWORD deviceNum; //! Serial number of physical device char serialNum[SERNUM_LEN]; }; //****************************************************************************** // //! \addtogroup hiddevice_api //! @{ // //****************************************************************************** //****************************************************************************** // //! \brief Close a HID Device. //! //! This function will close a HID device based on the HID structure //! //! \param pstrHidDevice Structure which contains important data of an HID //! device //! //! \return Returns the error status, as one of //! \n \b HID_DEVICE_SUCCESS //! \n \b HID_DEVICE_NOT_OPENED //! \n \b HID_DEVICE_HANDLE_ERROR // //****************************************************************************** BYTE HID_Close(struct strHidDevice* pstrHidDevice); //****************************************************************************** // //! \brief Flush USB buffer for the given device //! //! \param pstrHidDevice Structure which contains important data of an HID //! device. //! //! \return Returns the error status, as one of //! \n \b HID_DEVICE_SUCCESS //! \n \b HID_DEVICE_HANDLE_ERROR //! \n \b HID_DEVICE_UNKNOWN_ERROR // //****************************************************************************** BYTE HID_FlushBuffer(struct strHidDevice* pstrHidDevice); //****************************************************************************** // //! \brief Gets the number of HID devices //! //! This function will return the number of interfaces connected with a //! specified VID, PID and serial number, if no devices are connected, //! it will return a 0 //! //! \param vid Vendor-Id of the device //! \param pid Product-Id of the device //! \param numSerNums Total number of connected physical devices //! //! \return Return the number of connected devices with the specific VID, PID, //! and serial number. // //****************************************************************************** DWORD HID_GetNumOfInterfaces(WORD vid, WORD pid, DWORD numSerNums); //****************************************************************************** // //! \brief Gets the number of serial number and serial number list //! //! Scans the HID Devices on the system for any whose VID/PID match the //! ones specified. For every one it finds, it returns that device's //! serial number in serialNumList. Every physical USB device within a //! given VID/PID space has a unique serial number; therefore, each //! item in the list corresponds with a separate physical USB device //! attached to this host; that is, different physical instances of the //! same product or design. The function returns the total number of //! serial numbers found; if none are found, it returns 0. //! //! \param vid Vendor-ID of the device //! \param pid Product-ID of the device //! \param serialNumList List of serial numbers corresponding to the passed //! VID and PID //! //! \return Returns the number of connected physical devices with the specific //! VID and PID // //****************************************************************************** DWORD HID_GetSerNums(WORD vid, WORD pid, struct strTrackSerialNumbers * serialNumList); //****************************************************************************** // //! \brief Returns the version number of a device. //! //! \param pstrHidDevice Structure which contains important data of an HID //! device. //! \param VersionNumber Pointer to USHORT variable. //! //! \return Returns the error status, as one of //! \n \b HID_DEVICE_SUCCESS //! \n \b HID_DEVICE_HANDLE_ERROR // //****************************************************************************** BYTE HID_GetVersionNumber(struct strHidDevice* pstrHidDevice, USHORT * VersionNumber); //****************************************************************************** // //! \brief Init structure with default values. //! //! It is important to call HID_Init() before calling HID_Open() to //! avoid unpredictable behavoir. //! //! \param pstrHidDevice Structure which contains important data of a HID //! device //! //! \return None // //****************************************************************************** void HID_Init(struct strHidDevice* pstrHidDevice); //****************************************************************************** // //! \brief This has to be called inside WM_ON_DEVICECHANGE notification window //! //! This function checks if the particular HID device structure is //! still connected or disconnected. //! //! \param pstrHidDevice Structure which contains important data of an HID //! device. //! //! \return Returns the error status, as one of //! \n \b HID_DEVICE_SUCCESS //! \n \b HID_DEVICE_HANDLE_ERROR // //****************************************************************************** BOOL HID_IsDeviceAffected(struct strHidDevice* pstrHidDevice); //****************************************************************************** // //! \brief Open a HID Device. //! //! This function opens the HID device associated with the HID interface //! 'deviceIndex' (0-7), on the physical device described by the VID, //! PID, and serial number. //! \param pstrHidDevice Structure which contains important data of an HID //! device //! \param vid Vendor-ID of the device //! \param pid Product-ID of the device //! \param deviceIndex Index of the device.If only one HID is connected, //! deviceIndex is 0. //! - Starts with zero //! - Maximum value is (HID_GetNumOfInterfaces() - 1) //! \param serialNumber Serial number of device to be opened. //! \param totalDevNum Total number of interfaces associated with the //! serial number //! \param totalSerNum Total number of physical devices associated with //! the VID/PID //! //! \return Returns the error status, as one of //! \n \b HID_DEVICE_SUCCESS //! \n \b HID_DEVICE_NOT_FOUND //! \n \b HID_DEVICE_ALREADY_OPENED // //****************************************************************************** BYTE HID_Open(struct strHidDevice* pstrHidDevice, WORD vid, WORD pid, DWORD deviceIndex, char serialNumber[SERNUM_LEN], DWORD totalDevNum, DWORD totalSerNum); //****************************************************************************** // //! \brief Reads a data stream from the given HID device. //! //! Prefixed report ID will be skipped. //! //! \param pstrHidDevice Structure which contains important data of an HID //! device //! \param buffer Pointer to buffer in which will be written //! \param bufferSize Number of bytes to read //! \param bytesReturned Number of actual read bytes //! //! \return Returns the error status, as one of //! \n \b HID_DEVICE_SUCCESS //! \n \b HID_DEVICE_NOT_OPENED //! \n \b HID_DEVICE_TRANSFER_TIMEOUT //! \n \b HID_DEVICE_TRANSFER_FAILED // //****************************************************************************** BYTE HID_ReadFile(struct strHidDevice* pstrHidDevice, BYTE* buffer, DWORD bufferSize, DWORD* bytesReturned); //****************************************************************************** // //! \brief Registers a device for program Windows notification. //! //! Registers the window pointed to by handle hWnd to receive //! notification when devices are added or removed from the system. //! //! \param hWnd Windows handle //! \param diNotifyHandle Device notification handle pointer address //! //! \return Returns the error status, as one of //! \n \b HID_DEVICE_SUCCESS //! \n \b HID_DEVICE_HANDLE_ERROR // //****************************************************************************** BYTE HID_RegisterForDeviceNotification(HWND hWnd, HDEVNOTIFY* diNotifyHandle); //****************************************************************************** // //! \brief Un-Registers a device from Windows notification. //! //! Un-registers the window pointed to by handle hWnd to receive //! notification when devices are added or removed from the system. //! //! \param diNotifyHandle: Device notification handle pointer address. //! //! \return Returns the error status, as one of //! \n \b HID_DEVICE_SUCCESS //! \n \b HID_DEVICE_HANDLE_ERROR // //****************************************************************************** BYTE HID_UnRegisterForDeviceNotification(HDEVNOTIFY* diNotifyHandle); //****************************************************************************** // //! \brief Writes a data stream to the given HID device. //! //! Needed report IDs will be generated automatically. //! //! \param pstrHidDevice Structure which contains important data of an HID //! device //! \param buffer Buffer which will be send //! \param bufferSize Number of bytes to send //! //! \return Returns the error status, as one of //! \n \b HID_DEVICE_SUCCESS //! \n \b HID_DEVICE_NOT_OPENED //! \n \b HID_DEVICE_TRANSFER_TIMEOUT //! \n \b HID_DEVICE_TRANSFER_FAILED // //****************************************************************************** BYTE HID_WriteFile(struct strHidDevice* pstrHidDevice, BYTE* buffer, DWORD bufferSize);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值