vni*_*nik 14 c linux x86 assembly
有人可以解释汇编指令int $0x00和执行实际除法之间的差异.我在与IDT中的第0个条目相关联的内核中的divide_error()处理程序上设置了断点(除法错误).
当我在我的C程序中执行此操作时:
int i = 5/0;
Run Code Online (Sandbox Code Playgroud)
然后我点击了断点(如预期的那样).然而,
asm volatile ("int $0x00")
Run Code Online (Sandbox Code Playgroud)
不会触发处理程序.为什么?
Jon*_*art 12
int 0h是不一样的东西作为该CPU生成陷阱0由于零的鸿沟.
Phrack的这篇文章很好地解释了IDT以及Linux如何设置它.关键部分是:
DPL=Descriptor Privilege Level
The DPL is equal to 0 or 3. Zero is the most privileged level (kernel
mode). The current execution level is saved in the CPL register (Current
Privilege Level). The UC (Unit Of Control) compares the value of the CPL
register against the DPL field of the interrupt in the IDT. The interrupt
handler is executed if the DPL field is greater (less privileged) or equal
to the value in the CPL register. Userland applications are executed in
ring3 (CPL==3). Certain interrupt handlers can thus not be invoked by
userland applications.
...
linux/arch/i386/kernel/traps.c::set_system_gate(n, addr)
insert a trap gate.
The DPL field is set to 3.
These interrupts can be invoked from the userland (ring3).
set_system_gate(3,&int3)
set_system_gate(4,&overflow)
set_system_gate(5,&bounds)
set_system_gate(0x80,&system_call);
linux/arch/i386/kernel/traps.c::set_trap_gate(n, addr)
insert a trap gate with the DPL field set to 0.
The Others exception are initialized with set_trap_gate :
set_trap_gate(0,÷_error)
set_trap_gate(1,&debug)
set_trap_gate(2,&nmi)
set_trap_gate(6,&invalid_op)
set_trap_gate(7,&device_not_available)
set_trap_gate(8,&double_fault)
set_trap_gate(9,&coprocessor_segment_overrun)
set_trap_gate(10,&invalid_TSS)
set_trap_gate(11,&segment_not_present)
set_trap_gate(12,&stack_segment)
set_trap_gate(13,&general_protection)
set_trap_gate(14,&page_fault)
set_trap_gate(15,&spurious_interrupt_bug)
set_trap_gate(16,&coprocessor_error)
set_trap_gate(17,&alignement_check)
set_trap_gate(18,&machine_check)
Run Code Online (Sandbox Code Playgroud)
那里的描述完美地解释了它.只能int从用户空间调用3,4,5和0x80,因为内核将其陷阱门设置为(Descriptor Prvilege Level)DPL = 3.
其他处理器异常向量具有DPL = 0(只能从环0调用).
除以零时,CPU首先转换为环0,内核处理异常divide_error.int 0x00但是,当您明确调用它时,您仍然处于(当前特权级别)CPL = 3.
有关非常低级别的细节,请参阅"英特尔软件开发人员手册".第2卷描述了该int指令,并概述了CPU决定如何处理陷阱/中断的所有决策步骤.第3卷描述了IDT,Trap Gates等的私密细节.
具体而言,表3-61决策表准确说明了中断发生的每种可能方式.在您的示例中,调用int 0x00将您置于第2列,主要说明:
if PE=1 # protected mode enabled
and DPL < CPL # DPL=0 - kernel set up trap gate like this
# CPL=3 - b/c you're in user-mode
and int type == S/W # you executed int instruction (s/w interrupt)
then issue #GP # General Protection fault
# -- kernel delivers this to usermode as SIGSEGV
Run Code Online (Sandbox Code Playgroud)
附加参考: