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

汇编跳转指令异常排查:我的代码是否符合给定要求?

汇编代码合规性排查与修正

原始需求

  • 代码首条指令为jmp
  • 该jmp为相对跳转,跳转到当前位置偏移0x51字节处
  • 在0x51位置编写以下代码:
    • 将栈顶值存入RDI寄存器
    • jmp到绝对地址0x403000

初始汇编代码

.intel_syntax noprefix
    .global _start
    _start:
        jmp $+0x51
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        pop rdi
        mov eax, 0x403000
        jmp rax

用户疑问

请问这是否完全符合要求?相对跳转或绝对跳转是否存在问题?

补充尝试代码

. . .
    nop
    pop rdi
    mov rax, 0x403000
    jmp fword ptr [eax]

问题分析与修正

1. 相对跳转的偏移问题

x86相对跳转的偏移是相对于下一条指令的地址,但GAS汇编器里的$+offset是基于当前指令地址计算的,汇编器会自动把它转换成符合CPU要求的相对偏移。从目标文件信息来看,你的jmp $+0x51最终生成的机器码偏移是0x4C,计算下来正好能跳到_start+0x51的位置,这部分逻辑是对的。不过手动写一堆nop很容易数错数量,建议用汇编器的重复指令自动填充,避免位置偏差。

2. 绝对跳转的错误

  • 初始代码里mov eax, 0x403000在64位环境下会把rax的高32位清零,虽然0x403000是32位有效地址,但直接用mov rax, 0x403000更稳妥,避免潜在的地址截断问题。
  • 你补充的jmp fword ptr [eax]完全错误:fword ptr是6字节宽度,不适合64位环境;而且[eax]是访问内存地址,相当于跳转到0x403000这个地址里存储的内容,而不是跳转到0x403000本身,彻底违背了需求。正确的绝对跳转逻辑就是把目标地址存入通用寄存器,然后通过jmp 寄存器实现跳转。

3. 栈顶取值的正确性

pop rdi本身符合需求,但要确保程序执行到这里时栈顶有合法值,不过这属于调用上下文的问题,代码本身的指令逻辑是正确的。

修正后的代码

.intel_syntax noprefix
.global _start
_start:
    jmp $+0x51  # 汇编器自动转换为正确的相对偏移,目标是_start+0x51
    .rept 0x51 - 5  # jmp指令占5字节,自动填充对应数量的nop
        nop
    .endr
    pop rdi
    mov rax, 0x403000  # 64位环境下直接赋值rax
    jmp rax  # 跳转到寄存器存储的绝对地址0x403000

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 07:55:17