z80 golf(6)

yaneurao2008-01-01


なんか世間ではお正月らしいが、


〇∧〃 でもそんなの関係ねぇ!
/ >   そんなの関係ねぇ!
< \  そんなの関係ねぇ!


ということで、気がついたら、ySasさんとkoderaさんが、z80の Hello, world!の19バイト達成。さすが常連、年季が入っている。ちなみに私が考えた19Bのコードは、これだ。



DB 95,124,131,131,134,67,55,142,134,137,131,123,56

HALT
DEC SP
POP AF
PUSH HL
SUB 23


Hello, world!の文字をencodeしてfall thoughさせ、DEC SP〜POP AFで、Aレジスタに1バイトずつ取り込み、PUSH HL(DEやBCなど破壊されていないゼロクリアされているレジスタならok)で取り込んだ文字をゼロクリアしながら、かつ、このゼロクリアされる0が1文字表示のサブルーチンである8000HをCALLしたときの戻りアドレスになっている。


SUB 23が問題の2バイト decodeで、ここを1バイト系のdecodeに変更したいが、いろいろ考えたが不可能という結論になった。そこで2バイトエンコードで何か効率的に命令が含まれるencode系を考えなければならないが、コードは1バイトずつ消失して行くので、最後まで実行されなくてはならない命令は、最後の1バイトに埋めなければならないが、最後の1バイトは、直後のHALTを包み隠すために2バイト命令の1バイト目でなければならないので、これは不可能である。


唯一、18Bに出来る可能性があるとしたら、このencodeの係数(ここでは23)をレジスタに代入するコードが、Hello, world!の文字列をencodeしたコード中に現れることだが、


・代入する命令コードが出現して、その命令コードの直後に必要な係数が現れる
・最後の1バイトは2バイト命令の1バイト目
・fall throughできること(haltやjpなどが出現しないこと。レジスタBC,DE,HLのいずれかが破壊されないこと)


という3つの条件を同時に満たす必要がある。SUB 23のSUBのところをADD/SUB/RRA/RRA/RLCA/NEG/CPL/XORなどで調べてみたが上記の条件を満たすコードは発見できなかった。要するに18B到達は私には不可能なように思える。


以下、追記。(2007/01/04)


書き忘れていた。もう一つ、18Bにする可能性があるとしたら、このように
http://www.nmt.ne.jp/~ysas/diary/?200801a&to=200801012#200801012
fall thoughされたときにHLを破壊されないなら、PUSH HL〜INC HLで戻り先アドレスを一つずつ増やしていき、Hello, world!の最後が2文字が、2バイト命令の1バイト目 + HALT(76h)になれば良いのだが、そういうencodeは私には見つけられなかった。