0

很抱歉,这不是正确的地方,但我正拼命地试图理解这个汇编脚本中发生的事情(我假设就是这样,基于我已经完成的谷歌搜索时间。)它是口袋妖怪黄色版的rom,我了解一些但不是全部。我想如果我能得到一些帮助来理解这一段在做什么,我可以弄清楚其余的。代码如下所示:

PalletTownScript:
    CheckEvent EVENT_GOT_POKEBALLS_FROM_OAK
    jr z, .next
    SetEvent EVENT_PALLET_AFTER_GETTING_POKEBALLS
.next
    call EnableAutoTextBoxDrawing
    ld hl, PalletTownScriptPointers
    ld a, [wPalletTownCurScript]
    jp JumpTable

我的理解是第一行只是将其余部分放入名为“PalletTownScript”的标签中,只是稍后引用的名称。第二行检查是否发生了某个事件,详细信息在另一个文件中。到目前为止一切都很好。第三行是对我来说变得复杂的地方。我确定“jr”跳转到脚本的另一部分,然后返回这里?我认为?但是,据我所见,每个示例只有一个参数,而这一行有两个。是跳到z吗?什么是z?我已经搜索了这个文件的其余部分,并且没有名为 z 的部分。z 是另一个函数吗?另一个参数是 .next,据我所知,它是 PalletTownScript 部分的一个子部分。所以它跳到那里是有道理的(但为什么要跳呢?如果它 s 就在那里,它不就是这样做吗?)但我仍然不知道“z”在那里做什么。在.next中,它调用了一些东西并加载了一些其他东西,这很好,但最后,它跳转到另一个文件中的JumpTable(我假设它全部编译后都没有关系,所以我'我不关心那个),但它仍然跳转到.next,然后再次跳转到JumpTable吗?它什么时候回去做那个 SetEvent?之后它会去哪里?m 不关心),但它仍然跳转到 .next,然后再次跳转到 JumpTable?它什么时候回去做那个 SetEvent?之后它会去哪里?m 不关心),但它仍然跳转到 .next,然后再次跳转到 JumpTable?它什么时候回去做那个 SetEvent?之后它会去哪里?

我以前从未处理过大会,这对我来说非常困惑,所以如果有人可以在这方面给我一些帮助,我将不胜感激。谢谢!

4

3 回答 3

5

jr z, .next是有条件的相对跳跃。只有在设置了零标志(在 F 寄存器中)时才会进行跳转。

如果事件EVENT_GOT_POKEBALLS_FROM_OAK已经发生,则事件EVENT_PALLET_AFTER_GETTING_POKEBALLS变为已设置。

如果没有,SetEvent EVENT_PALLET_AFTER_GETTING_POKEBALLS则跳过。

CheckEvent和宏在SetEvent这里定义:https ://github.com/pret/pokered/blob/master/macros/scripts/events.asm

于 2020-05-09T06:54:52.273 回答
1

汇编程序应逐行读取。每一行都可以

  1. 注释(被 CPU 忽略),
  2. 一个标签(程序中这个地方的符号名称),
  3. 机器指令(CPU 执行某些操作的命令),
  4. 宏(在源文件的其他地方或包含在主源中的其他源文件中定义的一堆机器指令的符号名称)

在心理上将每个陈述想象成一个做某事的黑匣子。为了理解每条语句,它应该记录它的输入、它的作用、输出是什么、是否有任何附带损害(损坏的寄存器或标志、不平衡的堆栈、异常)。CPU貌似是Zilog Z80,其机器指令的助记符快捷键在http://nemesis.lonestar.org/computers/tandy/software/apps/m4/qd/opcodes.html中,并附有简要说明。在您的代码段中,我们可以识别机器指令jr, call, ld, jp. Z80 有 8 位寄存器a, b, c, d, e, h, l, 其中一些可以连接起来形成一个 16 位对: bc,de, hl. 它还具有 1 位“寄存器” z,称为标志c,可以通过某些指令设置或重置,因此它们会记住先前语句的结果。处理器可以根据标志使用条件跳转来分支其进一步执行,例如. 如果前面的语句已将标志设置为true,则跳转到,否则将被忽略。标签没有魔法,它只是一种汇编程序将您的手指指向程序流中特定位置的方式。pjr z, .nextzjr.nextjr

如果您想知道z之前的语句是设置还是重置
CheckEvent EVENT_GOT_POKEBALLS_FROM_OAK,您必须CheckEvent在包含的源文件中使用 grep for 并希望宏定义与其文档一起提供。Pokemon ROM 中的标签、符号和宏名称是健谈的(不幸的是,在 asm 程序中并非总是如此),因此很容易猜测宏将z在(无论它意味着什么)发生时重置标志EVENT_GOT_POKEBALLS_FROM_OAK,否则以下条件跳转命令 CPU 跳过宏指令
SetEvent EVENT_PALLET_AFTER_GETTING_POKEBALLS并在标签处继续.next

.

于 2020-05-09T07:06:16.890 回答
1

其他答案很好地解释了它,但是您对跳跃有误解。

我确定“jr”跳转到脚本的另一部分,然后返回这里?我认为?

Jump ( jrand jp) 不返回,它只是更改程序计数器,它的 C 等效项是goto. call(and rst) 是像函数一样返回的,它将当前 pc 存储在堆栈中,更改 pc 然后在到达ret/时从堆栈中恢复 pc reti

之后它会去哪里?

它只是去JumpTable而永远不会回来。


PokeRed 使用 RGBDS,这是有据可查的。

指令说明: https ://rgbds.gbdev.io/docs/v0.5.0/gbz80.7

宏等其他语法说明: https ://rgbds.gbdev.io/docs/v0.5.0/rgbasm.5

于 2021-05-06T02:59:04.793 回答