最近在跟着网上教程写内核,很累很疲惫,但也学到了许多。
且夫水之积也不厚 则其负大舟也无力
忽然想到这句话,很有道理,水平所限,好的教程是绝对写不出来的。仅以此篇作为记录之用。
代码实例
#include "common.h"
/*
* %1代表输入,%0代表输出,输出要加"="号,a和dN代表寄存器约束
* 行与行直接:分隔开
* 最后一项代表 clobered register 即变动过的寄存器,需要GCC将其恢复原样
*/
//端口写一个字节
inline void outb(uint16_t port, uint8_t value)
{
asm volatile("outb %1, %0" : : "dN" (port), "a" (value));
}
//端口读一个字节
inline uint8_t inb(uint16_t port)
{
uint8_t ret;
asm volatile("inb %1, %0" : "=a" (ret) : "dN" (port));
return ret;
}
//端口读入一个字
inline uint16_t inw(uint16_t port)
{
uint16_t ret;
asm volatile("inw %1, %0" : "=a" (ret) : "dN" (port));
return ret;
}inline 关键字
其作用相当于宏定义,这么说不够严谨但很直观。
要比宏定义高级的多。用来修饰函数,可以在编译时直接把函数嵌入调用的主体,节省重新开栈、返回的开销。
当然你也可以通过宏定义一个函数,但是实在是想不到这样的用意在哪里,在我看来完全可以给函数起一个足够清晰的名称来省略这一步。
而 inline 所修饰的函数,调用起来和常规函数并没有什么区别,而且效率更高,因为 inline 所修饰的函数,也可以被编译器进行类型检查。
参考链接: