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

如何在64位模式下不使用64位寄存器执行x86远跳转?

64位模式下无64位寄存器依赖的远跳转实现

核心限制说明

64位AMD64架构不支持立即数形式的64位远跳转(jmp far seg:64bit_offset),指令集没有对应的编码格式,这是你之前汇编报错的原因。必须通过内存中的10字节远指针结构完成跳转,结构为:

  • 低2字节:目标段选择子(小端序)
  • 高8字节:64位目标虚拟地址(小端序)

实现方案(NASM + Linux内联汇编)

1. 静态数据区存储远指针(无寄存器修改)

利用RIP相对寻址直接访问静态数据区的远指针,全程不修改任何64位寄存器:

bits 64
default rel  ; 启用RIP相对寻址,自动生成偏移
section .data
; 定义远指针:段选择子 + 64位目标地址
target_far_ptr:
    dw 0x33          ; Linux用户态代码段选择子(内核态用0x08)
    dq 0xdeadbeefdeadbeef  ; 你要跳转的64位目标地址

section .text
global main
main:
    ; 执行远跳转,无寄存器依赖
    jmp far [target_far_ptr]

2. C内联汇编版本

如果需要在C代码中嵌入,同样利用RIP相对寻址,避免修改64位寄存器:

#include <stdint.h>

// 定义远指针结构(小端序)
static const uint8_t far_ptr[10] = {
    0x33, 0x00,          // 用户态代码段选择子0x33(小端存储)
    0xef, 0xbe, 0xad, 0xde, 0xef, 0xbe, 0xad, 0xde  // 目标地址0xdeadbeefdeadbeef(小端存储)
};

int main() {
    __asm__ volatile (
        "jmp far [rip + %0]"  // RIP相对寻址访问远指针
        :
        : "i"((intptr_t)&far_ptr - (intptr_t)__builtin_extract_return_addr(__builtin_return_address(0)) - 5)
        // 计算RIP到far_ptr的偏移:-5是因为jmp指令长度为5字节,RIP指向指令后地址
        : "memory"
    );
    return 0;
}

关键注意事项

  • 段选择子必须匹配当前特权级:Linux用户态用0x33,内核态用0x08,错误的选择子会触发异常。
  • 远指针必须按小端序存储,x86架构默认是小端,直接按字节定义即可。
  • RIP相对寻址属于64位模式的默认寻址方式,仅读取RIP值(不修改),符合“不破坏64位寄存器”的要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 00:25:20