- 论坛徽章:
- 0
|
我照搬了linux 0.11内核的中断描述符表初始化函数,但是发现中断不起作用,通过查看汇编语言发现了一个挺奇怪的问题,希望斑竹和各位高手解答。
代码如下:
#define _set_gate(gate_addr,type,dpl,addr) \
__asm__ ("movw %%dx,%%ax\n\t" \
"movw %0,%%dx\n\t" \
"movl %%eax,%1\n\t" \
"movl %%edx,%2" \
: : "i" ((short) (0x8000+(dpl<<13)+(type<<8 )), \
"o" (*((char *) (gate_addr))), \
"o" (*(4+(char *) (gate_addr))), \
"d" ((char *) (addr)),"a" (0x00080000))
#define set_trap_gate(n,addr) \
_set_gate(&idt[n],15,0,addr)
void trap_init(void)
{
int i;
for(i=0; i<48; ++i)
set_trap_gate(i,&reserved);
}
相应的汇编代码如下:
.align 2
.globl _trap_init
_trap_init:
pushl %ebp
movl %esp,%ebp
subl $16,%esp
pushl %edi
pushl %esi
pushl %ebx
nop
movl $0,-4(%ebp)
L3:
cmpl $47,-4(%ebp) //i和47比较
jg L4 //大于则跳转
movl -4(%ebp),%eax //i->eax
movl %eax,-12(%ebp)
movl %eax,-16(%ebp)
movl -12(%ebp),%ecx //i->ecx
movl -16(%ebp),%ebx //i->ebx
leal _idt(,%ecx,8 ),%esi //_idt+i*8的地址->esi
leal _idt+4(,%ebx,8 ),%edi //_idt+i*8+4地址->edi
movl $_reserved,%edx //待设定的地址(_reserved)->edx
movl $524288,%eax //内嵌汇编的输入寄存器
/APP
movw %dx,%ax //dx(_reserved)->ax
movw $-28928,%dx //??????????
movl %eax,(%esi) //
movl %edx,(%edi) //设置中断描述符表的陷阱门
/NO_APP
L5:
incl -4(%ebp) //i++
jmp L3 //循环
??????????处是问题所在,我觉得这个数应该是0x8f00,也就是36608,这样才符合陷阱门的设置要求。不知道为什么会变成程序中的一个负数?实验了把dpl用0代替,type用15代替没有用,也试验了移位用乘以参数代替,也不起作用。 |
|