2011-09-28 28 views
1

我使用Intel-Atom 32位(汇编AT & T)。将ISR链接到向量中断80x86 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,没什么happends!

出了什么问题?

回答

0

解决:),因为有一个BIOS,它已经建立了GDT/IDT,所以我找到了IDT的使用SIDT和SGDT指令的地址,我将自己ISR到SIDT

3

在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开始之后,您想要的条目的位置是个字节。在修改条目之前,应确保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 
+1

+1伟大的答案,除了[IA软件开发人员手册](http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html)的强制性链接之外,我没有其他补充内容。 (哦,为了完整性可能会投入一个'sub $ 8,%esp'顶部:) – user786653

+0

@ user786653感谢您的链接。至于'sub $ 8,%esp',我的回应取决于你的推理。如果1)你正在为函数调整堆栈,这是没有必要的,因为没有函数调用,或者2)你想使用'%esp'的正偏移量,我更喜欢在红色区域工作尽可能少量的数据。 – ughoavgfhw

+0

我想在堆栈上分配空间,因为我不记得在32位x86上使用了带有红色区域的调用约定?无论哪种方式,能够理解和使用上面的代码中任何人都应该能够轻松地做出适当的调整他们的调用约定:) – user786653

1

x86上的地址由段和偏移量组成。在实模式下,它是段* 16 +偏移量。在保护模式下,有一点间接性:段寄存器实际上是一个指向段描述符的选择器,该段描述符包含段基和限制以及其他段属性。访问存储器的指令可以采用明确的段说明符(例如:DS:BX),否则它们将取决于所用寄存器的隐式段(例如:如果使用SP,则隐式段为SS)。

实模式下的IVT地址为0000:0000,保护模式下的IDT为地址IDT:0000,其中IDT可通过LIDT/SIDT指令访问。

您还应该考虑到,如果您运行的是虚拟内存操作系统,则您无法直接访问物理内存,程序中的地址是虚拟地址,在分割后会转换为物理地址,分页。