解析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
技术疑问
- 该解压例程的具体格式是什么?压缩数据如何结构化并完成解压?
- 内存地址$44在例程中的具体作用是什么?
- 例程中的位左移(ASL)和循环移位(ROL)操作的用途是什么?
注:已有压缩数据和解压后数据可供参考。
内容的提问来源于stack exchange,提问作者HoosierTransfer
相关产品推荐
相关产品推荐

