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

はじめに

今回の内容は以下の記事の続きになります。

[IPSwitch] 誰でもできるコード開発 #4 (opens new window)

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

時間変更コード

以下のコードは ナワバリバトルとガチマッチの時間を変更するものです。

// Turf War (3.1.0)
@disabled
01181038 20008052 // MOV W0, #1
// Turf War (5.4.0)
@disabled
01367358 20008052 // MOV W0, #1
1
2
3
4
5
6
7
// Ranked Match (3.1.0)
@disabled
01180B78 20008052 // MOV W0, #1
// Ranked Match (5.4.0)
@disabled
01366E68 20008052 // MOV W0, #1
1
2
3
4
5
6
7

今回はこれが何を意味するかについて解説していこうと思います。

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

HEX to ARM Converter で ARM64 に変換すると以下のコードであることがわかります。

20008052 // MOV W0, #1
1

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

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

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

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

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

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

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

ARM HEX 進数
MOV W0, #2809 205F8152 10 進数
MOV W0, 2809 205F8152 10 進数
MOV W0, #0xAF9 205F8152 16 進数

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

// Turf War (46:49) (3.1.0)
@disabled
01181038 205F8152 // MOV W0, #2809
// Turf War (46:49) (5.4.0)
@disabled
01367358 205F8152 // MOV W0, #2809
1
2
3
4
5
6
7
// Ranked Match (46:49) (3.1.0)
@disabled
01180B78 205F8152 // MOV W0, #2809
// Ranked Match (46:49) (5.4.0)
@disabled
01366E68 205F8152 // MOV W0, #2809
1
2
3
4
5
6
7

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

どこまで長くできるか

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

// Turf War (18:12:15) (3.1.0)
@disabled
01181038 E0FF9F52 // MOV W0, #0xFFFF
// Turf War (18:12:49) (5.4.0)
@disabled
01367358 E0FF9F52 // MOV W0, #0xFFFF
1
2
3
4
5
6
7
// Ranked Match (18:12:15) (3.1.0)
@disabled
01180B78 E0FF9F52 // MOV W0, #0xFFFF
// Ranked Match (18:12:15) (5.4.0)
@disabled
01366E68 E0FF9F52 // MOV W0, #0xFFFF
1
2
3
4
5
6
7

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

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

ARM HEX
ORN W0, W0, WZR 00003F2A
ORN W0, W0, W0 0000202A
EON W0, W0, W0 0000204A

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

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

ARM 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 日くらいガチマッチが遊べるコードが完成しました。

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

記事は以上。