Code machine Z80, 8 6 octets *
<8ww8>
* Suppose certaines conditions en entrant depuis 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
est initialement 0 lorsqu'il est entré depuis BASIC. Il incrémente A
n fois, puis l'écrit n fois dans le même emplacement mémoire (qui est défini sur un emplacement légèrement aléatoire par BASIC)! L' JR
opération Jump Relative ne fait jamais rien car le C
drapeau est toujours non défini, il est donc utilisé pour "commenter" l'octet suivant! Cette version triche légèrement en supposant certaines conditions d'entrée, à savoir la saisie à partir des garanties BASIC qui A
est toujours 0. L'emplacement de(HL)
n'est pas garanti pour être sûr, et en fait, est probablement un endroit dangereux. Le code ci-dessous est beaucoup plus robuste, c'est pourquoi il est tellement plus long.
Code machine Z80, 30 octets
En ASCII:
o!.ww.!>A=o>{))((}<o=A<!.ww.!o
Fondamentalement, la première moitié garantit la création d'une valeur nulle et la seconde moitié l'incrémente et l'écrit en mémoire. Dans la version développée ci-dessous ##
désigne un code qui ne sert à rien dans sa moitié du miroir.
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
Répartition des instructions autorisées:
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
Sur les 39 instructions autorisées, 28 sont des opérations de chargement (le bloc de 0x40 à 0x7F sont toutes des LD
instructions à un octet ), dont la plupart ne sont d'aucune utilité ici! La seule instruction de chargement en mémoire encore autorisée est LD (HL), A
ce qui signifie que je dois stocker la valeur dans A
. Puisque A
c'est le seul registre qui reste avec une INC
instruction autorisée , c'est en fait assez pratique!
Je ne peux pas charger A
avec 0x00 pour commencer car ASCII 0x00 n'est pas un caractère autorisé! Toutes les valeurs disponibles sont loin de 0 et toutes les instructions mathématiques et logiques ont été interdites! Sauf que ... je peux encore le faire ADD HL, HL
, ajouter du 16 bits HL
à lui - même! Hormis le chargement direct de valeurs (inutile ici!), INCrementing A
et DECrementing A
, L
ou HL
c'est la seule façon dont j'ai de changer la valeur d'un registre! Il y a en fait une instruction spécialisée qui pourrait être utile dans la première moitié mais une douleur à contourner dans la seconde moitié, et une instruction complémentaire qui est presque inutile ici et prendrait juste de la place.
J'ai donc trouvé la valeur la plus proche de 0 que je pouvais: 0x41. Comment est-ce proche de 0? En binaire, c'est 0x01000001. Je le décrémente donc, le charge L
et le fais ADD HL, HL
deux fois! L
est maintenant nul, dans lequel je charge de nouveau A
! Malheureusement, le code ASCII pour ADD HL, HL
est )
donc je dois maintenant utiliser (
deux fois. Heureusement, (
est JR Z, e
, où e
est l'octet suivant. Donc, il engloutit le deuxième octet et je dois juste m'assurer qu'il ne fait rien en faisant attention au Z
drapeau! La dernière instruction pour affecter l' Z
indicateur a été DEC A
(contre-intuitivement, ADD HL, HL
ne le change pas) et puisque je sais que A
c'était 0x40 à ce point, il est garanti que ce Z
n'est pas défini.
La première instruction de la seconde moitié JR Z, #28
ne fera rien les 255 premières fois car l'indicateur Z ne peut être défini que si A a dépassé de 255 à 0. Après cela, la sortie sera erronée, cependant, car elle ne sauvegarde de toute façon que des valeurs de 8 bits qui ne devrait pas avoir d'importance. Le code ne doit pas être développé plus de 255 fois.
Le code doit être exécuté comme un extrait de code, car tous les moyens disponibles pour retourner proprement ont été interdits. Toutes les instructions RETurn sont supérieures à 0x80 et les quelques opérations de saut autorisées ne peuvent que passer à un décalage positif, car toutes les valeurs négatives à 8 bits ont également été interdites!
#
c'est aussi sa propre reflexion, mais, vous avez raison, pas dans les consoles.