【译】x86程序员手册30-8.2 I/O指令-程序员宅基地

技术标签: 操作系统  

8.2 I/O Instructions I/O指令

 

The I/O instructions of the 80386 provide access to the processor's I/O ports for the transfer of data to and from peripheral devices. These instructions have as one operand the address of a port in the I/O address space. There are two classes of I/O instruction:

80386IO指令用来访问处理器的IO端口,来和外围设备之间传送数据。这些指令有一个位于IO地址空间的端口地址作为操作数。IO指令分成两类:

  1. Those that transfer a single item (byte, word, or doubleword) located in a register.

传送寄存器中的单个项目(字节、字或双字)。

  1. Those that transfer strings of items (strings of bytes, words, or doublewords) located in memory. These are known as "string I/O instructions" or "block I/O instructions".

传送内存中的字符串项目(字节、字或双字构成的字符串)。这些指令也被叫做“字符串IO指令”或“块传送IO指令”。

8.2.1 Register I/O Instructions 寄存器IO指令

 

The I/O instructions IN and OUTare provided to move data between I/O ports and the EAX (32-bit I/O), the AX (16-bit I/O), or AL (8-bit I/O) general registers. IN andOUTinstructions address I/O ports either directly, with the address of one of up to 256 port addresses coded in the instruction, or indirectly via the DX register to one of up to 64K port addresses.

IN、OUT这两个IO指令用来在EAX(32位IO)、AX(16位IO)或AL(8位IO)这些通用寄存器和IO端口之间传送数据。IN和OUT指令寻址IO端口即可以是直接的,好使用最多256个端口之一的地址编码在指令中,也可以是非直接的,而是通过DX寄存器使用最多达64K的端口地址。

IN (Input from Port) transfers a byte, word, or doubleword from an input port to AL, AX, or EAX. If a program specifies AL with the IN instruction, the processor transfers 8 bits from the selected port to AL. If a program specifies AX with the IN instruction, the processor transfers 16 bits from the port to AX. If a program specifies EAX with the IN instruction, the processor transfers 32 bits from the port to EAX.

IN(从端口输入)从一个输入端口传送一个字节、字或双字到AL、AX或EAX寄存器。如果程序在IN指令中指定AL,处理器从选定的端口中传送8位数据到AL中。如果指定AX,则传送16位数据,如果指定EAX,则处理器传送32位数据。

OUT(Output to Port) transfers a byte, word, or doubleword to an output port from AL, AX, or EAX. The program can specify the number of the port using the same methods as the IN instruction.

OUT(向端口输出)将AL、AX或EAX寄存器中的字节、字或双字传送到输出端口。正如IN指令一样,程序可以使用同样的方式来指定一个端口号码。

 

8.2.2 Block I/O Instructions 块传送IO指令

 

The block (or string) I/O instructions INS and OUTS move blocks of data between I/O ports and memory space. Block I/O instructions use the DX register to specify the address of a port in the I/O address space. INS and OUTSuse DX to specify:

块(或叫字符串)传送IO指令INS和OUTS在IO端口与内存空间之间传送数据块。块IO指令使用DX寄存器来指定一个在IO地址上的端口地址。

  • 8-bit ports numbered 0 through 65535 

8位端口,数值从0到65535

  • 16-bit ports numbered 0, 2, 4, . . . , 65532, 65534

16位端口,数值从0,2,4,...,65532,65534

  • 32-bit ports numbered 0, 4, 8, . . . , 65528, 65532

32位端口,数值从0,4,8,...,65528,65532

Block I/O instructions use either SI or DI to designate the source or destination memory address. For each transfer, SI or DI are automatically either incremented or decremented as specified by the direction bit in the flags register.

IO指令使用SI或DI来指定源或目的内存地址。每次传送,根据标志寄存器中的方向位的设置,SI或DI都自动增加或减少。

INS and OUTS, when used with repeat prefixes, cause block input or output operations. REP, the repeat prefix, modifies INS and OUTS to provide a means of transferring blocks of data between an I/O port and memory. These block I/O instructions are string primitives (refer also to Chapter 3 for more on string primitives). They simplify programming and increase the speed of data transfer by eliminating the need to use a separate LOOP instruction or an intermediate register to hold the data.

在使用重复前缀时,INS和OUTS都会引发块输入或输出操作。REP,重复前缀,用来修饰INS和OUTS指令,以能够提供内存与IO端口之间的数据块传输。这些块IO指令是字符串原语(参见第3章关于字符串原语的更多内容)。它们使程序更加简化,并通过删除对独立的LOOP指令或保存数据的中间寄存器的需求从而加快了数据传输。

The string I/O primitives can operate on byte strings, word strings, or doubleword strings. After each transfer, the memory address in ESI or EDI is updated by 1 for byte operands, by 2 for word operands, or by 4 for doubleword operands. The value in the direction flag (DF) determines whether the processor automatically increments ESI or EDI (DF=0) or whether it automatically decrements these registers (DF=1).

字符串IO原语可以对字节、字或双字构成的字符串进行操作。在每次传输后,ESI或EDI中的内存地址以1(字节操作数)、2(字操作数)或4(双字操作数)的变化量更新。方向标志(DF)的值决定处理器自动增加ESI或EDI的值(DF = 0)或减少这些寄存器值(DF = 1)。

INS(Input String from Port) transfers a byte or a word string element from an input port to memory. The mnemonics INSBINSW, and INSD are variants that explicitly specify the size of the operand. If a program specifies INSB, the processor transfers 8 bits from the selected port to the memory location indicated by ES:EDI. If a program specifies INSW, the processor transfers 16 bits from the port to the memory location indicated by ES:EDI. If a program specifies INSD, the processor transfers 32 bits from the port to the memory location indicated by ES:EDI. The destination segment register choice (ES) cannot be changed for the INS instruction. Combined with the REP prefix, INS moves a block of information from an input port to a series of consecutive memory locations.

INS(从端口输入字符串)从内存中的输入端口传输一个字节或字的字符串元素。助记符INSB、INSW和INSD是变形指令,用来指定操作数的大小。如果程序使用INSB,处理器从选择的端口中传送8位到ES:EDI指定上的内存中。而INSW则传送16位,INSD则传送32位。INS指令中的目的段寄存器选择(ES)不能被修改。与REP前缀组合使用时,INS从一个输入端口移动一个信息块到指定上的连续内存中。

OUTS (Output String to Port) transfers a byte, word, or doubleword string element to an output port from memory. The mnemonics OUTSBOUTSW, and OUTSD are variants that explicitly specify the size of the operand. If a program specifies OUTSB, the processor transfers 8 bits from the memory location indicated by ES:EDI to the the selected port. If a program specifies OUTSW, the processor transfers 16 bits from the memory location indicated by ES:EDI to the the selected port. If a program specifies OUTSD, the processor transfers 32 bits from the memory location indicated by ES:EDI to the the selected port. Combined with the REP prefix, OUTS moves a block of information from a series of consecutive memory locations indicated by DS:ESI to an output port.

OUTS(向端口输出字符串)从内存中向输出端口传送一个字、字节或双字的字符串元素。助记符OUTSB、OUTSW和OUTSD是变形指令,用来指定操作数大小。如果程序指定OUTSB,则处理器从ES:EDI指明的内存地址中取8位数据输出到选定的端口上。同理,如果指定OUTSW,则传送16位数据,指定OUTSD,则传送32位数据。与REP前缀组合时,OUTS从DS:ESI指定的连续内存中取信息块移到输出端口。(译注:这里是不是有错误呢?为什么OUTS不与REP组合时,使用的是EDI寄存器?)

8.3 Protection and I/O 保护与I/O

Two mechanisms provide protection for I/O functions:

对于I/O功能有两种保护机制:

  1. The IOPL field in the EFLAGS register defines the right to use I/O-related instructions.

EFLAGS寄存器的IOPL字段定义了使用I/O相关指令的权限。

  1. The I/O permission bit map of a 80386 TSS segment defines the right to use ports in the I/O address space.

80386的TSS段的I/O允许位图定义了使用位于I/O地址空间端口的权限。

These mechanisms operate only in protected mode, including virtual 8086 mode; they do not operate in real mode. In real mode, there is no protection of the I/O space; any procedure can execute I/O instructions, and any I/O port can be addressed by the I/O instructions.

这些机制仅在保护模式下使用,包括虚拟8086模式;不能在实模式下使用。在实模式下,不对I/O空间进行保护;任何程序都可以执行I/O指令,任何I/O端口都可以被I/O指令寻址。

 

8.3.1 I/O Privilege Level I/O特权级别

 

Instructions that deal with I/O need to be restricted but also need to be executed by procedures executing at privilege levels other than zero. For this reason, the processor uses two bits of the flags register to store the I/O privilege level (IOPL). The IOPL defines the privilege level needed to execute I/O-related instructions.

处理I/O的指令需要被约束,那些运行在除特权0级外的程序也需要执行它们。为此,处理器使用标志寄存器的两个位来存储I/O特权级别(IOPL)。IOPL定义了需要运行I/O相关指令的特权级别。

The following instructions can be executed only if CPL <= IOPL:

下面的指令仅当CPL小于或等于IOPL时可以被执行:

  • IN -- Input 输入
  • INS -- Input String 输入串
  • OUT -- Output 输出
  • OUTS -- Output String 输出串
  • CLI -- Clear Interrupt-Enable Flag 清除中断使能标志位
  • STI -- Set Interrupt-Enable 设置中断使能

These instructions are called "sensitive" instructions, because they are sensitive to IOPL.

因类它们对IOPL敏感,所以这些指令被叫做“敏感”指令。

To use sensitive instructions, a procedure must execute at a privilege level at least as privileged as that specified by the IOPL (CPL <= IOPL). Any attempt by a less privileged procedure to use a sensitive instruction results in a general protection exception.

为使用敏感指令,程序必须执行在IOPL指定的特权级别上(CPL <= IOPL)。任何较低特权的程序企图使用敏感指令,都会引发一般性保护异常。

Because each task has its own unique copy of the flags register, each task can have a different IOPL. A task whose primary function is to perform I/O (a device driver) can benefit from having an IOPL of three, thereby permitting all procedures of the task to perform I/O. Other tasks typically have IOPL set to zero or one, reserving the right to perform I/O instructions for the most privileged procedures.

因为每个任务都有自己的唯一的标志寄存器的拷贝,每个任务都可以有不同的IOPL。一个主要功能是操作I/O的任务(设备驱动)都可以从下面受益,拥有一个3级的IOPL,这样允许该任务的所有程序执行I/O操作。典型的,其他任务的IOPL都被设为0或1,这样就将执行I/O指令的权力保留给了更高级特权的程序。

A task can change IOPL only with the POPF instruction; however, such changes are privileged. No procedure may alter IOPL (the I/O privilege level in the flag register) unless the procedure is executing at privilege level 0. An attempt by a less privileged procedure to alter IOPL does not result in an exception; IOPL simply remains unaltered.

任务仅可通过POPF指令修改IOPL;然而,这个修改是特权级的。没有程序可以更改IOPL(标志寄存器中的I/O特权级别),除非这个程序执行在特权级0上。较低特权级别的程序企图更改IOPL不会导致异常;IOPL简单地保持未被变更状态。

The POPF instruction may be used in addition to CLI and STI to alter the interrupt-enable flag (IF); however, changes to IF by POPF are IOPL-sensitive. A procedure may alter IF with a POPF instruction only when executing at a level that is at least as privileged as IOPL. An attempt by a less privileged procedure to alter IF in this manner does not result in an exception; IF simply remains unaltered.

POPF指令也被CLI和STI指令来更改中断使能标志(IF);然而,通过POPF修改IF是IOPL敏感的。仅当一个程序运行在与IOPL相比最小的特权级别上时,才可以使用POPF来更改IF。较低特权上的程序企图以这种方式变更IF不会引发异常;IF简单地保持原值。

8.3.2 I/O Permission Bit Map I/O权限位图

 

The I/O instructions that directly refer to addresses in the processor's I/O space are ININSOUTOUTS. The 80386 has the ability to selectively trap references to specific I/O addresses. The structure that enables selective trapping is the I/O Permission Bit Map in the TSS segment (see Figure 8-2). The I/O permission map is a bit vector. The size of the map and its location in the TSS segment are variable. The processor locates the I/O permission map by means of the I/O map base field in the fixed portion of the TSS. The I/O map base field is 16 bits wide and contains the offset of the beginning of the I/O permission map. The upper limit of the I/O permission map is the same as the limit of the TSS segment.

直接引用处理器的I/O空间的地址的I/O操作指令有IN、INS、OUT和OUTS。80386可以指定I/O地址。这个可以精心选择的trapping结构是TSS段中的I/O权限位图(见图8-2)。I/O权限位图是一个位向量。图的大小和在TSS段中的位置是可变的。处理器通过在TSS中定长部分的I/O位图基址字段的含义来定位I/O权限图。I/O图基址字段16位宽,包含I/O权限图的开始处的偏移量。I/O权限图的限长等于TSS段的限长。

 

 

In protected mode, when it encounters an I/O instruction (ININSOUT, or OUTS), the processor first checks whether CPL <= IOPL. If this condition is true, the I/O operation may proceed. If not true, the processor checks the I/O permission map. (In virtual 8086 mode, the processor consults the map without regard for IOPL . Refer to Chapter 15.)

在保护模式下,当最到一个I/O指令(IN、INS、OUT或OUTS)时,处理器首先检查CPL是否大于或等于IOPL。如果条件为真,I/O操作可以执行。如果不为真,处理器检查I/O权限图。(在虚拟8086模式,处理器不管IOPL,只参考位图。参见第15章。)

Each bit in the map corresponds to an I/O port byte address; for example, the bit for port 41 is found at I/O map base + 5, bit offset 1. The processor tests all the bits that correspond to the I/O addresses spanned by an I/O operation; for example, a doubleword operation tests four bits corresponding to four adjacent byte addresses. If any tested bit is set, the processor signals a general protection exception. If all the tested bits are zero, the I/O operation may proceed.

图中的每一位都对应一个I/O端口的字节地址;例如,端口41的对应位在I/O图的基址 + 5处,位的偏移为1。处理器对I/O操作涉及的所有I/O地址的对应位都进行测试;例如,一个双字操作测试一个以4对齐的字节地址所对应的4个位。如果任何位被设置,处理器发送一个一般保护异常。如果所以测试的位都是0,则I/O操作可以执行。

It is not necessary for the I/O permission map to represent all the I/O addresses. I/O addresses not spanned by the map are treated as if they had one bits in the map. For example, if TSS limit is equal to I/O map base + 31, the first 256 I/O ports are mapped; I/O operations on any port greater than 255 cause an exception.

对于IO权限位图,代表所有的I/O地址是不必要的。不被图所包含的I/O地址被视为在图中的位为1。例如,如果TSS限长等于I/O图基址 + 31,第一个256I/O端口被映射;任何对端口大于255的I/O操作都会导致异常。

If I/O map base is greater than or equal to TSS limit, the TSS segment has no I/O permission map, and all I/O instructions in the 80386 program cause exceptions when CPL > IOPL.

如果I/O图基址大于或等于TSS限长,则TSS段没有I/O权限位图,所有80386程序中的IO指令在CPL > IOPL时都会引发异常。

Because the I/O permission map is in the TSS segment, different tasks can have different maps. Thus, the operating system can allocate ports to a task by changing the I/O permission map in the task's TSS.

因为I/O权限图在TSS段中,不同任务可以有不同的位图。这样,操作系统可以通过修改在任务TSS中的I/O权限位图来给任务分配端口。

转载于:https://www.cnblogs.com/mqmelon/p/6692705.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_30332705/article/details/96247858

智能推荐

rnn pytorch_pytorch介绍rnn字符级文本生成-程序员宅基地

文章浏览阅读765次。rnn pytorchToday, we’ll continue our journey through the fascinating world of natural language processing (NLP) by introducing the operation and use of recurrent neural networks to generate text from ..._为啥seed the rnn with the input sentence.

DICOMRT-DiBugs:dicomParser解析无头DICOM与cornerstone显示RGB-DICOM错误_dicom_parser-程序员宅基地

文章浏览阅读2.8k次。背景介绍cornerstone几乎是所有做B/S架构必要的学习框架,之前博文刚介绍过,cornerstone本身并不解析DICOM数据,而是依赖于dicomParser.js这个前端库。dicomParser库对DICOM格式的兼容性,目前是远远落后于dcmtk、dcm4che、fo-dicom这类后端库的,其本身并不是因为前/后端语言的差异,更多的是因为之前的解析都是放在后端,所以对前端库的维护和更新比较匮乏。DICOMer星球,每日更新知识点,欢迎加入,一起交流学习!此博文是DiBugs(即DI_dicom_parser

基于Qt ffmpeg opengl开发跨平台安卓实时投屏软件QtScrcpy_基于qt ffmpeg开发跨平台安卓实时投屏软件-程序员宅基地

文章浏览阅读10w+次,点赞103次,收藏297次。基于Qt ffmpeg opengl开发跨平台安卓实时投屏软件课程介绍课程地址:https://edu.csdn.net/course/detail/10750本课程是一个音视频相关的Qt项目的实战教程,涉及Qt开发实际项目的完整流程。基于qt ffmpeg opengl实现了安卓手机实时投屏到电脑端,电脑端键鼠控制安卓手机的功能。可以自定义按键映射从而实现键鼠玩吃鸡手游的效果。基于Qt的跨..._基于qt ffmpeg开发跨平台安卓实时投屏软件

从世界最大的博客网站的基于xml的网站架构看它的缺点-程序员宅基地

文章浏览阅读1.8k次。在不短的时间里,我一直以为blogspot.com是一个不成熟的站点,以至于用户写完文章是无法看到的,直到我知道这是世界上最大的最早地也是最成功的博客站点,同时也是google的唯一战略联盟伙伴时,才意识到这是不可能的:一定是让中国网安给封闭了。中国网安乐于封闭海外媒体站点,特别是海外有中文信息提供的媒体站点,动机是可以理解的,只要各位想想《包身工》中的一段话:“只要不接触到外面的新鲜空气,发霉的

储能行业 | 储能EMS | 一次侧与二次侧 | 削峰填谷 | 防逆流 | 需量控制 | AC-DC | DC-DC | A网与B网 | 并网点 | DI与DO | 计划曲线 | 峰谷套利_最大需量控制-程序员宅基地

文章浏览阅读1k次,点赞8次,收藏20次。储能EMS(Energy Management System)是指储能系统的管理系统,用于监控、控制和优化储能设备的运行。储能EMS通过实时监测和分析电网和储能设备的状态,以及预测和优化能源需求和供应,实现对储能系统的智能化管理。能量管理:监测和管理储能设备的充放电过程,确保能量的高效利用。功率平衡:根据电网负荷需求和储能设备的状态,调整储能系统的输出功率,实现电网负荷平衡。频率调节:根据电网频率变化,调整储能系统的输出功率,维持电网频率稳定。_最大需量控制

记一次自定义拦截器失效的问题排查_自定义拦截器里打断点进不去-程序员宅基地

文章浏览阅读170次。记一次自定义拦截器失效的问题排查_自定义拦截器里打断点进不去

随便推点

倒数计时类_arduino倒数日代码-程序员宅基地

文章浏览阅读876次。倒数计时类 html>head>script type="text/javascript">...var Class = ...{ create: function() ...{ return function() ...{ this.initialize.apply(this, arguments); } }}//倒数计时类var Countdown = C_arduino倒数日代码

【QT】QT自定义C++类_qt在类中添加-程序员宅基地

文章浏览阅读788次。建立项目后,添加类MyBtn,Base class中可以直接输入QPushButton作为继承类新建自定义方法 void SetMyText(QString str),MyBtn.h// 自定义添加类,写代码前,要先编译一下,确保没有错误,再继续写。Q_OBJECTpublic:MyBtn.cpp新建类完成。_qt在类中添加

PHP数组函数 array_reverse (反转数组)-程序员宅基地

文章浏览阅读4.1k次。在PHP中,数组函数 array_reverse() 用来反转数组的元素。函数语法:array_reverse(array$array[,bool$preserve_keys=FALSE]):array函数参数说明:参数 描述 array 必需。规定数组。 preserve_keys 可选。规定是否保留原始数组的键名。 如果设置为 TRUE 会保留数字的键。 非数字的键则不受这个设置的影响,总是会被保留。 ..._array_reverse

【转】Ubuntu 16.04 Nvidia驱动安装(run方式)_ubuntu下载nvidia驱动后怎么运行下载的.run文件-程序员宅基地

文章浏览阅读756次。转自:Ubuntu 16.04 Nvidia驱动安装(run方式)_lihe的博客-程序员宅基地1.下载驱动程序Nvidia驱动下载https://www.geforce.cn/drivers/beta-legacyhttp://www.nvidia.cn/Download/index.aspx根据显卡选择适用的驱动版本,下载完之后是一个名称为 NVIDIA-Linux-x86_64-xxx.xx.run 的文件(我的显卡为GTX1060,NVIDIA-Linux-x86_64-418.56_ubuntu下载nvidia驱动后怎么运行下载的.run文件

【Android】Android Framework系列---输入法服务_android 输入法-程序员宅基地

文章浏览阅读712次。车载项目需要定制输入法,也有一些POC演示的项目使用原生比如LatinIME(源码路径为/packages/inputmethods/LatinIME),关于输入法可能会遇到以下一些问题输入法进程启动崩溃输入法画面被其他应用遮挡输入法输入内容显示到错误的编辑框内多屏情况下输入法显示异常输入法未弹出或输入法未隐藏定制多屏多客户端输入法上面举了一些常见例子,实际开发过程中也会有定制输入法服务这类需求。_android 输入法

C语言之坑二--定义不定长数组_c语言定义一个不定长数组-程序员宅基地

文章浏览阅读4.9k次。#include #include void arr(int size){if(size>0){ int a[size]; a[0]=99;} printf("%d\n",a[0]);}int main(){ arr(2);return 0; }定义变量不能再if结构里。否则程序运行行,不会给数组分配空间,而且编译时候也没有错误提示。_c语言定义一个不定长数组