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

解析SNES游戏《侏罗纪公园》自定义解压例程的技术问询

SNES《侏罗纪公园》自定义解压例程逆向分析疑问

更新说明

  • 我不再认为该例程采用游程编码(RLE),目前完全无法确定其压缩格式。

项目背景

我正在开展SNES游戏《侏罗纪公园》汇编代码的逆向分析项目,核心目标是研究其中一个自定义解压例程。目前已为大部分代码添加注释并理解基础逻辑,但仍无法明确以下关键信息:具体解压格式、部分内存地址的作用、部分位操作的用途。

汇编代码片段

; Y寄存器存储解压后数据的地址
; 内存地址$44、$48的用途是什么?
; 内存地址$46似乎用于存储MVN操作中要传输的字节数
; 内存地址$48似乎用于存储源地址与目标地址的偏移量
; 我仍在尝试搞清楚位移位和循环移位操作的用途

CODE_81B18B:
    STX.b $40 ; 压缩数据的地址
    STA.b $42 ; 压缩数据的存储库

    ; 已搞清楚这段代码的作用:在不改变处理器状态的情况下将数据库设置为7F
    ; 这么做是为了后续执行MVN操作
    ; 等价代码如下:
    ; SEP.b #$20
    ; PHB
    ; LDA #$7F
    ; PHA
    ; PLB
    ; REP #$20

    PHB
    LDA.w #$7F7F
    PHA
    PLB
    PLB
    
    ; 初始化循环条件
    LDA.w #$8000 ; 为什么是0x8000?
    BRA CODE_81B1B6 ; 无条件跳转到CODE_81B1B6

CODE_81B19B:
    LDX.w #$0100
    STX.b $44
CODE_81B1A0:
    ASL
    BNE.b CODE_81B1AA ; 循环1.1.1
    LDA.b [$40] ; 加载压缩数据
    INC.b $40
    INC.b $40
    ROL
CODE_81B1AA:
    ROL.b $44
    BCC.b CODE_81B1A0 ; 当左移产生进位时退出循环1.1.2
    ; 将解压后的字节存入输出
    TAX
    LDA.b $44
    STA.w $0000,y ; 存储解压后数据
    INY
    TXA
CODE_81B1B6: ; 解压循环第一部分的起点
    ASL
    ; 检测数据是否已完成解压
    BNE.b CODE_81B1C0 
    LDA.b [$40] ; 加载压缩数据
    INC.b $40
    INC.b $40
    ROL
CODE_81B1C0:
    BCC.b CODE_81B19B 
    ASL
    BNE.b CODE_81B1CC
    LDA.b [$40] ; 加载压缩数据
    INC.b $40
    INC.b $40
    ROL
CODE_81B1CC:
    BCS.b CODE_81B1D5
    LDX.w #$0000 
    STX.b $46 ; 将传输字节数设为0
    BRA.b CODE_81B208

; 以下代码用于计算重复的字节数
; 以及重复字节的范围

CODE_81B1D5: ; 满足特定条件时进入解压第二部分
    LDX.w #$2000
    STX.b $46 ; 将传输字节数设为0x2000
CODE_81B1DA:
    ASL
    BNE.b CODE_81B1E4 ; 当A为0或$46为0时执行后续指令:循环2.1.1
    LDA.b [$40] ; 加载压缩数据
    INC.b $40
    INC.b $40
    ROL
CODE_81B1E4: ; 解压第二部分循环的起点
    ROL.b $46
    BCC.b CODE_81B1DA ; 重复直到$46为0:循环2.1.2
    BNE.b CODE_81B208 ; 解压编码数据
    LDX.w #$0100
    STX.b $46
CODE_81B1EF:
    ASL
    BNE.b CODE_81B1F9 ; 当A为0或$46为0时执行后续指令:循环2.2.1
    LDA.b [$40] ; 加载压缩数据
    INC.b $40
    INC.b $40
    ROL
CODE_81B1F9:
    ROL.b $46
    BCC.b CODE_81B1EF ; 重复直到$46为0:循环2.2.2
    BEQ.b CODE_81B22A ; 如果A为0,则解压完成,退出例程
    ; 否则继续解压编码数据
    TAX
    LDA.w #$0006 ; 给传输字节数加6???
    ADC.b $46
    STA.b $46
    TXA
CODE_81B208:
    LDX.w #$0040
    STX.b $48
CODE_81B20D:
    ASL
    BNE.b CODE_81B217 ; 不确定这段的作用
    LDA.b [$40] ; 加载压缩数据
    INC.b $40
    INC.b $40
    ROL
CODE_81B217:
    ; 这是解压例程的核心部分
    ; 使用MVN指令重复数据
    ; $46存储要传输的字节数
    ; X存储源地址的高低字节
    ; Y存储目标地址的高低字节
    ROL.b $48
    BCC.b CODE_81B20D
    PHA ; 保存A寄存器
    TYA ; 将目标地址存入A寄存器
    SBC.b $48
    DEC
    TAX ; 计算源地址
    LDA.b $46
    INC ; 给传输字节数加1
    MVN $7F,$7F
    PLA ; 恢复A寄存器原值
    BRA.b CODE_81B1B6 ; 进入下一轮解压循环

CODE_81B22A:
    PLB
    RTL

技术疑问

  1. 该解压例程的具体格式是什么?压缩数据如何结构化并完成解压?
  2. 内存地址$44在例程中的具体作用是什么?
  3. 例程中的位左移(ASL)和循环移位(ROL)操作的用途是什么?

注:已有压缩数据和解压后数据可供参考。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 14:14:53