支持硬件输入输出的IN指令和OUT指令及测试输入和输出程序

CSDN话题挑战赛第2期
参赛话题:学习笔记

目录

一、支持硬件输入输出的IN指令和OUT指令

二、测试输入和输出程序


一、支持硬件输入输出的IN指令和OUT指令

        Windows控制硬件借助的是输入输出的指令。其中具有代表性的两个输入输出指令就是IN和OUT指令。这些指令也是汇编语言的助记符

 可以通过IN和OUT指令来实现对数据的读入和输出,如下图所示

IN指令和OUT指令:

3d1d0bd572704f7fad41e330ff1f50a1.png

        也就是说,IN指令通过指定的端口号输入数据,OUT指令则是把CPU寄存器中存储的数据输出到指定端口号的端口。

        那么这个 端口号端口是什么呢?你感觉它像不像港口一样?通过标注哪个港口然后进行货物的运送和运出?

下面我们来看一下官方是如何定义端口号和端口的

        还记得计算机组成原理中计算机的五大组成部分吗,再来回顾一下:运算器、控制器、存储器、输入设备和输出设备。我们今天不谈前三个,就说说后面两个输入设备和输出设备,这两个与我们本节主题息息相关

        那么问题来了,IO设备如何实现输入和输出的呢?计算机主机中,附带了用来连接显示器以及键盘等外围设备的 连接器。而连接器的内部,都连接有用来交换计算机主机同外围设备之间电流特性的IC.如果IC你不明白是什么的话,这些IC统称为 I0 控制器

        IO是Input/Output的缩写。显示器、键盘等外围设备都有各自专用的1/O控制器。I/0 控制器中有用于临时保存输入输出数据的内存。这个内存就是 端口(port).端口你就可以把它理解为我们上述说的港口。I0控制器内部的内存,也被称为 寄存器,不要慌,这个寄存器和内存中的寄存器不一样。CPU内存的寄存器是用于进行数据运算处理的,而IO中的寄存器是用于临时存储数据的

        在I/O设备内部的IC中,有多个端口。由于计算机中连接着很多外围设备,因此也就有很多1/O控制器。当然也会有多个端口,一个I/0控制器可以控制多个设备,不仅仅只能控制一个。各端口之间通过端口号 进行区分

        端口号也被称为 I/0地址。IN指令和OUT 指令在端口号指定的端口和CPU之间进行数据的输入和输出。这跟通过内存的地址来对内存进行读写是一样的道理。

以端口为桥梁实现CPU和外围设备的数据传递:

cf6392f1dc814584a629a07e6a958a09.png

二、测试输入和输出程序

        首先让我们利用IN指令和OUT指令,来进行一个直接控制硬件的实验。假如试验的目的是让一个计算机内置的喇叭(蜂鸣器)发出声音。蜂鸣器封装在计算机内部,但它也是外围设备的一种

        用汇编语言比较繁琐,这次我们用C语言来实现。在大部分C语言的处理(编译器的种类)中,只要使用_asm{ 和 }括起来,就可以在其中记述助记符。也就是说,采用这种方式就能够使用C语言和汇编语言混合的源代码

        在AT兼容机中,蜂鸣器的默认端口号是61H,末尾的H表示的是十六进制数的意思。用IN指令通过该端口号输入数据,并将数据的低2位设定为ON,然后再通过该端口号用OUT指令输出数据,这时蜂鸣器就会发出声音。同样的方法,将数据的低2位设定为OFF并输出后,蜂鸣器就停止工作

        位设定为ON指的是将该位设定为1,位设定为OFF 指的是将该位设定为0.把位设定为ON,只需要把想要设定为ON的位设定为1,其他位设定为0后进行OR运算即可。由于这里需要把低2位置为1,因此就是和03H进行OR运算。03H用8为二进制来表示的话是00000011.由于即便高6位存在着具体意义。和0进行OR运算后也不会发生变化,因而就和03H进行OR运算。把位设定为OFF,只需要把想要置OFF的位设定为0,其他位设定为1后进行AND运算即可。由于这里需要把低2位设定为0

        因此就要和FCH进行AND运算。在源代码中,FCH是用OFCH来记述的。在前面加0是汇编语言的规定,表示的是以A-F这些字符开头的十六进制数是数值的意思。OFCH用8位二进制数来表示的话是11111100.由于即便高6位存在着具体意义,和1进行AND运算后也不会产生变化,因而就是同OFCH进行OR运算

void main(){

    //计数器
    int i;

    //蜂鸣器发生
    _asm{
        IN  EAX, 61H
        OR  EAX, 03H
        OUT 61H, EAX
    }

    // 等待一段时间
    for(i = 0; i < 1000000; i++);

    //蜂鸣器停止发生
    _asm{
        IN  EAX, 61H
        OR  EAX, 03H
        OUT 61H, EAX
    }
}

        我们对上面的代码进行说明,main是C语言程序起始位置的函数。在该函数中,有两个用_asm {}围起来的部分,它们中间有一个使用for 循环的空循环

        首先是蜂鸣器发声的部分,通过IN EAX,61H(助记符不区分大小写)指令,把端口61H的数据存储到CPU的EAX寄存器中。接下来,通过OREAX,03H指令,把EAX寄存器的低2位设定成ON.最后,通过OUT 61H,EAX指令,把EAX寄存器的内容输出到61端口。使蜂鸣器开始发音。虽然EAX寄存器的长度是32位,不过由于蜂鸣器端口是8位,所以只需对下8位进行OR运算和AND运算就可以正常工作了

        其次是一个重复100次的空循环,主要是为了在蜂鸣器开始发音和停止发音之间稍微加上一些时间间隔。因为现在计算机器的运行速度非常快,哪怕是100万次循环,也几乎是瞬时间完成的

        然后是用来控制器蜂鸣器停止发声的部分。首先,通过IN EAX,61H指令,把端口61H的数据存储到CPU的EAX寄存器中。接下来,通过AND EAX,OFCH指令,把EAX寄存器的低2位设定为OFF.最后,通过OUT 61H,EAX指令,把寄存器的EAX内容输出到61号端口,使蜂鸣器停止发音。

 

  • 15
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夏志121

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值