アセンブラ短歌やってみた。

アセンブラ短歌」は五・七・五・七・七の三十一バイト(みそひとバイト)から成る機械語コードでプログラムを書いてみるという近未来の文化的趣味であり,近年,国内のハッカー間で密かなブームが起きています.http://kozos.jp/asm-tanka/

 はっかーもすなるあせんぶら短歌といふものを、ぼくもしてみんとて、するなり。

 大昔に学校でならった古文的な何か*1をインスパイアしつつ、今日はアセンブラ短歌について書いてみました。国内のハッカー間で密かなブームが起きているアセンブラ短歌、ぼくもエンジニアのはしくれとしてやってみたい! と思ったのですが、ぼくのマシン、Windows7なのでちょっとアセンブラ短歌には向いてなさそう…。というわけでAssembler Tanka on Javascriptでやってみました。

ba f8 03 00 00
68 61 6e 6b 61 90 90
68 41 53 4d 54
8b dc b9 08 00 00 00
8a 03 43 ee e2 fa 90

 これがデフォルトのアセンブラ短歌です。逆アセンブルしたコードがこちらです。

baf8030000: mov edx, 0x3f8  #5
68616e6b61: push 0x616b6e61 #7
        90: nop
        90: nop
6841534d54: push 0x544d5341 #5
      8bdc: mov ebx, esp    #7
b908000000: mov ecx, 0x8
      8a03: mov al, [ebx]   #7
        43: inc ebx
        ee: out dx, al
      e2fa: loop 0x18
        90: nop

 これで8文字出力できています。

 しかし無駄が多いですね。まずb908000000: mov ecx, 0x8ってやつをなんとかしましょう。xor ecx, ecxで2バイト、mov cl, 0x08で2バイトの計4バイトに短縮できます。さっそく1バイト確保です。

NG) b908000000: mov ecx, 0x8
OK)       33c9: xor ecx, ecx
          b10c: mov cl, 0xc

 2バイトずつになったので短歌にも組み込みやすくなりました。

 あとは先頭のbaf8030000: mov edx, 0x3f8もなんとかしたいですね。できればここに684c6f7665: push 0x65766f4cをいれたいです。これができれば12文字出力できます。ここにpushをいれるとして、movはどこに移動しましょうか…。

 さっき2バイトずつに分けた片方、33c9: xor ecx, ecxを連続しているnopにいれれば3バイトは空けられそうです。

684c6f7665: push 0x65766f4c
68616e6b61: push 0x616b6e61
      33c9: xor ecx, ecx    ■ココにxor ecx, ecxをいれた
6841534d54: push 0x544d5341
      8bdc: mov ebx, esp
      b10c: mov cl, 0xc
        90: nop             ■この辺りにmov edx, 0x3f8をいれたい
        90: nop
        90: nop
      8a03: mov al, [ebx]
        43: inc ebx
        ee: out dx, al
      e2fa: loop 0x18
        90: nop

 あと2バイト、どうしましょうか。

 よくみると一番最後にも1バイト余っています。8a03: mov al, [ebx]を8a0424: mov al, [esp]にすれば、8bdc: mov ebx, espの2バイトがなくなり、3+2=5バイトが確保できます。

 というわけで、こんな感じになりました。

684c6f7665: push 0x65766f4c #5
68616e6b61: push 0x616b6e61 #7
      33c9: xor ecx, ecx
6841534d54: push 0x544d5341 #5
baf8030000: mov edx, 0x3f8  #7
      b10c: mov cl, 0xc
    8a0424: mov al, [esp]   #7
        44: inc esp
        ee: out dx, al
      e2f9: loop 0x18

 マシン語にするとこうですね。

68 4c 6f 76 65
68 61 6e 6b 61 33 c9
68 41 53 4d 54
ba f8 03 00 00 b1 0c
8a 04 24 44 ee e2 f9

 というわけでAssembler Tanka on Javascriptでは、12文字出力までやれることが分かりました。頑張ればもっといけるかもしれませんが、今日はこのへんで。ではでは。