Z80マシンコード、8 6バイト*
<8ww8>
* Amstrad BASICから入力して特定の条件を想定
< INC A // A=A+1
8w JR C, #77 ## C is unset unless A has overflowed, does nothing
w LD (HL), A // Saves A to memory location in HL (randomly initialised)
8> JR C, #3E ## C is still unset, does nothing
A
BASICから入力した場合、最初は0です。それ刻みA
のn倍、それに書き込むのn(BASICによって多少ランダムな位置に設定されている)同じメモリ位置に時間を!JR
以来、ジャンプ相対的な操作は何もしませんでしC
フラグが常に設定されていないので、次のバイト「コメントアウト」に使用されています!このバージョンは、特定の入力条件、つまりA
常に0であるBASIC保証からの入力を想定することにより、少しごまかしてい(HL)
ます。の位置は安全であるとは限りません。以下のコードははるかに堅牢であるため、非常に長くなります。
Z80マシンコード、30バイト
ASCIIとして:
o!.ww.!>A=o>{))((}<o=A<!.ww.!o
基本的に、前半はゼロ値の作成を保証し、後半はそれをインクリメントしてメモリに書き込みます。以下の拡張バージョンで##
は、ミラーの半分で目的を果たさないコードを示しています。
o LD L, A ##
!.w LD HL, #772E // Load specific address to not corrupt random memory!
w LD (HL), A ## Save random contents of A to memory
.! LD L, #21 ##
>A LD A, #41 // A=#41
= DEC A // A=#40
o LD L, A // L=#40
>{ LD A, #7B ##
) ADD HL, HL // HL=#EE80
) ADD HL, HL // HL=#DD00. L=#00 at this point
(( JR Z, #28 ##
} LD A, L // A=L
< INC A // A=L+1
o LD L, A // L=L+1
= DEC A // A=L
A LD B, C ##
< INC A // A=L+1
!.w LD HL, #772E // Load address back into HL
w LD (HL), A // Save contents of A to memory
.! LD L, #21 ##
o LD L, A // L=A
許可された指示の内訳:
n op description
-- ---- -----------
28 LD LoaD 8-bit or 16-bit register
3 DEC DECrement 8-bit or 16-bit register
1 INC INCrement 8-bit or 16-bit register
1 ADD ADD 8-bit or 16-bit register
Available but useless instructions:
3 JR Jump Relative to signed 8-bit offset
1 DAA Decimal Adjust Accumulator (treats the A register as two decimal digits
instead of two hexadecimal digits and adjusts it if necessary)
1 CPL 1s ComPLement A
1 HALT HALT the CPU until an interrupt is received
許可されている39個の命令のうち、28個はロード操作(0x40から0x7FまでのブロックはすべてシングルバイトLD
命令です)で、そのほとんどはここでは役に立ちません!まだ許可されているメモリ命令への唯一のロードはLD (HL), A
、値をに保存する必要があることを意味しA
ます。A
許可されたINC
命令を残した唯一のレジスタなので、これは実際には非常に便利です!
ロードできません A
ASCII 0x00は許可された文字ではないため、最初から0x00を!使用可能なすべての値は0からはほど遠いものであり、すべての数学および論理命令は許可されていません!を除いて...私はまだできるADD HL, HL
、HL
それ自体に16ビットを追加します!値を直接ロードする(ここでは使用しない!)、INCrementing A
およびDECrementing以外A
はL
、HL
これがレジスタの値を変更する唯一の方法です!実際には、前半には役立つかもしれないが後半には対処するのに苦労する特殊な命令と、ここではほとんど役に立たず、スペースを占有する1補数の命令があります。
だから、私は0に最も近い値を見つけました:0x41。それはどのように0に近いですか?バイナリでは0x01000001です。だから私はそれをデクリメントし、ロードして2回L
実行ADD HL, HL
します!L
ゼロになりましたA
。残念ながら、のASCIIコードADD HL, HL
は2回)
使用する必要があります(
。幸いなことに、(
あるJR Z, e
場合には、e
次のバイトがあります。したがって、2番目のバイトを飲み込んでしまいます。Z
フラグ!Z
フラグに影響を与える最後の命令はDEC A
(反直感的に、ADD HL, HL
変更しない)であり、A
その時点で0x40であったことがわかってZ
いるため、設定されていないことが保証されます。
JR Z, #28
Aが255から0にオーバーフローした場合にのみZフラグを設定できるため、後半の最初の命令は最初の255回は何もしません。ただし、その後は出力が間違っています関係ありません。コードは255回以上展開しないでください。
コードをスニペットとして実行する必要があるのは、きれいに戻るための利用可能なすべての方法が禁止されているためです。すべてのRETurn命令は0x80を超えており、8ビットの負の値もすべて許可されていないため、許可されるいくつかのジャンプ操作は正のオフセットにしかジャンプできません。
#
は、独自の修正もありますが、コンソラではなく、あなたは正しいです。