如何通过间接跳转到长模式?AP远跳转触发三重故障求助
解决长模式下AP直接远跳转触发三重故障的方案
长模式(64位模式)下,CPU不支持传统的直接远跳转指令格式(jmp cs:offset),该指令无法正确处理64位目标地址,这正是你触发三重故障的核心原因。必须使用间接远跳转,通过内存中的16字节跳转描述符来实现。
具体实现步骤
1. 定义远跳转描述符
在汇编代码中定义一个16字节的结构,格式严格遵循CPU要求:
- 低8字节:64位目标地址(对应你要跳转到的
to_target) - 高8字节:低16位为代码段选择子(你的
0x8),剩余48位保留为0
示例代码:
; 远跳转描述符(16字节) ap_jmp_desc: dq to_target ; 64位目标偏移地址 dw 0x8 ; 代码段选择子 dw 0x0000 ; 长模式下无意义,填0 dd 0x00000000 ; 长模式下无意义,填0
2. 执行间接远跳转
使用jmp qword ptr [描述符地址]指令完成跳转:
jmp qword ptr [ap_jmp_desc]
替代方案:栈上临时构造描述符
如果不想单独定义全局描述符,也可以在栈上临时构造16字节结构再跳转:
; 把目标地址和段选择子压入栈 mov rax, to_target ; 加载目标地址到rax mov rbx, 0x8 shl rbx, 48 ; 将段选择子移到64位值的低16位 push rbx ; 压入高8字节(段选择子+保留位) push rax ; 压入低8字节(目标地址) ; 执行间接远跳转 jmp qword ptr [rsp] ; rsp指向栈上的16字节描述符起始位置 add rsp, 16 ; 清理栈空间(根据你的栈使用情况选择是否执行)
关键说明
- 长模式下,间接远跳转是唯一支持的跨段远跳转方式,它通过内存结构传递完整的64位地址和段选择子,避免了直接跳转的编码限制。
- 确保
to_target是长模式下有效的地址:若分页已开启则为虚拟地址,若分页未开启则为物理地址;同时确认代码段选择子0x8对应的GDT项是正确的64位代码段描述符。
内容的提问来源于stack exchange,提问作者BambooPyanda
相关产品推荐
相关产品推荐

