D中的我的OS内核:某些嵌入的字符串不起作用

我知道这是一个相当难以回答的问题,主要是因为有很多事情可能是错误的,很难把事情搞得一团糟。但我会尽可能多地提供信息;希望这会有所帮助。 我开始使用D语言和Digital Mars D编译器编写自己的内核,并且在弄清楚如何生成可以重新定位的平面二进制文件之后遇到了很多麻烦,我终于提出了生成普通PE文件的想法。地址
0xC0000000
,并用字节
0x90
(NOP操作码)替换所有标题。这非常好用,我能够在屏幕上编写内容,设置分页,完全进入保护模式等,当然还有16位基于汇编的引导加载程序的帮助。 一切都很顺利,也就是说,我决定将D运行时库移植到我的内核中。我设法提取了库的一个子集并对其进行了修改,以便将其编译到我的应用程序中。然后我运行了我的程序。 (注意:我根本没有使用该库;我的代码是第一个在引导后执行的代码 - 第一件事就是将
"Kernel"
打印到屏幕上,之前没有调用运行时代码。) 一个D数组(因此一个字符串,因为一个字符串只是一个
char[]
)只不过是一个带有指针和大小成员的结构,因此在32位系统上它将是8字节大。有趣的是,当我运行我的程序时,结构的成员显示为零 - 也就是说,指针和大小都为零。 (我通过将指针的值打印到屏幕以及长度成员来验证这一点 - 两者都是零。)一旦我删除了运行时的源代码(从未执行过),它们工作正常。 我把它缩小到两种可能性: 堆栈在某种程度上没有正确设置:我排除了这一点,因为没有运行时库,一切正常,我确认在我的代码之前没有通过反汇编文件执行其他代码。 PE文件部分很有趣:我检查过,并发现在运行时版本中有两个TLS(线程局部)变量。果然,当我让它们共享(而不是线程本地)时,我的代码工作了!但是,当我调用我在不同文件中编写的代码时,我的代码仍然表现出相同的问题 - 只有
kernel.d
,这是启动文件,表现正确的字符串;在其他文件中,数组再次为零。 现在,有没有人猜到为什么会发生这种情况? 如果需要更多信息,我很乐意发布。 谢谢!     
已邀请:
首先,免责声明:我不知道关于D.的第一件事。 第二,另一个免责声明:基于使用术语“PE文件”我会猜测你正在使用Windows。我即将给出一个GNU工具链的建议...... 但是......假设D编译器生成目标文件就像其他任何一样......为什么不执行以下操作(这是我在C中使用业余爱好操作系统时所做的,当我有时间做这些事情时): 为您的内核生成ELF二进制文件...为此,请正常构建所有目标文件。在链接步骤中,将链接描述文件提供给
ld
,它将定义诸如起始地址,二进制的部分(文本,数据,rodata等)的顺序...... 使用GRUB启动它(相当容易做...你需要在二进制文件的开头附近添加一些神奇的单词。你可以在.asm文件中使用
db
dw
类型的语句执行此操作,前提是相应的obj最终链接在附近内核的开头。看看这个链接) 通过这种方式,您可以专注于更多有趣的事情,而不是破解PE头或编写引导程序。 当然......完全有可能代码本身存在一些问题,而不是你链接的方式。在某些可以让您逐步完成程序集输出的内容中运行它可能会提供信息。 x86 PC仿真器
qemu
有一些调试选项,可以将汇编和寄存器状态输出到日志。我以前用过它。     
一年之后... 解决了! :d (>'。')>  (^'。'^)  <('。')>  (v'。'v)  <('。'<) 这是我的启动加载器的问题:我在内存中读取的扇区太少了。 (即64个扇区而不是128个125.)     

要回复问题请先登录注册