【Linux102】39-include/asm/io.h


公粽号「专注Linux」,专注Linux内核开发

Linux102系列会详细讲解Linux0.11版本中的102个文件,本文讲解linux0.11的第39个文件【Linux102】39-include/asm/io.h的文件源码。

1. include/asm/io.h的主要作用

io.h定义了一系列宏,这些宏是 x86 架构下直接操作硬件 I/O 端口的底层工具:

inb/outb 用于基本的端口读写,带_p后缀的版本(inb_p/outb_p)增加了延迟适配慢速设备
通过内联汇编直接控制 CPU 寄存器(AL、DX 等),实现了最高效的硬件交互
通常用于操作系统内核设备驱动等需要直接操作硬件的场景

2.源码用到的文件

NO

3.源码版

#define outb(value, port) \
    __asm__("outb %%al,%%dx" ::"a"(value), "d"(port))

#define inb(port) ({                                          \
    unsigned char _v;                                         \
    __asm__ volatile("inb %%dx,%%al" : "=a"(_v) : "d"(port)); \
    _v;                                                       \
})

#define outb_p(value, port)    \
    __asm__("outb %%al,%%dx\n" \
            "\tjmp 1f\n"       \
            "1:\tjmp 1f\n"     \
            "1:" ::"a"(value), \
            "d"(port))

#define inb_p(port) ({                             \
    unsigned char _v;                              \
    __asm__ volatile("inb %%dx,%%al\n"             \
                     "\tjmp 1f\n"                  \
                     "1:\tjmp 1f\n"                \
                     "1:" : "=a"(_v) : "d"(port)); \
    _v;                                            \
})

4.源码注释版本


// 向指定端口输出一个字节数据
// value: 要输出的数据(8位)
// port: 目标端口地址(16位)
#define outb(value, port) \
        __asm__ ("outb %%al, %%dx"  /* 汇编指令: 将AL寄存器的值输出到DX寄存器指定的端口 */ \
        :: "a" (value), "d" (port) /* 约束条件: 
                                * "a" (value): 将value放入EAX寄存器(AL是EAX的低8位)
                                * "d" (port): 将port放入EDX寄存器
                                */ \
)

// 从指定端口输入一个字节数据并返回
// port: 要读取的端口地址(16位)
// 返回值: 从端口读取的8位数据
#define inb(port) ({ \
        unsigned char _v; /* 声明临时变量存储读取的值 */ \
        __asm__ volatile ( /* volatile确保汇编不会被编译器优化掉 */ \
        "inb %%dx, %%al"  /* 汇编指令: 从DX寄存器指定的端口读取数据到AL寄存器 */ \
        : "=a" (_v)       /* 输出约束: 将EAX寄存器(AL)的值存入变量_v */ \
        : "d" (port)      /* 输入约束: 将port放入EDX寄存器 */ \
        ); \
        _v; /* 返回读取到的值 */ \
})

// 向指定端口输出一个字节数据,并加入短暂延迟
// 用于需要等待的硬件设备,确保数据已被处理
#define outb_p(value, port) \
__asm__ ( \
        "outb %%al, %%dx\n"    /* 输出数据到端口 */ \
        "\tjmp 1f\n"           /* 跳转到标签1f (1:) */ \
        "1:\tjmp 1f\n"         /* 再次跳转,创建短暂延迟 */ \
        "1:"                   /* 延迟结束的标签 */ \
        :: "a" (value), "d" (port) /* 与outb相同的寄存器约束 */ \
)

// 从指定端口输入一个字节数据,加入短暂延迟并返回
// 用于需要等待的硬件设备,确保数据已准备好
#define inb_p(port) ({ \
        unsigned char _v; /* 临时变量存储读取的值 */ \
        __asm__ volatile ( \
        "inb %%dx, %%al\n"    /* 从端口读取数据 */ \
        "\tjmp 1f\n"          /* 跳转延迟 */ \
        "1:\tjmp 1f\n"        /* 再次跳转增加延迟 */ \
        "1:"                  /* 延迟结束标签 */ \
        : "=a" (_v)           /* 输出约束: 结果存入_v */ \
        : "d" (port)          /* 输入约束: 端口地址存入EDX */ \
        ); \
        _v; /* 返回读取到的值 */ \
})

5.源码图像版

【Linux102】39-include/asm/io.h

6.源码注释版图像

【Linux102】39-include/asm/io.h



汇编语言

本系列将带领大家从0开始循序渐进学习汇编语言,直至完全掌握这门底层语言。同时给出学习平台DOSBox的使用教程。

😉【汇编语言】1—基础硬件知识

😉【汇编语言】2—寄存器基础知识

😉【汇编语言】3-寄存器与内存的交互

😉【汇编语言】4-第一个完整的汇编程序

😉【汇编语言】5-[BX]和loop指令

😉【汇编语言】6-包含多个段的程序

😉【汇编语言】7-灵活的5大寻址方式

😉【汇编语言】8-1-数据的位置

😉【汇编语言】8-2-数据的长度

😉【汇编语言】8-数据处理的两个基本问题(位置与长度)

😉【DOSBox】1-debug

😉【DOSBox】2-debug可执行文件

😉【DOSBox】3-完整开发流程


C语言

本系列将直击C语言的本质基础,流利处理出各个易错、实用的实战点,并非从零开始学习C。

😉【C语言】C Token(C89 C99 C11)

😉【C语言】指针基础

😉【C语言】数组基础

😉【C语言】结构体对齐

😉【C语言】华为C语言进阶测试

😉【C语言】触发刷新到磁盘的方式总结

😉【C语言】C语言文件操作的mode详解

😉【C语言】C语言文件知识全讲解

😉【C语言】从extern到头文件包含的最优实践

😉【C语言】C语言的关键字与重载机制

😉【C语言】长字符串的2种处理方式

😉【C语言】C语言嵌入汇编程序

😉【C语言】指针数组 VS 数组指针 原来这么简单!

😉【C语言】深浅拷贝、传参、赋值 本质剖析

😉【C语言】find-in-linux递归搜索文件名函数

😉【C陷阱与缺陷】-1-词法陷阱

😉【C陷阱与缺陷】-2-语法陷阱

😉【C陷阱与缺陷】-3-语义陷阱


Linux101系列

专注讲解Linux中的常用命令,共计发布100+文章。

😉【Linux101-1】ls

😉【Linux101-1】ls -l命令输出结果全解析

😉【Linux101-2】cd

😉【Linux101-3】cat

😉【Linux101-4】tac

😉【Linux101-5】head

😉【Linux101-6】tail

😉【Linux101-7】pwd

😉【Linux101-8】touch

😉【Linux101-9】cal

😉【Linux101-10】bc

😉【Linux101-11】df

😉【Linux101-12】uname

😉【Linux101-13】mkdir

😉【Linux101-14】gzip

😉【Linux101-15】tar

😉【Linux101-16】lsof

😉【Linux101-17】du

😉【Linux101-18】stat

😉【Linux101-19】top

😉【Linux101-20】echo


Linux102系列

本系列将精讲Linux0.11内核中的每一个文件,共计会发布100+文章。

😉【Linux102】1-Makefile

😉【Linux102】2-Makefile.header

😉【Linux102】3-system.map

😉【Linux102】4-bootsect.s

😉【Linux102】5-setup.s

😉【Linux102】6-head.s

😉【Linux102-D】/boot

😉【Linux102】7-main.c

😉【Linux102】8-kernel/asm.s

😉【Linux102】9-kernel/traps.c

😉【Linux102】10-kernel/printk.c

😉【Linux102】11-kernel/vsprintf.c

😉【Linux102】12-include/stdarg.h

😉【Linux102】13-kernel/mktime.c

😉【Linux102】14-kernel/system_call.s

😉【Linux102】15-include/linux/sched.h

😉【Linux102】18-include/signal.h

😉【Linux102】19-include/sys/types.h

😉【Linux102】20-include/linux/kernel.h

😉【Linux102】21-include/asm/segment.h

😉【Linux102】22-include/linux/head.h

😉【Linux102】23-include/linux/mm.h

😉【Linux102】24-include/linux/fs.h

😉【Linux102】25-include/errno.h

😉【Linux102】26-include/sys/wait.h

😉【Linux102】27-include/inux/tty.h

😉【Linux102】28-include/termios.h

😉【Linux102】29-kernel/panic.c

😉【Linux102】30-include/sys/times.h

😉【Linux102】31-include/sys/utsname.h

😉【Linux102】32-include/stddef.h

😉【Linux102】33-include/linux/sys.h

😉【Linux102】34-kernel/sys.c


Linux内核精讲系列

和Linux内核102系列不同,本系列将会从全局描绘Linux内核的各个模块,而非逐行源码分析,适合想对Linux系统有宏观了解的家人阅读。

😉【Linux】学习Linux前必备的知识点

😉【Linux】Linux内核对进程的内存抽象

😉【Linux】Linux概述1-linux对物理内存的使用

😉【Linux】软件从写下到运行的全部流程

😉【Linux】CPU的三寻址:实模式、保护模式、长模式

😉【Linux】实模式与保护模式的寻址, 这次讲明白了!

😉【Linux】linux0.11的源码目录架构

😉【Linux】Makefile机制及基础详解

😉【Linux】编译并运行Linux0.11

😉【Linux】“进进内网文”—Linux的内核结构全貌

😉【Linux】linux的中断机制

😉【Linux】linux进程描述



关于小希

😉嘿嘿嘿,我是小希,专注Linux内核领域,同时讲解C语言汇编等知识。

我的微信:C_Linux_Cloud,期待与您学习交流!

加微信请备注哦


小希的座右铭:别看简单,简单也是难。别看难,难也是简单。我的文章都是讲述简单的知识,如果你喜欢这种风格:

不妨关注、评论、转发,让更多朋友看到哦~~~🙈

下一期想看什么?在评论区留言吧!我们下期见!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值