SWF Binary Golf on FlashLite

先週の土曜日の勉強会で発表した資料を公開します。

FizzBuzz SWF Binary Golf on FlashLite 1.1

FizzBuzz SWF Binary Golf on FlashLite 1.1
http://namazu.org/~takesako/swf/FizzBuzz-SWF-Golf.ppt

申し訳ないことにActionScriptの話は一つもでてきません。
SWFファイルの構造解析とASバイトコードの話です。
そんなシチュエーションがあるかどうかわかりませんが、
SWFファイルのバイナリを直接いじりたいときに役に立つのではないかと。

勉強会ではどの発表も面白かったのですが、個人的にはBeInteractive!のyossyさんとASバイトコードの話ができて嬉しかったです。

[お約束] SWF で FizzBuzz ってみた

とりあえず

(1) 正解のFizzBuzz文字列をそのまま出力した場合 -> 478 byte (FlashLite1.1)
http://namazu.org/~takesako/swf/fizz478.txt

(2) FizzBuzzを計算しながら出力した場合 -> 251 byte (FlashLite1.1)
http://namazu.org/~takesako/swf/fizz251.txt

(3) FizzBuzzを計算しながら出力した場合 -> 159 byte (FlashLite2.0)
http://namazu.org/~takesako/swf/fizz159.txt

ここまで圧縮できました。

ASバイトコード最適化

ASバイトコードの最適化の過程はこんな感じで

http://namazu.org/~takesako/swf/

--- fizz287.flm	
+++ fizz161.flm
@@ -1,71 +1,48 @@
-movie 'fizz287.swf' // flash 4, total frames: 1, frame rate: 12 fps, 104x104 px
+movie 'fizz161.swf' compressed // flash 6, total frames: 1, frame rate: 12 fps, 104x104 px

   frame 0
-    push 'i', '0'
-    setVariable
    label1:
-    push 'i', 'i'
+    push '100', 'i', 'i', 'i'
     getVariable
     increment
     setVariable
-    push '100', 'i'
     getVariable
     oldLessThan
-    not
-    not
     branchIfTrue label6
-    push 'x', 'x', 'x'
-    getVariable
-    push 'i'
+    push 'x', 'x'
     getVariable
     push 'i'
     getVariable
     push '15'
-    divide
-    int
-    push '15'
-    multiply
-    subtract
+    modulo
     branchIfTrue label2
     push 'FizzBuzz'
     branch label5
    label2:
     push 'i'
     getVariable
-    push 'i'
-    getVariable
     push '5'
-    divide
-    int
-    push '5'
-    multiply
-    subtract
+    modulo
     branchIfTrue label3
     push 'Buzz'
     branch label5
    label3:
     push 'i'
     getVariable
-    push 'i'
-    getVariable
     push '3'
-    divide
-    int
-    push '3'
-    multiply
-    subtract
+    modulo
     branchIfTrue label4
     push 'Fizz'
     branch label5
    label4:
     push 'i'
     getVariable
    label5:
     concat
     push ' '
     concat
     setVariable
     branch label1
    label6:
   end // of frame 0
end

yossyさんから教えてもらったFlasmのコードでASバイトコードを読みやすい形に変換しています。

最後のFizzBuzz159byteへの圧縮は、ちょっとトリッキーなことをしています。

僕はActionScriptの経験は素人以下ですが、SWFバイナリの話ならできますので、
またどこかでAS関係のイベントがあれば声を掛けてくださると嬉しいです。(><)

この度は貴重な勉強会に参加できてよかったです。ありがとうございました。

コメントは受け付けていません。