前回の記事の UEFI ゴルフの続報です。
Hello world はどの環境でも文字列出力関数(API, メソッド, etc...)を呼び出すだけなのでコードはほぼ定型となりコード部分の最適化の余地はほとんどありませんでした。
ゴルフのお題のひとつに CHARS というものがあり、これは印字可能 ASCII 文字の一覧を出力するものです。
CHARS は固定の文字列データが存在しないのでロジックの最適化で Hello world より小さくできる可能性が高いです。
ということで、試行錯誤の末にヘッダの圧縮とセットで 268 バイトまで削減することができました。
EfiMain: push rbx push rdi enter 0x20, 0 mov rdi, rdx mov ebx, 0x20 .loop: mov rcx, [rdi + 0x40] ; EFI_SYSTEM_TABLE->ConOut lea rdx, [rbp + 0x20] mov [rdx], ebx call [rcx + 0x08] ; EFI_SIMPLE_OUTPUT_PROTOCOL->OutputString inc ebx cmp bl, 0x7F jb .loop xor eax, eax leave pop rdi pop rbx ret
なお、最後に改行を入れてないのでシェルのプロンプトによって表示が一部破壊されてしまいます。これがレギュレーション的に OK だったかどうかよく覚えてません...
実際には push/pop を使わないバージョンも一応動きはするのですが、なぜか起動しません。
そこですぐに ret する何もしないアプリケーションを作って nop の量を調整して調査した所、どういうわけかテキストセクションのサイズが 0x28 (40) バイトに満たないバイナリは問答無用でエラーになるようです。
つまり、これ以上ロジックを最適化しても意味がないということで、ゴルフ終了・・・?
ねり先生の次回作にご期待ください。
成果物を GitHub に公開しておきます。