程序员需要了解的硬核知识之控制硬件(一)

简介: 我们作为程序员一般很少直接操控硬件,我们一般通过 C、Java 等高级语言编写的程序起到间接控制硬件的作用。所以大家很少直接接触到硬件的指令,硬件的控制是由 Windows 操作系统 全权负责的。

应用和硬件的关系

我们作为程序员一般很少直接操控硬件,我们一般通过 C、Java 等高级语言编写的程序起到间接控制硬件的作用。所以大家很少直接接触到硬件的指令,硬件的控制是由 Windows 操作系统 全权负责的。

你一定猜到我要说什么了,没错,我会说但是,任何事情没有绝对性,环境的不同会造成结果的偏差。虽然程序员没法直接控制硬件,并且 Windows 屏蔽了控制硬件的细节,但是 Windows 却为你开放了 系统调用功能来实现对硬件的控制。在 Windows 中,系统调用称为 API,API 就是应用调用的函数,这些函数的实体被存放在 DLL 文件中。

15.png

下面我们来看一个通过系统调用来间接控制硬件的实例

假如要在窗口中显示字符串,就可以使用 Windows API 中的 TextOut 函数。TextOut 函数的语法(C 语言)如下

BOOL TextOut{
  HDC hdc,          // 设备描述表的句柄
  int nXStart,          // 显示字符串的 x 坐标
  int nYStart,                // 显示字符串的 y 坐标
  LPCTSTR lpString,     // 指向字符串的指针
  int cbString          // 字符串的文字数
}

那么,在处理 TextOut 函数的内容时,Windows 做了些什么呢?从结果来看,Windows 直接控制了作为硬件的显示器。但 Windows 本身也是软件,由此可见,Windows 应该向 CPU 传递了某种指令,从而通过软件控制了硬件。

Windows 提供的 TextOut 函数 API 可以向窗口和打印机输出字符。C 语言提供的 printf 函数,是用来在命令提示符中显示字符串的函数。使用 printf 函数是无法向打印机输出字符的。

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

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

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

16.jpg


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

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

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

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

那么问题来了,IO设备如何实现输入和输出的呢?计算机主机中,附带了用来连接显示器以及键盘等外围设备的连接器而连接器的内部,都连接有用来交换计算机主机同外围设备之间电流特性的 IC。如果 IC 你不明白是什么的话,可以参考作者的文章 程序员需要了解的硬核知识之内存 进行了解。这些 IC 统称为 IO 控制器

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

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

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

17.jpg


相关文章
给 Hexo 配置自定义域名进行访问
给 Hexo 配置自定义域名进行访问
231 0
|
缓存 安全 开发工具
Android 解决bug:Android studio 运行、编译项目时导致电脑死机
Android 解决bug:Android studio 运行、编译项目时导致电脑死机
1262 0
|
资源调度 前端开发 Shell
[docker] DevContainer高效开发(第二篇):前端开发体验
上面的配置只是最基本的配置,大部分情况我们是需要自定义配置,让容器更符合我们的需求。自定义配置就需要用到 Dockerfile,这个文件是 docker 的配置文件,可以在里面安装软件,配置环境等等。Dockerfile 的语法可以参考 官方文档。然后根据自己的需求编写 Dockerfile# 设置变量,由 .devcontainer.json 中的 args 传入# 指定 node 版本# 设置编码# 设置工作目录# 挂载 volume# 设置 bash 为默认 shell。
423 0
|
8月前
|
安全 Unix Linux
Veritas NetBackup 11 for Linux & Windows - 领先的企业备份和恢复解决方案
Veritas NetBackup 11 for Linux & Windows - 领先的企业备份和恢复解决方案
268 0
Veritas NetBackup 11 for Linux & Windows - 领先的企业备份和恢复解决方案
|
网络协议 算法 网络性能优化
【流媒体】推流与拉流简介
【流媒体】推流与拉流简介
1764 0
|
JavaScript 前端开发 Java
npm学习一:npm 包管理工具 学习、使用。
这篇文章是关于npm包管理工具的学习、使用指南,包括npm概述、基础命令和如何安装webpack。
393 3
npm学习一:npm 包管理工具 学习、使用。
|
存储 缓存 数据处理
深度解析:Hologres分布式存储引擎设计原理及其优化策略
【10月更文挑战第9天】在大数据时代,数据的规模和复杂性不断增加,这对数据库系统提出了更高的要求。传统的单机数据库难以应对海量数据处理的需求,而分布式数据库通过水平扩展提供了更好的解决方案。阿里云推出的Hologres是一个实时交互式分析服务,它结合了OLAP(在线分析处理)与OLTP(在线事务处理)的优势,能够在大规模数据集上提供低延迟的数据查询能力。本文将深入探讨Hologres分布式存储引擎的设计原理,并介绍一些关键的优化策略。
643 0
|
存储 Shell 区块链
怎么把Python脚本打包成可执行程序?
该文档介绍了如何将Python脚本及其运行环境打包成EXE可执行文件,以便在不具备Python环境的计算机上运行。首先确保Python脚本能够正常运行,然后通过安装PyInstaller并使用`--onefile`参数将脚本打包成独立的EXE文件。此外,还提供了去除命令行窗口和指定可执行文件图标的详细方法。这些步骤帮助用户轻松地将Python程序分发给最终用户。
196 3
怎么把Python脚本打包成可执行程序?
|
关系型数据库 MySQL Nacos
nacos启动报错 load derby-schema.sql error
这篇文章描述了作者在使用Nacos时遇到的启动错误,错误提示为加载derby-schema.sql失败,作者通过将数据库从Derby更换为MySQL解决了问题。
nacos启动报错 load derby-schema.sql error
|
11月前
|
Python
净利润断层策略
净利润断层策略通过分析公司财报公布后股价的异常波动来选股。当财报超预期且股价跳空高开时,视为买入信号。本文介绍了使用Python和Akshare库实现该策略的具体步骤,包括安装库、获取数据、识别断层及筛选股票等。