自研操作系统处理键盘IRQ时增减代码字符串触发崩溃问题求助
问题根因
1. 核心原因:内核镜像加载不完整
你提到新增字符串后,磁盘读取扇区数从45变为46时代码正常运行,这是最直接的判断依据:
- 你的引导程序要么写死了固定读取45个扇区,要么构建脚本计算内核所需扇区数时没有做向上取整
- 当内核体积小于45*512字节时,不足一个扇区的尾部代码没有被加载到内存,CPU执行到这部分地址时,读取的是内存里的随机垃圾数据,自然会触发无效操作码(ISR6)、断点(ISR3)这类异常
- 当你添加足够多的字符串后,内核体积刚好达到46个扇区的大小,引导程序会完整加载全部46个扇区,所有代码都在内存里,运行就正常了
2. 潜在隐患:中断栈结构定义不匹配
你提供的reg_t结构体和实际中断栈布局存在偏移:
- 汇编中
pusha压入的寄存器顺序为edi、esi、ebp、esp、ebx、edx、ecx、eax,但你的reg_t开头多了一个eax_save字段,这会导致你访问test->code时读取的是栈上的错误值,极端情况会触发越界访问 - 另外汇编宏里的
add esp,8逻辑需要区分中断类型:只有带错误码的中断才需要清理这8字节(中断号+错误码),普通IRQ如果没有错误码的话,这个操作会导致栈指针偏移,iret时读取错误的返回地址触发异常
修复方案
- 检查引导程序的内核加载逻辑:要么把写死的加载扇区数改大(比如设置为128,足够覆盖你现阶段的内核体积),要么修复构建脚本的扇区数计算逻辑,只要内核大小不是512字节的整数倍,就多加载1个扇区
- 修正
reg_t结构体定义,删除开头多余的eax_save字段,保证结构体字段顺序和中断压栈顺序完全对齐 - 调整中断栈清理逻辑,区分带错误码和不带错误码的中断,分别处理栈平衡,避免栈指针偏移
内容的提问来源于stack exchange,提问作者Architek
相关产品推荐
相关产品推荐

