能否让中断服务程序(ISR)不返回调用代码而跳转到指定标签?
中断服务程序(ISR)不返回调用位置直接跳转的可行性问题
我尝试用汇编语言编写一个中断服务程序(ISR),使其不返回到中断调用的位置,而是跳转到指定标签。请问直接跳转到标签而不使用iret(及其他中断相关指令)是否可行,还是有特定方法?我使用Netwide Assembler(NASM),示例代码如下:
[org 0x7c00] ; setting up ISR for int 69h (isr69h is the ISR) ; (i did it already, and worked fine with IRET, but i dont want to return to the caller) ; ... int 69h ; test ; don't continue code from here ; some more code... continue_from_here: jmp $ isr69h: ; do something jmp continue_from_here ; is it enough, or should i place here more code? (for example: restoring FLAGS etc.) times 510-($-$$) db 0 ; padding dw 0xAA55 ; boot signature
回答
直接跳转到目标标签是可行的,但必须处理栈状态和标志寄存器,否则会引发后续操作异常:
栈指针必须手动恢复:执行
int指令时,CPU会自动把FLAGS寄存器、返回地址的CS和IP依次压入栈中(实模式下共6字节)。如果直接跳转不清理这些数据,栈指针(SP)会停留在错误位置,后续任何涉及栈的操作(如函数调用、局部变量存储)都会出错。解决方法是在跳转前执行add sp, 6,把栈指针恢复到调用int指令之前的状态。FLAGS寄存器状态需按需调整:
int指令会自动将IF标志(中断允许位)置0,关闭可屏蔽中断。如果后续代码需要响应中断,必须手动执行sti指令重新开启;如果不需要,可忽略,但要明确当前中断状态。修改后的ISR示例:
isr69h: ; 执行你的ISR处理逻辑 add sp, 6 ; 清理栈中int指令压入的FLAGS、CS、IP sti ; 可选:若后续需要开启中断则添加 jmp continue_from_here
- 为什么不需要IRET?IRET的核心作用是自动弹出栈中的IP、CS、FLAGS并恢复原执行流,既然你明确不想返回原调用位置,就不需要依赖它的自动恢复逻辑,手动处理栈和FLAGS即可实现跳转需求。
内容的提问来源于stack exchange,提问作者Berc07
相关产品推荐
相关产品推荐

