gate.h 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142
  1. /**
  2. * @file gate.h
  3. * @author longjin
  4. * @brief 门定义
  5. * @date 2022-01-24
  6. *
  7. */
  8. #pragma once
  9. /**
  10. * @brief 初始化中段描述符表内的门描述符(每个16B)
  11. * @param gate_selector_addr IDT表项的地址
  12. * @param attr P、DPL、TYPE的属性
  13. * @param ist 中断栈表号
  14. * @param code_addr 中断服务程序的地址
  15. */
  16. // todo:在系统异常处理主功能完成后,将这段代码用C来写一遍。这段汇编实在是太晦涩难懂了,我看了半个钟才看明白。
  17. #define _set_gate(gate_selector_addr, attr, ist, code_addr) \
  18. do{
  19. unsigned long __d0, __d1; \
  20. __asm__ __volatile__ ( "movw %%dx, %%ax \n\t" \
  21. "andq $0x7, %%rcx \n\t" \ // 清空rcx中除了2:0以外的所有位(此前ist的值已经被赋给了rcx)
  22. "addq %4, %%rcx \n\t" \ // 将P,DPL, Type的值加到rcx中
  23. "shlq $32, %%rcx \n\t" \
  24. "addq %%rcx, %%rax \n\t" \ // 设置ist
  25. "xorq %%rcx, %%rcx \n\t" \ // 清空rcx
  26. "movl %%edx, %%ecx \n\t" \
  27. "shrq $16, %%ecx \n\t" \
  28. "shlq $48, %%rcx \n\t" \ // 左移到低8B中表示段内偏移的[31:16]处
  29. "addq %%rcx, %%rax \n\t" \ // 设置段内偏移[31:16]
  30. "movq %%rax, %0 \n\t" \ // 输出到门选择子的低8B
  31. "shrq $32, %%rdx \n\t" \
  32. "movq %%rdx, %1 \n\t" \ // 输出到门选择子的高8B
  33. :"=m"(*((unsigned long *)(gate_selector_addr))) , \
  34. "=m"(*(1 + (unsigned long *)(gate_selector_addr))),"=&a"(__d0),"=&d"(__d1) \
  35. :"i"(attr << 8), \
  36. "3"((unsigned long *)(code_addr)),"2"(0x8 << 16),"c"(ist) \
  37. :"memory" \
  38. )
  39. }while(0)