//// лûģʽС
// úiret ָʵִںģʽлûģʽʼ0
#define move_to_user_mode() \
__asm__ ( "movl %%esp,%%eax\n\t" \	// ջָesp eax ĴС
"pushl $0x17\n\t" \		// Ƚջѡ(SS)ջ
  "pushl %%eax\n\t" \		// Ȼ󽫱Ķջֵָ(esp)ջ
  "pushfl\n\t" \		// ־Ĵ(eflags)ջ
  "pushl $0x0f\n\t" \		// ں˴ѡ(cs)ջ
  "pushl $1f\n\t" \		// 1 ƫƵַ(eip)ջ
  "iret\n" \			// ִжϷָת1 
  "1:\tmovl $0x17,%%eax\n\t" \	// ʱʼִ0
  "movw %%ax,%%ds\n\t" \	// ʼμĴָ򱾾ֲݶΡ
"movw %%ax,%%es\n\t" "movw %%ax,%%fs\n\t" "movw %%ax,%%gs":::"ax")
#define sti() __asm__ ( "sti"::)	// жǶ꺯
#define cli() __asm__ ( "cli"::)	// жϡ
#define nop() __asm__ ( "nop"::)	// ղ
#define iret() __asm__ ( "iret"::)	// жϷء
//// 꺯
// gate_addr -ַtype -ֵdpl -Ȩֵaddr -ƫƵַ
// %0 - (dpl,type ϳɵͱ־)%1 - (4 ֽڵַ)
// %2 - (4 ֽڵַ)%3 - edx(ƫƵַaddr)%4 - eax(кжѡ)
#define _set_gate(gate_addr,type,dpl,addr) \
__asm__ ( "movw %%dx,%%ax\n\t" \	// ƫƵַѡϳ4 ֽ(eax)
  "movw %0,%%dx\n\t" \		// ͱ־ƫƸϳ4 ֽ(edx)
  "movl %%eax,%1\n\t" \		// ֱĵ4 ֽں͸4 ֽڡ
"movl %%edx,%2":
:"i" ((short) (0x8000 + (dpl << 13) + (type << 8))),
  "o" (*((char *) (gate_addr))),
  "o" (*(4 + (char *) (gate_addr))), "d" ((char *) (addr)), "a" (0x00080000))
//// жź
// n - жϺţaddr - жϳƫƵַ
// &idt[n]ӦжϺжеƫֵж14Ȩ0
#define set_intr_gate(n,addr) \
_set_gate(&idt[n],14,0,addr)
//// ź
// n - жϺţaddr - жϳƫƵַ
// &idt[n]ӦжϺжеƫֵж15Ȩ0
#define set_trap_gate(n,addr) \
_set_gate(&idt[n],15,0,addr)
//// ϵͳź
// n - жϺţaddr - жϳƫƵַ
// &idt[n]ӦжϺжеƫֵж15Ȩ3
#define set_system_gate(n,addr) \
_set_gate(&idt[n],15,3,addr)
//// ö
// gate_addr -ַtype -ֵdpl -Ȩֵ
// base - εĻַlimit - ޳μĸʽ
#define _set_seg_desc(gate_addr,type,dpl,base,limit) {\
*(gate_addr) = ((base) & 0xff000000) | \	// 4 ֽڡ
  (((base) & 0x00ff0000) >> 16) |
  ((limit) & 0xf0000) | ((dpl) << 13) | (0x00408000) | ((type) << 8);
*((gate_addr) + 1) = (((base) & 0x0000ffff) << 16) | \	// 4 ֽڡ
  ((limit) & 0x0ffff);
}

//// ȫֱ״̬/ֲ
// n - ȫֱn Ӧĵַaddr - ״̬/ֲڴĻַ
// type - еı־ֽڡ
// %0 - eax(ַaddr)%1 - (n ĵַ)%2 - (n ĵַƫ2 )
// %3 - (n ĵַƫ4 )%4 - (n ĵַƫ5 )
// %5 - (n ĵַƫ6 )%6 - (n ĵַƫ7 )
#define _set_tssldt_desc(n,addr,type) \
__asm__ ( "movw $104,%1\n\t" \	// TSS ȷ(0-1 ֽ)
"movw %%ax,%2\n\t" \		// ַĵַ2-3 ֽڡ
  "rorl $16,%%eax\n\t" \	// ַax С
  "movb %%al,%3\n\t" \		// ַеֽ4 ֽڡ
  "movb $" type ",%4\n\t" \	// ־ֽĵ5 ֽڡ
  "movb $0x00,%5\n\t" \		// ĵ6 ֽ0
  "movb %%ah,%6\n\t" \		// ַиֽ7 ֽڡ
  "rorl $16,%%eax" \		// eax 㡣
  ::"a" (addr), "m" (*(n)), "m" (*(n + 2)), "m" (*(n + 4)),
  "m" (*(n + 5)), "m" (*(n + 6)), "m" (*(n + 7)))
//// ȫֱ״̬
// n - Ǹָ룻addr - еĻֵַ״̬0x89
#define set_tss_desc(n,addr) _set_tssldt_desc(((char *) (n)),addr, "0x89")
//// ȫֱþֲ
// n - Ǹָ룻addr - еĻֲֵַ0x82
#define set_ldt_desc(n,addr) _set_tssldt_desc(((char *) (n)),addr, "0x82")
