[IPSwitch] 誰でもできるコード開発 #5

はじめに

この記事を読むにあたって必ず目を通して理解しておいてください。

今回はガチマッチやナワバリバトルの時間を変更するコードをいろいろ弄ってみましょう。

時間変更コード

// Ranked Match
@disabled
0134B1E4 20008052

// Turf War
@disabled
0134B6D4 20008052

アドレスが違うだけで変更する値は同じです。

ちなみに後ろの命令部を見てみると以下のようになっています。

00028052 -> 16s
00608052 -> 12m48s

これの意味がよくわかっていない人が多いので解説しようと思います。

0002で16秒で0060で13分(正確には12分48秒)…

16秒も見つけるの苦労したよ。

秒数で計算数らしいけどやり方わかんない。

機械語をアセンブラに変換

せっかくなのでこれが何を意味するか考えてみます。HEX To ARM ConberterでARM64に変換すると以下のコードであることがわかります。

20008052 -> MOVZ W0, #0x1

というか、命令部は必ずARMに変換しないと意味がわからないので戻しましょうね。

このときW0に代入するのが試合の残り時間の秒数ですので、ここに好きな数字を代入すれば上手く動作します。

例えば試合時間を46分49秒にしたければまずこれを秒数に変換します。

これは小学生であれば計算できますね。

なのでW0に2809を代入すれば良いことがわかります。

アセンブラを機械語に変換

よってこれを実装するためのアセンブラは次の三つのうちのどれかです。

MOVZ W0, 2809 -> 205F8152 // DEC
MOVZ W0, #2809 -> 205F8152 // DEC
MOVZ W0, #0xAF9 -> 205F8152 // HEX

どのアセンブラでも得られる機械語は同じなので問題ないです。

// Ranked Match (46:49)
@disabled
0134B1E4 205F8152

// Turf War (46:49)
@disabled
0134B6D4 205F8152

あとはこれをIPSwitchをつかってパッチを当てるだけですね。

無事に46:49のガチホコバトルができました。

どこまで長くできるか

一行だけのMOVZのコードであれば最大で16bitまで指定できるので、最も長くすると以下のようになります。

MOVZ W0, #0xFFFF -> E0FF9F52

// Ranked Match (18:12:15)
@disabled
0134B1E4 205F8152

// Turf War (18:12:49)
@disabled
0134B6D4 205F8152

もちろんこれはMOVZのみで実装した場合の話なので、上手いアセンブラを考えるとこれ以上に長くすることはできます。

最も長くなるのは全てのビット列が1だった場合なので、全てのビットが1のレジスタをセットすれば良いことになります。

ORN W0, W0, WZR -> 00003F2A
ORN W0, W0, W0 -> 0000202A
EON W0, W0, W0 -> 0000204A

三つのコードは意味するところは違いますが、動作の仕組みとしては同じです。

ORNは否定論理和ですので、C言語風に記述するとそれぞれ以下のようになります。

ORN W0, W0, WZR
-> W0 = W0 | ~WZR

ORN W0, W0, W0
-> W0 = W0 | ~W0

EON W0, W0, W0
-> W0 = W0 ^ ~W0

WZRはゼロレジスタと呼ばれ、全てのビットが0である値を返すのでそれの否定は全て1のビットが返ります。

それと論理和を取れば全てのビットが1になるのは明白です。

後者も自身とそれの否定の論理和は取れば必ず全てのビットが1になります。

排他的論理和はビットが同じなら0が返るので、自身とそれの否定の排他的論理和は必ず全てのビットが1になります。

やってみた

ところが実際にこれらのコードを動かしてみると始まった瞬間に延長になってしまいます。

多分数が大きすぎてオーバーフローしてしまっているとかそんなのだと思います、残念。

頑張って実装した最高記録

その後ちまちま修正して頑張って時間を延ばした結果、412日くらいガチマッチが遊べるコードが完成しました。

なんでこんなところにキャップがあるのかは不明ですが、限界チャレンジは結構楽しめたので良かったです。