我正在开发一个具有严格启动时间要求的项目.目标体系结构是基于IA-32的处理器,以32位保护模式运行.确定可以改进的一个领域是当前系统动态初始化处理器的IDT(中断描述符表).由于我们没有任何即插即用设备且系统相对静态,我希望能够使用静态构建的IDT.
然而,由于8字节中断门描述符分割ISR地址,这证明对于IA-32拱是麻烦的.ISR的低16位出现在描述符的前2个字节中,其他一些位填充接下来的4个字节,最后ISR的最后16位出现在最后2个字节中.
我想使用const数组来定义IDT,然后简单地将IDT寄存器指向它,如下所示:
typedef struct s_myIdt {
unsigned short isrLobits;
unsigned short segSelector;
unsigned short otherBits;
unsigned short isrHibits;
} myIdtStruct;
myIdtStruct myIdt[256] = {
{ (unsigned short)myIsr0, 1, 2, (unsigned short)(myIsr0 >> 16)},
{ (unsigned short)myIsr1, 1, 2, (unsigned short)(myIsr1 >> 16)},
Run Code Online (Sandbox Code Playgroud)
等等
显然这不起作用,因为在C中执行此操作是非法的,因为myIsr不是常量.它的值由链接器解决(只能进行有限的数学运算)而不是编译器.
关于如何做到这一点的任何建议或其他想法?
谢谢,
多年来,尤其是在x86操作系统开发中遇到的许多问题都激发了这个问题。最近,有关NASM的一个问题因修改而引起争议。在那种情况下,该人正在使用NASM并遇到汇编时间错误:
移位运算符只能应用于标量值
另一个相关问题是在编译时生成静态IDT时导致错误的GCC代码问题:
初始值设定项元素不是常量
在这两种情况下,此问题都与以下事实有关:IDT条目需要一个指向异常处理程序的地址,而GDT可能需要到另一个结构(如任务段结构(TSS))的基地址。通常这不是问题,因为链接过程可以通过重定位修复程序解析这些地址。对于IDT条目或GDT条目,这些字段将基地址/功能地址拆分开。没有重定位类型可以告诉链接程序将位移位,然后按照它们在GDT / IDT条目中的布局方式放置到内存中。彼得·科德斯(Peter Cordes)在这个答案中对此作了很好的解释。
我的问题是不是问这个问题是什么,但对于一个请求的功能,以及实用的解决方案的问题。尽管我对此进行了自我回答,但这只是许多可能的解决方案之一。我只要求提出的解决方案满足以下要求:
我以传统的引导加载程序1的形式提供了一些示例代码,该示例试图在组装时创建静态IDT和GDT,但是在与组装时会出现以下错误nasm -f elf32 -o boot.o boot.asm:
Run Code Online (Sandbox Code Playgroud)boot.asm:78: error: `&' operator may only be applied to scalar values boot.asm:78: error: `&' operator may only be applied to scalar values boot.asm:79: error: `&' operator may only be applied to scalar values boot.asm:79: error: `&' operator …
我有一个内存位置,其中包含一个我想要与另一个角色进行比较的角色(并且它不在堆栈的顶部,所以我不能只是pop它).如何引用内存位置的内容以便进行比较?
基本上我如何在语法上做到这一点.