• GBA平台ASM学习手记 第三天

    2009-04-06

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://www.blogbus.com/liuyanghejerry-logs/37521340.html

    第三天

    今天看到了HackMew放出的ASM教程,收获很大.原来GBA的ASM分为THUMB模式和ARM模式,二者的命令差不多,但THUMB的方式会比ARM更快更轻量.

    借助HackMew的教程,我新认识了一种汇编工具(名字忘了...),同时进一步明白了thethethethe的ASM代码的意思.


    以往对:
    [code]
     .text
    .align 2
    .thumb
    .thumb_func
    .global main

    main:;这句懂...
      push {r0-r4, lr}
    [/code]
    这一部分完全不理解,查ARM指令表亦不得其解.
    现在终于明白了这部分前面是汇编器用来包含功能的代码,和我们的ASM本身无关.

    后面的push命令本身也不是标准ARM指令,而是使用THUMB方法时将寄存器内容压入栈的方法.因为这里被压入了,所以最终还要再压出,也就是最后的pop指令了.

    目前的疑惑是,我们应当如何获取ROM运行时各个数据在RAM中的位置,比如这段:

    [code]
    .pokedata:
      .word 0x02024284
    .var1:
      .word 0x020370b8
    .var2:
      .word 0x020370ba
    .var3:
      .word 0x020370b8
    [/code]
    至少应该有一张地图来说明RAM中各数据的位置吧...

    另外在拜读了6遍之后,终于明白了"ldr r0, [r0]"的含义:r0在当前状态装载的是一个内存地址,该语句则把内存地址所对应的值读入到r0.

    看来汇编中也有类似指针的东西啊...

    借鉴了HackMew的教程,顺便写了一段ASM:
    [code]
    .text
    .align 2
    .thumb
    .thumb_func
    .global asm1

    main:  ;FR_ONLY
      push {r0-r1, lr}
      ldr r0, .PLAYER_DATA
      ldr r0, [r0]
      ldr r1, .VAR1
      ldrh r0, [r0, #0xE] ;带有h后缀的读写命令表示为半字节操作
      strh r0, [r1]
      pop {r0-r1, pc}


    .align 2
    .PLAYER_DATA:
      .word 0x0300500C
    .VAR1:
      .word 0x020270B6 + (0x800D * 2)
    [/code]

    该ASM代码可以读出游戏已经进行的时间(仅小时数,而且是16进制值),存放到变量0x800D中.

    以下是转好的HEX,把它们写到一个ROM空位里:

    03B5034800680349C089088003BDC0460C500003D0700302

    在脚本中我们可以这样用:
    [code]
    #org @1
    lock
    faceplayer
    callasm 0x[地址]+1'注意了,HEX插入的地址必须+1,这是THUMB模式必须的
    buffernumber 0x00 0x800D'buffer系的命令可以把HEX换成DEC
    message @2 0x2
    release
    end

    #org @2
    = You've been playing for [buffer1] hours!
    [/code]

    效果:


    以上只是一个例子,事实上这里提供了一种获得时间的命令,拿它可以做的事还很多.

    分享到:

    评论

  • 你一玩就7H....
    回复说:
    那是别人的存档……
    另外,玩了N个小时后照样可以回到小镇啊……
    2009-05-05 12:36:03
  • 摸摸头
    回复依怜说:
    欢迎~~
    2009-05-05 12:36:10