美文网首页
gameboy反汇编

gameboy反汇编

作者: 杰_6343 | 来源:发表于2025-08-24 23:22 被阅读0次

一、启动过程

当gameboy通电后,机子会从内存地址为0的地方开始运行一段长度为256字节的程序,这段程序是固化在gameboy内部的ROM(只读存储器)上的。

这段程序的作用是,把卡带中从104H到133H地址的任天堂的LOGO读取出来并显示在屏幕的最上方。这个LOGO会滚动到屏幕中间,然后会播放两个提示音。然后会把从这个地址段读出来的数据和内部数据进行比较,如果比较失败,则停止运行。如果比较通过,则把地址从134H到14DH的数据逐个相加,再把相加的结果加25,如果最后得到的结果的最低有效位不为0,则停止运行。否则,内部程序运行结束,机子会从卡带地址100H处开始执行实际的游戏指令,同时设置寄存器为以下值:

AF=$01B0

  BC=$0013

  DE=$00D8

  HL=$014D

  Stack Pointer=$FFFE

  [$FF05] = $00  ; TIMA

  [$FF06] = $00  ; TMA

  [$FF07] = $00  ; TAC

  [$FF10] = $80  ; NR10

  [$FF11] = $BF  ; NR11

  [$FF12] = $F3  ; NR12

  [$FF14] = $BF  ; NR14

  [$FF16] = $3F  ; NR21

  [$FF17] = $00  ; NR22

  [$FF19] = $BF  ; NR24

  [$FF1A] = $7F  ; NR30

  [$FF1B] = $FF  ; NR31

  [$FF1C] = $9F  ; NR32

  [$FF1E] = $BF  ; NR33

  [$FF20] = $FF  ; NR41

  [$FF21] = $00  ; NR42

  [$FF22] = $00  ; NR43

  [$FF23] = $BF  ; NR30

  [$FF24] = $77  ; NR50

  [$FF25] = $F3  ; NR51

  [$FF26] = $F1-GB, $F0-SGB ; NR52

  [$FF40] = $91  ; LCDC

  [$FF42] = $00  ; SCY

  [$FF43] = $00  ; SCX

  [$FF45] = $00  ; LYC

  [$FF47] = $FC  ; BGP

  [$FF48] = $FF  ; OBP0

  [$FF49] = $FF  ; OBP1

  [$FF4A] = $00  ; WY

  [$FF4B] = $00  ; WX

  [$FFFF] = $00  ; IE

二、Rom文件的反汇编

好了,现在知道了ROM的文件结构(参考上一篇文章),知道了gameboy从ROM的什么地方开始执行指令,接下来就要对ROM进行反汇编,看看ROM的实际内容是什么东西。

先说一下反汇编的思路:首先按字节从ROM文件中读取单个字节的数据,然后根据gameboy的CPU指令手册,把读出来的数据翻译成相应的CPU指令输出成文本,这样就能看到ROM的内容了。

有了思路之后我们就开始着手实现吧,嘿嘿嘿,首先需要一个gameboy的CPU指令手册,可以从网上找到相应的资料。这个是我找到的CPU的参考资料:http://www.myquest.nl/z80undocumented/z80cpu_um.pdf

从资料中可以知道,gameboy用的CPU是8位的,从程序的角度讲,就是CPU一次能从内存中读取8个位,刚好一个字节的数据到内部,所以我们要逐个字节分析,接下来这个是gameboy的CPU所用到的指令:http://pastraiser.com/cpu/gameboy/gameboy_opcodes.html

从表格中我们可以知道每条指令的长度,以及每条指令对应的二进制数,而且我们看可以看到有些指令是用一个字节表示,有些指令是用两个字节表示,而且两个字节的指令都是以十六进制数CB开头的。注意:一条完整的指令应该包括指令的操作符和操作数,这里说的一个字节、两个字节只是用来表示指令的操作符,不包含操作数,所以完整的指令长度还应该包含标识指令操作数的长度。我们可以先获取到指令的操作符,然后再根据地址中给出的表格来查询出指令的操作数以及完整指令的指令长度。

对于两个字节长度的操作符,CPU会先读第一个字节,如果第一个字节是CB的话,则再读下一个字节,这样根据第二个字节读到的值,就可以通过查表来确定该两个字节长度的操作符是什么了。

那么CPU怎么知道它读出来的就一定是操作符,而不是操作数或别的什么东西呢。

首先,CPU一定是从读取第一个指令的操作符开始的,然后通过翻译该操作符,再获取到这条指令使用到的操作数。接着执行该条指令,执行完后再去读取下一个指令。所以这就要求CPU在翻译指令的时候,最先读取出来的一定是指令的操作符,这样才能确定该条指令的长度,以及实用那些操作数等这些指令的附加信息。

所以,我们在模拟gameboy的CPU进行翻译指令的时候(也就是通常所说的译码),首先读取进来的一定是CPU的指令的操作符,这时如果读取的值是CB,则我们就可以知道当前处理的是一个双字节长度的操作符,接着我们需要读取下一个地址的字节数据,然后通过这次读取出来的数据来确定当前世纪的操作符是什么。

相关文章

  • 第四次寒假集训

    都说天上不会掉馅饼,但有一天gameboy正走在回家的小径上,忽然天上掉下大把大把的馅饼。说来gameboy的人品...

  • iOS逆向之OC反汇编(下)

    本文主要理解OC对象反汇编,以及block常见类型的反汇编 OC反汇编 创建一个Person类,并在main函数中...

  • 对抗反汇编方法

    1.插入流氓字节,阻止真正的指令被反汇编 线性反汇编和面向代码流的反汇编: 线性反汇编是遍历一个代码段,一次一条指...

  • 各种 iPhone 透明外壳透视壁纸

    90后的科友还记得透明版任天堂吗? ↓↓透明GameBoy↓↓ 小编小时候曾经热爱过透明版的 GameBoy、GB...

  • 一个java 比较迷惑的问题

    反汇编bytecode

  • Gameboy的经典

    OliverWorlds File 106 从我开始认真接触电玩这个东西开始,在我的潜意识里,电玩主机一直被我划分...

  • 007——逆向之OC反汇编

    block反汇编 全局静态block 反汇编的代码如下: 当看到0x100c121e8 <+12>: adrp ...

  • 计算机病毒分析

    一、ollydbg(od反汇编工具) ollydbg(od反汇编工具是当前逆向工程主流的动态跟踪调试工具,olly...

  • 程序调用过程和堆栈的关系,为什么要传地址而不传值

    bug.c 使用gdb调试,main函数反汇编的代码 swap函数的反汇编代码 在执行到call swap函数之前...

  • od调试笔记

    反汇编窗口: 作用:ollydbg在这里显示反汇编代码 在此可以进行调试 这里可以进行关闭分析 寄存器窗口: 堆栈...

网友评论

      本文标题:gameboy反汇编

      本文链接:https://www.haomeiwen.com/subject/ctglajtx.html