You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何isr_common_stub未调用isr_handler?x86_64 IDT实现是否正确?

问题分析:isr_common_stub未调用isr_handler的原因及调用方式正确性

调用方式的正确性

你的调用方式符合x86_64 System V ABI规范:

  • 按照ABI要求,第一个参数通过rdi寄存器传递,这里mov rdi, rsp将栈指针传给isr_handler,而栈上的布局正好对应registers_t结构体的定义,这种参数传递方式是正确的。
  • cld指令的使用也符合ABI要求(确保字符串操作指令的方向标志为0)。

可能导致未调用isr_handler的原因

1. save_registers实现与registers_t结构体不匹配

registers_t定义的寄存器顺序必须和save_registers压栈的顺序完全一致:

  • 检查save_registers是否按结构体顺序依次压入ds/es/fs/gs、通用寄存器(r15到rax)、int_no和err_code。如果顺序错位,栈布局会和结构体定义不符,导致isr_handler接收到的参数无效,甚至在调用时触发异常。
  • 注意:部分中断会自动压入err_code,如果你的中断服务程序(ISR)没有处理这一点,可能导致栈上多了或少了数据,破坏结构体布局。

2. 段寄存器加载错误

mov eax, 0x10加载内核数据段描述符后,如果0x10对应的GDT项无效(比如段限长错误、类型错误),后续访问内存(比如执行call isr_handler时取指令或访问栈)会触发段异常,导致流程跳转到异常处理函数,看起来像是isr_handler未被调用。

3. isr_handler函数签名错误

isr_handler的函数签名必须为:

void isr_handler(registers_t *regs);

如果写成void isr_handler(registers_t regs)(值传递),会导致函数尝试从栈上拷贝整个结构体,而栈布局不匹配,触发栈错误,函数无法正常执行。

4. IDT中断门配置错误

  • 确保IDT中的中断门是64位中断门(属性字段需设置正确的位,比如类型为0xE),存在位(P位)置1。
  • 中断门的代码段选择子必须是有效的内核代码段(通常是0x08,对应GDT中内核代码段项),DPL设置为0(内核级),避免权限错误导致中断无法触发。

5. 栈指针或栈段错误

  • 如果中断门配置了错误的栈段(比如指定用户栈而非内核栈),进入中断时栈切换失败,会导致后续指令执行异常,无法到达call isr_handler。
  • 检查save_registers执行后,rsp是否指向有效的内核栈空间,栈溢出或栈地址无效都会导致调用失败。

6. 符号链接问题

  • 在汇编代码中,需通过extern isr_handler声明该C函数,确保链接器能正确解析符号。如果缺少声明,链接时可能出现未定义符号错误,或运行时无法找到函数地址,导致call指令执行失败。

7. add rsp, 16的合理性

检查add rsp, 16的作用:如果int_no和err_code是在save_registers之外压入栈的,那么这条指令是用来清理这两个值;但如果save_registers已经包含了这两个字段的压栈操作,这条指令会破坏栈平衡,导致restore_registers执行错误,甚至在call isr_handler前就出现栈问题。


内容的提问来源于stack exchange,提问作者baponkar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 11:20:58