看到个很有趣的位域问题,放上来分享下(位域介绍)
#include<stdio.h> #define STS_TG32 0xC // 32-bit Call Gate #define STS_IG32 0xE // 32-bit Interrupt Gate typedef unsigned int uint32_t; #define SETGATE(gate, istrap, sel, off, dpl) { (gate).gd_off_15_0 = (uint32_t)(off) & 0xffff; (gate).gd_ss = (sel); (gate).gd_args = 0; (gate).gd_rsv1 = 0; (gate).gd_type = (istrap) ? STS_TG32 : STS_IG32; (gate).gd_s = 0; (gate).gd_dpl = (dpl); (gate).gd_p = 1; (gate).gd_off_31_16 = (uint32_t)(off) >> 16; } /* Gate descriptors for interrupts and traps */ struct gatedesc { unsigned gd_off_15_0 : 16; // low 16 bits of offset in segment unsigned gd_ss : 16; // segment selector unsigned gd_args : 5; // # args, 0 for interrupt/trap gates unsigned gd_rsv1 : 3; // reserved(should be zero I guess) unsigned gd_type : 4; // type(STS_{TG,IG32,TG32}) unsigned gd_s : 1; // must be 0 (system) unsigned gd_dpl : 2; // descriptor(meaning new) privilege level unsigned gd_p : 1; // Present unsigned gd_off_31_16 : 16; // high bits of offset in segment }; int main() { unsigned intr; intr=8; SETGATE((*(struct gatedesc*)&intr), 0,1,2,3); printf("%x ",intr); }
分析intr的值:
首先看一下getedesc在内存中是如何存储的:
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
地址 向下 增大 |
gd_off_15_0
|
|||||||||||||||
gd_ss |
||||||||||||||||
gd_p |
gd_dpl |
gd_s |
gd_type |
gd_rsv1 |
gd_args |
|||||||||||
gd_off_31_16 |
unsigned占用4字节,即32位,getedesc占用8字节,即64位。
按题目操作,由于X86使用小端存储,intr所占内存对应位置应该是getedesc的低32位,也就是表格的前两列。
同样由于X86使用小端存储,所以intr高16位为gd_ss,低16位为gd_off_15_0。
所以intr的值应该为 0000 0000 0000 0001 0000 0000 0000 0002 ,即0x10002。
知道了intr=0x10002以后,*(&intr+1)=0xee00也就很显而易见了对吧~