我在Intel-Atom 32位(汇编语言AT&T)上工作。
我想将ISR链接到向量中断0x33:
push %ebp //save the context to swith back
movl %esp,%ebp
movl $OSTickISR, %eax //address of int 0x33 = address of OSTickISR
movl $0x33*4, %ebx
movl %eax, (%ebx)
pop %ebp //Return to the calling function
ret当我尝试使用int $0x33时,什么也没有发生!
出什么问题了?
发布于 2011-10-28 21:39:48
Resolved :),因为有一个BIOS,它已经构建了GDT/ IDT,所以我使用sidt和sgdt指令找到了IDT的地址,并将我的ISR添加到了sidt
发布于 2011-09-29 05:17:26
在x86 32位中,ISR信息存储在IDT中。IDT不是简单的地址列表,并且不一定存储在地址0处。有关IDT格式的说明,请参阅OSDev Wiki page。IDT的位置由操作系统确定,用户模式软件可能无法访问它。假设您确实有权修改它,您可以使用sidt指令获取IDT的位置。
sidt -6(%esp)在32位模式下,sidt将在指定位置存储6个字节的数据。我在示例中使用了-6(%esp),它将数据存储在当前堆栈的正下方。低两个字节是IDT的长度(以字节为单位),接下来的4个字节( 32位模式)是IDT的地址。因为每个IDT条目都是8字节长,所以您想要的条目的位置应该是IDT开始之后的0x33*8字节。在修改条目之前,您应该确保IDT确实包含该条目(它至少有0x34*8字节长)。
下面是一个查找IDT、确保其足够长并设置中断0x33条目的示例。
sidt -6(%esp) // Get the location and size of the IDT
cmpw $0x34*8, -6(%esp) // Make sure the IDT is long enough
jb IDT_too_short // and handle the error if it isn't
mov -4(%esp), %ebx // Get the IDT's address
add $0x33*8, %ebx // and move to the entry for 0x33
mov $OSTickISR, %eax // Get the ISR's address
mov %ax, (%ebx) // Store the low 16 bits of the ISR's address
movw $ISR_CS, 2(%ebx) // Store the code segment which should be used with this ISR
movb $0, 4(%ebx) // This has to be 0
movb $0xEE, 5(%ebx) // See the OSDev link for information on this byte.
// 0xEE is most common for interrupts available from user mode
shr $16, %eax
mov %ax, 6(%ebx) // Store the high 16 bits of the ISR's address发布于 2011-09-29 05:25:06
x86上的地址由数据段和偏移量组成。在实模式下,它是segment*16 + offset。在保护模式下有一点间接:段寄存器它实际上是一个选择器,指向一个段描述符,其中包含段基础和限制,以及其他段属性。访问内存的指令可以采用显式段说明符(例如:DS:BX),也可以采用取决于所用寄存器的隐式段(例如:如果使用SP,则隐式段为SS)。
实模式下的IVT位于地址0000:0000,保护模式下的IDT位于地址IDT:0000,其中IDT可通过LIDT/SIDT指令访问。
您还应该考虑到,如果在Virtual memory操作系统上运行,则无法直接访问物理内存,程序中的地址是经过分段和分页后转换为物理地址的虚拟地址。
https://stackoverflow.com/questions/7589326
复制相似问题