traps的主要功能:其函数被asm.s中调用打印中断信息,通过set_trap_gate设置中断向量(如:set_trap_gate(0,÷_error);),c语言中写汇编。
寄存器变量:register定义一个寄存器变量,他可以在汇编中跟寄存器一样操作,是链接c语言和汇编的桥梁。
如:register char __res;
定义的die函数打印信息,其他的中断调用该函数打印中断信息:
如:void do_divide_error(long esp, long error_code)
{
die("divide error",esp,error_code);
}
下面几个函数是读取寄存器数据和die函数
_inline char get_seg_byte(unsigned short segm, void *addr)
{
register char __res;
_asm{
push fs
mov ax,segm
mov fs,ax
mov ebx,addr
mov al,byte ptr fs:[ebx]
mov __res,al
pop fs
}
return __res;
}
// 取段seg 中地址addr 处的一个长字(4 字节)。
_inline long
get_seg_long(unsigned short segm,long *addr) {
register unsigned long __res;
_asm{
push fs
mov ax,segm
mov fs,ax
mov ebx,addr
mov eax,fs:[ebx]
mov __res,eax
pop fs
}
return __res;
}
//#define get_seg_long(seg,addr) ({ \
//register unsigned long __res; \
//__asm__("push %%fs;mov %%ax,%%fs;movl %%fs:%2,%%eax;pop %%fs" \
// :"=a" (__res):"0" (seg),"m" (*(addr))); \
//__res;})
// 取fs 段寄存器的值(选择符)。
_inline unsigned short _fs() {
register unsigned short __res;
_asm mov ax,fs
_asm mov __res,ax
return __res;
}
// 该子程序用来打印出错中断的名称、出错号、调用程序的EIP、EFLAGS、ESP、fs 段寄存器值、
// 段的基址、段的长度、进程号pid、任务号、10 字节指令码。如果堆栈在用户数据段,则还
// 打印16 字节的堆栈内容。
static void die(char * str,long esp_ptr,long nr)
{
long * esp = (long *) esp_ptr;
int i;
printk("%s: %04x\n\r",str,nr&0xffff);
printk("EIP:\t%04x:%p\nEFLAGS:\t%p\nESP:\t%04x:%p\n",
esp[1],esp[0],esp[2],esp[4],esp[3]);
printk("fs: %04x\n",_fs());
printk("base: %p, limit: %p\n",get_base(current->ldt[1]),get_limit(0x17));
if (esp[4] == 0x17) {
printk("Stack: ");
for (i=0;i<4;i++)
printk("%p ",get_seg_long(0x17,i+(long *)esp[3]));
printk("\n");
}
str(i);
printk("Pid: %d, process nr: %d\n\r",current->pid,0xffff & i);
for(i=0;i<10;i++)
printk("%02x ",0xff & get_seg_byte(esp[1],(i+(char *)esp[0])));
printk("\n\r");
do_exit(11); /* play segment exception */
}