最近写mit的JOS操作系统看到一些有意思的位运算的使用方法,在这里分享/记录一下。
一 使用&
位可以快速清除低位
页表的entry格式如下:1
2
3
4
5
6
7
8
9
10
11
12
13
1431 12 11 0
+--------------------------------------+-------+---+-+-+---+-+-+-+
| | | | | | |U|R| |
| PAGE FRAME ADDRESS 31..12 | AVAIL |0 0|D|A|0 0|/|/|P|
| | | | | | |S|W| |
+--------------------------------------+-------+---+-+-+---+-+-+-+
P - PRESENT
R/W - READ/WRITE
U/S - USER/SUPERVISOR
D - DIRTY
AVAIL - AVAILABLE FOR SYSTEMS PROGRAMMER USE
NOTE: 0 INDICATES INTEL RESERVED. DO NOT DEFINE.
现在需要从页表entry中获得页的物理地址。我们知道因为页的物理地址也是关于页大小对齐的,所以在页表entry存储的只是页对应的物理地址的高20bits。只要将entry的低12bits置零就可以得到对应的物理地址。在JOS中是这样做的1
2
3#define PADDR(pte) pte & ~0xfff
// 0xfff是12bits都是1的数字,取~后使得高20bits都为1,低12bits都为0。再与pte取&即可
// 将低12bits置零,其余bit保持不变
二 使用|
位运算来结合flags:
还是在一中页表的例子,在设置页表的时候要设置12bits的flags来控制页是否present/读写权限/用户权限等等。
JOS中做法大致如下1
2
3
4
5
6
7
8define PTE_P 0x1
define PTE_W 0x2
//
typedef uint32_t pte_t
// 声明一个entry
pte_t pte = 0x8000ffff; // 随便写的一个
// 设置flag P = 1 R/W = 1
pte = PADDR(pte) | PTE_P | PTE_W ; // pte的最后两个bit就会变成11
使用或位运算可以用来清晰方便的combine flags。
三 快速置零
1 | // 快速将a的值清零 |