Z80 Maschinencode, 8 6 Bytes *
<8ww8>
* Unter bestimmten Bedingungen von Amstrad BASIC eingeben
< 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
ist anfangs 0, wenn von BASIC eingegeben. Es wird A
n- mal inkrementiert und dann n- mal an denselben Speicherort geschrieben (der von BASIC auf einen leicht zufälligen Speicherort festgelegt wurde)! Die JR
Operation "Relativ springen" führt zu keinem Ergebnis, da das C
Flag immer nicht gesetzt ist. Daher wird das folgende Byte "auskommentiert". Diese Version schummelt leicht, wenn bestimmte Einreisebedingungen vorausgesetzt werden, nämlich, dass die Einreise aus den BASIC-Garantien A
immer 0 (HL)
ist. Der folgende Code ist viel robuster, weshalb er viel länger ist.
Z80-Maschinencode, 30 Byte
Als ASCII:
o!.ww.!>A=o>{))((}<o=A<!.ww.!o
Grundsätzlich garantiert die erste Hälfte die Erzeugung eines Nullwerts und die zweite Hälfte erhöht ihn und schreibt ihn in den Speicher. In der erweiterten Version ##
bezeichnet unten Code, der in seiner Hälfte des Spiegels keinen Zweck erfüllt.
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
Aufschlüsselung der erlaubten Anweisungen:
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
Von den 39 zulässigen Befehlen sind 28 Ladeoperationen (die Blöcke von 0x40 bis 0x7F sind alle Einzelbyte- LD
Befehle), von denen die meisten hier keine Hilfe sind! Die einzige Anweisung LD (HL), A
zum Laden in den Speicher, die noch zulässig ist , bedeutet, dass ich den Wert in speichern muss A
. Da dies A
das einzige Register ist, in dem eine INC
Anweisung zulässig ist , ist dies praktisch.
Ich kann nicht A
mit 0x00 beginnen, da ASCII 0x00 kein zulässiges Zeichen ist! Alle verfügbaren Werte sind weit von 0 entfernt und alle mathematischen und logischen Anweisungen wurden nicht zugelassen! Außer ... ich kann immer ADD HL, HL
noch 16-Bit HL
zu sich selbst hinzufügen ! Abgesehen vom direkten Laden von Werten (hier keine Verwendung!), Dem Inkrementieren A
und Dekrementieren A
, L
oder HL
nur so kann ich den Wert eines Registers ändern! Es gibt tatsächlich eine spezielle Anweisung, die in der ersten Hälfte hilfreich sein könnte, aber in der zweiten Hälfte ein Problem, das umgangen werden muss, und eine ergänzende Anweisung, die hier fast nutzlos ist und nur Platz beansprucht.
Also fand ich den nächsten Wert zu 0, den ich finden konnte: 0x41. Wie ist das nahe bei 0? In der Binärdatei ist es 0x01000001. Also dekrementiere ich es, lade es hinein L
und mache es ADD HL, HL
zweimal! L
ist jetzt null, in die ich wieder lade A
! Leider für den ASCII - Code ADD HL, HL
ist )
so ich jetzt verwenden müssen (
zweimal. Zum Glück (
ist JR Z, e
, wo e
ist das nächste Byte. Also verschlingt es das zweite Byte und ich muss nur sicherstellen, dass es nichts tut, indem ich vorsichtig mit der Z
Flagge bin ! Die letzte Anweisung, die das Z
Flag beeinflusste, war DEC A
( ADD HL, HL
nicht intuitiv zu ändern) und da ich weiß, dass A
es zu diesem Zeitpunkt 0x40 war, ist garantiert, dass Z
es nicht gesetzt ist.
Die erste Anweisung in der zweiten Hälfte JR Z, #28
wird die ersten 255-mal nichts tun, da das Z-Flag nur gesetzt werden kann, wenn A von 255 auf 0 übergelaufen ist. Danach ist die Ausgabe jedoch falsch, da ohnehin nur 8-Bit-Werte gespeichert werden sollte keine Rolle spielen. Der Code sollte nicht mehr als 255 Mal erweitert werden.
Der Code muss als Snippet ausgeführt werden, da alle verfügbaren Methoden zur sauberen Rückgabe nicht zugelassen wurden. Alle RETurn-Befehle liegen über 0x80 und die wenigen erlaubten Sprungoperationen können nur zu einem positiven Offset springen, da auch alle negativen 8-Bit-Werte nicht erlaubt wurden!
#
ist dies auch eine eigene Relektion, aber Sie haben Recht, nicht in Konsolen.