惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - Franky
N
Netflix TechBlog - Medium
Google Online Security Blog
Google Online Security Blog
月光博客
月光博客
量子位
酷 壳 – CoolShell
酷 壳 – CoolShell
V
V2EX
腾讯CDC
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 聂微东
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
M
MIT News - Artificial intelligence
Vercel News
Vercel News
The GitHub Blog
The GitHub Blog
Hugging Face - Blog
Hugging Face - Blog
博客园 - 【当耐特】
Apple Machine Learning Research
Apple Machine Learning Research
aimingoo的专栏
aimingoo的专栏
博客园 - 三生石上(FineUI控件)
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
MongoDB | Blog
MongoDB | Blog
H
Help Net Security
The Cloudflare Blog
Blog — PlanetScale
Blog — PlanetScale
F
Full Disclosure
G
Google Developers Blog
罗磊的独立博客
Jina AI
Jina AI
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Y
Y Combinator Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
J
Java Code Geeks
A
About on SuperTechFans
IT之家
IT之家
大猫的无限游戏
大猫的无限游戏
S
SegmentFault 最新的问题
有赞技术团队
有赞技术团队
GbyAI
GbyAI
雷峰网
雷峰网
T
The Blog of Author Tim Ferriss
The Register - Security
The Register - Security
U
Unit 42
D
Docker
Martin Fowler
Martin Fowler
L
LINUX DO - 热门话题
NISL@THU
NISL@THU
阮一峰的网络日志
阮一峰的网络日志
C
Cybersecurity and Infrastructure Security Agency CISA
博客园_首页
Google DeepMind News
Google DeepMind News

faryou的博客

5月月考 - faryou的博客 - 日记 faryou的博客-五一回老家 【汇编 - 功能】中断安装中断实现 【汇编&硬件】时钟中断的具体实现 faryou的博客-这些年,我不再看《熊出没》 【汇编&硬件】关机中断的具体实现 【汇编&硬件】网络连接相关中断的具体实现 faryou的博客-年初小记 【汇编&硬件】鼠标控制中断的具体实现 【汇编&硬件】声音输出中断的具体实现 【汇编&硬件】屏幕输出中断的具体实现 【汇编&硬件】磁盘读取中断的具体实现 【汇编&硬件】键盘读取中断的具体实现 【汇编】汇编环境的搭建及Debug的使用教程 【汇编】漫谈:学习汇编后的一些思考 faryou的博客-关于本站即日起实行“一站三体”运营制度 【汇编基础教程】完结篇 写在最后:前言 【汇编基础教程】使用BIOS的中断实现键盘输入及磁盘I/O 【汇编基础教程】中断 【汇编基础教程】标志寄存器 【汇编基础教程】再谈栈 【汇编基础教程】段 【汇编基础教程】来存一些数据! 【汇编基础教程】寄存器和内存&一些基本命令的说明 【汇编基础教程】来写个“函数” 【汇编基础教程】更灵活的定位内存 【汇编基础教程】理解一下[bx]和loop指令 【汇编基础教程】跳一跳! faryou的博客-我的竞赛经历&对人生的一些思考 faryou的博客-关于现在中小学计算机课的一些想法及思考 faryou的博客-2025年度总结 faryou的博客-临平山下十五年 faryou的博客-Windows 10即将停止支持,谈谈自己从小到大用电脑的感受 faryou的博客-谈谈一名10后的怀旧情怀 【汇编基础教程】8086CPU工作原理 【C语言】指针的理解与应用 【算法教程】【C/C++】DP(动态规划):区间DP——程序设计思路与代码实现 【算法教程】【C/C++】BFS(广度优先搜索)——程序设计思路与代码实现 【算法教程】【C/C++】DFS(深度优先搜索)——程序设计思路与代码实现 【算法教程】【C/C++】单源最短路径——程序设计思路与代码实现 【算法教程】【C/C++】最小生成树——程序设计思路与代码实现 【算法教程】【C/C++】并查集——程序设计思路与代码实现 【算法教程】【C/C++】DP(动态规划):背包DP——程序设计思路与代码实现 【算法教程】【C/C++】DP(动态规划):简单动规问题——程序设计思路与代码实现 【算法教程】【C/C++】递推——程序设计思路与代码实现 【算法教程】【C/C++】三分算法——程序设计思路与代码实现 【算法教程】【C/C++】二分答案——程序设计思路与代码实现 【算法教程】【C/C++】二分查找——程序设计思路与代码实现 【算法教程】【C/C++】贪心算法——程序设计思路与代码实现 【算法教程】【C/C++】基础数学:快排——程序设计思路与代码实现 【算法教程】【C/C++】基础数学:快速幂——程序设计思路与代码实现 【算法教程】【C/C++】基础数学:进制转换——程序设计思路与代码实现 一文弄懂C++中的自定义函数 faryou的博客-2024年度总结
【汇编基础教程】端口
作者: faryou · 2026-01-30 · via faryou的博客

前言&端口简介

(本文有点长,相比之前的内容也更有意思,请耐心食用~)
电脑作为一个由各零件拼凑成的整体,以CPU为核心,管理其他的硬件。端口,就是联系CPU与其他硬件的一个中间规范。各硬件把功能封装好,CPU通过端口访问,实现交互。本文以CMOS RAM为例,介绍端口的使用方法。

in指令和out指令

在8086CPU中,只有in指令和out指令这两条,能够对端口进行操作,其使用格式如下:
in指令(从端口读入数据)

in al,端口号(若为0~255号直接用常数指明,若为256~65535号则先将号码放在dx中,再在此处填写dx);本指令用于访问8位端口
in ax,端口号(同上);本指令用于访问16位端口

out指令(输出数据到端口)

out 端口号(同上),al;本指令用于访问8位端口
out 端口号(同上),ax;本指令用于访问16位端口

需要注意的是,在使用in指令和out指令时,读入和读出的数据都存放在固定寄存器中(8位端口对应al,16位端口对应ax),如果改动会出错。

CMOS RAM简介

CMOS RAM是一种芯片,存放了电脑中的时间信息及其他一些系统配置,其中有一块128字节的RAM可以读取。其只有70h和71h两个端口。我们作为初学者可以用它作为端口学习的一个简单实例,今天我们写一个小程序,用端口读入其时间并显示在屏幕上。下面说明其使用:
70h:地址端口,存放要访问的CMOS RAM单元的地址。
71h:数据端口,存放70h端口中指定地址的数据。
由此可见,我们如果要读取CMOS RAM的x(x为0~255的正整数)号单元,只需要先将x送入端口70h,再从71h读取结果即可。
在CMOS RAM中,秒、分、时、日、月、年信息依次存放在0、2、4、7、8、9单元中。用BCD码的形式存放,即用8位二进制分割为两个4位,高4位存十位,低4位存个位。例如,00010100b表示14。

如何输出内容到屏幕上

今天我们即将写出第一个输出结果到屏幕上的程序~下面介绍显示缓冲区:
在80*25彩色字符模式下,内存中B8000h~BFFFFh为显示缓冲区,分为8页,通常情况下显示第0页,即B8000h~B8F9Fh中的字符,显示时会将显示缓冲区中的内容转为ASCLL码后输出。
一个字符的信息存在一个字中,其中前一个字节放字符,后一个字节放属性
下面为一个属性字节所包含的信息:

位数(二进制位)76543210
含义闪烁背景背景背景高亮前景前景前景
对应颜色 绿

例如:
红底绿字:01000010B 红底闪烁黄字:11000110B
紫底黑字:01010000B 蓝底高亮白字:01001111B
以此类推,可以根据光学三原色互相合成调出8种颜色。

移位指令

shl和shr为逻辑移位指令,其中shl为左移,shr为右移。功能类似C语言的<<及>>。使用格式:

shl/shr 原数据(存放在的寄存器名),移位量(0~8)。

程序编写

终于介绍完全部的知识了,下面整理一下思路:

  1. 从CMOS RAM中读出一个字节
  2. 将该字节以十进制输出(原数+30h)
  3. 重复以上步骤,并将其格式化为“年/月/日 时:分:秒”的格式(前面日期用红底白字,后面时间用黑底高亮黄字)

以下为代码:

assume cs:code
code segment
start:
      mov bx,0b800h
      mov es,bx
      mov cl,4
      
      mov al,9
      out 70h,al
      in al,71h
      mov ah,al
      shr ah,cl
      and al,00001111b
      add ah,30h
      add al,30h
      mov byte ptr es:[0],ah
      mov byte ptr es:[1],01000111b
      mov byte ptr es:[2],al
      mov byte ptr es:[3],01000111b
      
      mov al,2Fh
      mov byte ptr es:[4],al
      mov byte ptr es:[5],01000111b
      
      mov al,8
      out 70h,al
      in al,71h
      mov ah,al
      shr ah,cl
      and al,00001111b
      add ah,30h
      add al,30h
      mov byte ptr es:[6],ah
      mov byte ptr es:[7],01000111b
      mov byte ptr es:[8],al
      mov byte ptr es:[9],01000111b
      
      mov al,2Fh
      mov byte ptr es:[10],al
      mov byte ptr es:[11],01000111b
      
      mov al,7
      out 70h,al
      in al,71h
      mov ah,al
      shr ah,cl
      and al,00001111b
      add ah,30h
      add al,30h
      mov byte ptr es:[12],ah
      mov byte ptr es:[13],01000111b
      mov byte ptr es:[14],al
      mov byte ptr es:[15],01000111b
      
      mov al,4
      out 70h,al
      in al,71h
      mov ah,al
      shr ah,cl
      and ah,00001111b
      add ah,30h
      add al,30h
      mov byte ptr es:[20],ah
      mov byte ptr es:[21],00001110b
      mov byte ptr es:[22],al
      mov byte ptr es:[23],00001110b
      
      mov al,3Ah
      mov byte ptr es:[24],al
      mov byte ptr es:[25],00001110b
      
      mov al,2
      out 70h,al
      in al,71h
      mov ah,al
      shr ah,4
      and 00001111b
      add ah,30h
      add al,30h
      mov byte ptr es:[26],ah
      mov byte ptr es:[27],00001110b
      mov byte ptr es:[28],al
      mov byte ptr es:[29],00001110b
      
      mov al,3Ah
      mov byte ptr es:[30],al
      mov byte ptr es:[31],00001110b
      
      mov al,0
      out 70h,al
      in al,71h
      mov ah,al
      shr ah,cl
      and ah,00001111b
      add ah,30h
      add al,30h
      mov byte ptr es:[32],ah
      mov byte ptr es:[33],00001110b
      mov byte ptr es:[34],al
      mov byte ptr es:[35],00001110b
      
      mov ax,4c00h
      int 21h

code ends
end start

(没有用循环,导致出现了挺多冗余代码的,各位可以试试用循环+子程序简化程序~)