#define _set_gate(gate_addr,type,dpl,addr) \
789 do { \
790 int __d0, __d1; \
791 __asm__ __volatile__ ("movw %%dx,%%ax\n\t" \
792 "movw %4,%%dx\n\t" \
793 "movl %%eax,%0\n\t" \
794 "movl %%edx,%1" \
795 :"=m" (*((long *) (gate_addr))), \
796 "=m" (*(1+(long *) (gate_addr))), "=&a" (__d0), "=&d" (__d1) \
797 :"i" ((short) (0x8000+(dpl<<13)+(type<<8))), \
798 "3" ((char *) (addr)),"2" (__KERNEL_CS << 16)); \
799 } while (0)
789 do { \
790 int __d0, __d1; \
791 __asm__ __volatile__ ("movw %%dx,%%ax\n\t" \
792 "movw %4,%%dx\n\t" \
793 "movl %%eax,%0\n\t" \
794 "movl %%edx,%1" \
795 :"=m" (*((long *) (gate_addr))), \
796 "=m" (*(1+(long *) (gate_addr))), "=&a" (__d0), "=&d" (__d1) \
797 :"i" ((short) (0x8000+(dpl<<13)+(type<<8))), \
798 "3" ((char *) (addr)),"2" (__KERNEL_CS << 16)); \
799 } while (0)
trap_init的主要函数,解释如下:
由输入部可知addr开始绑定了edx寄存器,_KERNEL_CS左移16位后与eax寄存器绑定。
第一行代码要求将dx,也就是edx低16位的数据拷贝进ax寄存器中。此条指令之前eax本身高16位保存着__KERNEL_CS的数值。但是低16位并没有设置(想象成eax的低16位都是0)。ax寄存器就是eax寄存器的低16位,所以,第一条指令完成后eax的高16位为_KERNEL_CS,低16位为入口地址的低16位。
第二行代码将按照intel要求构造的数据(0x8000+.....)装入dx,也就是edx寄存器的低16位。此时edx的高16位装着入口地址的高16位。
下面的代码按照intel的要求放入idt表项之中。代码结束。