UD2指令,产生一个中断,该中断使处理器把eflags,cs,ip等压入堆栈。ud2指令的bochs调试地址为:0x30430
同时产生一个中断向量,根据中断向量在IDT中寻找该向量的选择子,跟据这个选择子找到处理函数。处理之。
ud2指令产生中断向量号是0x06,根据0x06,找到 inval_opcode()函数,根据函数名跳到inval_opcode跳到inval_opcode:这个地址处,执行:
push 0xFFFFFFFF ; no err code 作为exception_handler()的参数使用
push 6 ; vector_no = 6 作为exception_handler()的参数使用
jmp exception ;注意是jmp,不是call,所以没有call的压入堆栈。其实在产生中断时,系统已经把eflags,es,ip压入堆栈了
jmp exception 其实跳到exception:这个地址
exception:
call exception_handler
add esp, 4*2 ; 让栈顶指向 EIP,指向EIP后堆栈中从顶向下依次是:EIP、CS、EFLAGS,那是因为前面压入的还有错误号或0xFFFFFFFF和中断向量
hlt
---------------------------------------------------------------
PUBLIC void exception_handler(int vec_no,int err_code,int eip,int cs,int eflags)
{ //vec_no,err_code,eip,cs,eflags分别得到push过来的参数,从而可以在下面的函数中使用这些参数
int i;
int text_color = 0x74; /* 灰底红字 */
char * err_msg[] = {"#DE Divide Error",
"#DB RESERVED",
"-- NMI Interrupt",
"#BP Breakpoint",
"#OF Overflow",
"#BR BOUND Range Exceeded",
"#UD Invalid Opcode (Undefined Opcode)",
"#NM Device Not Available (No Math Coprocessor)",
"#DF Double Fault",
" Coprocessor Segment Overrun (reserved)",
"#TS Invalid TSS",
"#NP Segment Not Present",
"#SS Stack-Segment Fault",
"#GP General Protection",
"#PF Page Fault",
"-- (Intel reserved. Do not use.)",
"#MF x87 FPU Floating-Point Error (Math Fault)",
"#AC Alignment Check",
"#MC Machine Check",
"#XF SIMD Floating-Point Exception"
};
/* 通过打印空格的方式清空屏幕的前五行,并把 disp_pos 清零 */
disp_pos = 0;
for(i=0;i<80*5;i++){
disp_str(" ");
}
disp_pos = 0;
disp_color_str("Exception! --> ", text_color);
disp_color_str(err_msg[vec_no], text_color);
disp_color_str("\n\n", text_color);
disp_color_str("EFLAGS:", text_color);
disp_int(eflags);
disp_color_str("CS:", text_color);
disp_int(cs);
disp_color_str("EIP:", text_color);
disp_int(eip);
if(err_code != 0xFFFFFFFF){
disp_color_str("Error code:", text_color);
disp_int(err_code);
}
}