Código máquina Z80, 8 6 bytes *
<8ww8>
* Asume ciertas condiciones al ingresar desde 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
es inicialmente 0 cuando se ingresa desde BASIC. ¡Incrementa A
n veces, luego lo escribe n veces en la misma ubicación de memoria (que BASIC establece en una ubicación ligeramente aleatoria)! losJR
operación Jump Relative nunca hace nada, ya que el C
indicador siempre está desactivado, por lo que se utiliza para "comentar" el siguiente byte. Esta versión es un poco engañosa al asumir ciertas condiciones de entrada, es decir, ingresar desde BASIC garantiza que A
siempre es 0. La ubicación de (HL)
no está garantizada como segura, y de hecho, es probablemente una ubicación peligrosa. El siguiente código es mucho más robusto, por lo que es mucho más largo.
Código máquina Z80, 30 bytes
Como ASCII:
o!.ww.!>A=o>{))((}<o=A<!.ww.!o
Básicamente, la primera mitad garantiza la creación de un valor cero y la segunda mitad lo incrementa y lo escribe en la memoria. En la versión ampliada a continuación, se ##
indica un código que no sirve para nada en su mitad del espejo.
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
Desglose de las instrucciones permitidas:
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
De las 39 instrucciones permitidas, 28 son operaciones de carga (el bloque de 0x40 a 0x7F son LD
instrucciones de un solo byte ), ¡la mayoría de las cuales no ayudan aquí! La única instrucción de carga en memoria aún permitida es lo LD (HL), A
que significa que tengo que almacenar el valor A
. Dado que A
es el único registro que queda con un permitidoINC
instrucción , ¡esto es realmente muy útil!
¡No puedo cargar A
con 0x00 para empezar porque ASCII 0x00 no es un personaje permitido! ¡Todos los valores disponibles están lejos de 0 y todas las instrucciones matemáticas y lógicas han sido rechazadas! Excepto ... que aún puedo hacer ADD HL, HL
, ¡agregar 16 bits HL
a sí mismo! Además de cargar directamente los valores (¡no se usa aquí!), INCrementing A
y DECrementing A
, L
oHL
esta es la única forma que tengo de cambiar el valor de un registro! En realidad, hay una instrucción especializada que podría ser útil en la primera mitad, pero un trabajo difícil de resolver en la segunda mitad, y una instrucción complementaria que es casi inútil aquí y que solo ocuparía espacio.
Entonces, encontré el valor más cercano a 0 que pude: 0x41. ¿Cómo es eso cerca de 0? En binario es 0x01000001. ¡Así que lo decremento, lo cargo L
y lo hago ADD HL, HL
dos veces! L
ahora es cero, que vuelvo a cargar A
! Desafortunadamente, el código ASCII ADD HL, HL
es )
así que ahora necesito usar (
dos veces. Afortunadamente, (
es JR Z, e
, ¿dónde e
está el próximo byte? ¡Así que engulle el segundo byte y solo necesito asegurarme de que no haga nada teniendo cuidado con la Z
bandera! La última instrucción para afectar el Z
indicador fue DEC A
(contra intuitivamente, ADD HL, HL
no lo cambia) y como sé que A
era 0x40 en ese punto, está garantizado que Z
no está configurado.
La primera instrucción en la segunda mitad. JR Z, #28
no hará nada las primeras 255 veces porque el indicador Z solo se puede establecer si A se ha desbordado de 255 a 0. Después de eso, la salida será incorrecta, ya que de todos modos solo está guardando valores de 8 bits que no debería importar El código no debe expandirse más de 255 veces.
El código debe ejecutarse como un fragmento, ya que se han rechazado todas las formas disponibles de regresar limpiamente. Todas las instrucciones de RETORNO están por encima de 0x80 y las pocas operaciones de salto permitidas solo pueden saltar a un desplazamiento positivo, ¡porque todos los valores negativos de 8 bits también se han rechazado!
#
es su propia versión, pero, tienes razón, no en consolas.