Codice macchina Z80, 8 6 byte *
<8ww8>
* Presuppone determinate condizioni entrando da 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
è inizialmente 0 quando inserito da BASIC. Aumenta A
n volte, quindi la scrive n volte nella stessa posizione di memoria (che è impostata su una posizione leggermente casuale da BASIC)! L' JR
operazione Jump Relative non fa mai nulla poiché il C
flag è sempre non impostato, quindi viene utilizzato per "commentare" il seguente byte! Questa versione è leggermente ingannevole assumendo determinate condizioni di accesso, vale a dire entrare da garanzie BASIC che A
sono sempre 0. La posizione di (HL)
non è garantita per essere sicura, e in effetti, è probabilmente una posizione pericolosa. Il codice seguente è molto più robusto ed è per questo che è molto più lungo.
Codice macchina Z80, 30 byte
Come ASCII:
o!.ww.!>A=o>{))((}<o=A<!.ww.!o
Fondamentalmente, la prima metà garantisce la creazione di un valore zero e la seconda metà lo incrementa e lo scrive in memoria. Nella versione estesa di seguito ##
indica il codice che non serve a nulla nella sua metà del mirror.
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
Ripartizione delle istruzioni consentite:
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
Delle 39 istruzioni consentite, 28 sono operazioni di caricamento (il blocco da 0x40 a 0x7F sono tutte LD
istruzioni a byte singolo ), la maggior parte delle quali non sono di aiuto qui! L'unico caricamento ancora consentito nella memoria è il LD (HL), A
che significa che devo memorizzare il valore A
. Poiché A
è l'unico registro rimasto con un'istruzione consentita INC
, questo è in realtà abbastanza utile!
Non posso caricare A
con 0x00 per cominciare perché ASCII 0x00 non è un carattere consentito! Tutti i valori disponibili sono lontani da 0 e tutte le istruzioni matematiche e logiche sono state vietate! Tranne ... posso ancora fare ADD HL, HL
, aggiungere 16 bit HL
a se stesso! Oltre a caricare direttamente i valori (non usare qui!), INCrementare A
e DECrementare A
, L
o HL
questo è l'unico modo che ho di cambiare il valore di un registro! Esiste in realtà un'istruzione specializzata che potrebbe essere utile nella prima metà, ma una seccatura da risolvere nella seconda metà, e un'istruzione a complemento a uno che è quasi inutile qui e occuperebbe solo spazio.
Quindi, ho trovato il valore più vicino a 0 che potevo: 0x41. Quanto è vicino a 0? In binario è 0x01000001. Quindi lo decremento, lo carico L
e lo faccio ADD HL, HL
due volte! L
è ora zero, che carico nuovamente A
! Sfortunatamente, il codice ASCII per ADD HL, HL
è )
quindi ora devo usare (
due volte. Fortunatamente, (
è JR Z, e
, dov'è e
il byte successivo. Quindi divora il secondo byte e devo solo assicurarmi che non faccia nulla facendo attenzione con la Z
bandiera! L'ultima istruzione per influenzare la Z
bandiera è stata DEC A
(controintuitivamente, ADD HL, HL
non la modifica) e poiché so che A
era 0x40 a quel punto è garantito che Z
non è impostato.
La prima istruzione nella seconda metà JR Z, #28
non farà nulla le prime 255 volte perché il flag Z può essere impostato solo se A ha traboccato da 255 a 0. Successivamente, l'output sarà errato, tuttavia dal momento che sta salvando comunque solo valori a 8 bit che non dovrebbe importare. Il codice non deve essere espanso più di 255 volte.
Il codice deve essere eseguito come frammento poiché tutti i modi disponibili per restituire in modo pulito sono stati vietati. Tutte le istruzioni RETurn sono superiori a 0x80 e le poche operazioni Jump consentite possono saltare solo a un offset positivo, poiché anche tutti i valori negativi a 8 bit sono stati vietati!
#
è presente anche il suo riferimento, ma, hai ragione, non nelle console.