Машинный код 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
изначально 0 при вводе из бейсика. Он увеличивает A
n раз, а затем записывает его n раз в одну и ту же ячейку памяти (которую BASIC устанавливает в слегка случайную позицию)! Операция JR
Jump Relative никогда не делает ничего, поскольку C
флаг всегда не установлен, поэтому используется для «закомментирования» следующего байта! Эта версия слегка обманывает, предполагая определенные условия входа, а именно, вход из BASIC гарантирует, что A
всегда 0. Местоположение (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
с 0x00, чтобы начать с, потому что ASCII 0x00 не разрешенный символ! Все доступные значения далеки от 0, и все математические и логические инструкции запрещены! За исключением ... Я все еще могу сделать ADD HL, HL
, добавить 16-битный HL
себе! Помимо прямой загрузки значений (здесь нет смысла!), INCrementing A
и DECrementing A
, L
или HL
это единственный способ изменить значение регистра! На самом деле есть одна специальная инструкция, которая может быть полезна в первой половине, но во второй половине боль обходится, и инструкция с одним дополнением, которая здесь почти бесполезна и просто займет место.
Итак, я нашел наиболее близкое значение к 0, которое я мог: 0x41. Как это близко к 0? В двоичном виде это 0x01000001. Поэтому я уменьшаю его, загружаю L
и делаю ADD HL, HL
дважды! L
теперь ноль, который я загружаю обратно A
! К сожалению, код ASCII для ADD HL, HL
это , )
так что я теперь нужно использовать (
дважды. К счастью, (
это JR Z, e
, где e
находятся следующие байты. Таким образом, он поглощает второй байт, и мне просто нужно убедиться, что он ничего не делает, будучи осторожным с Z
флагом! Последней инструкцией, влияющей на Z
флаг, была DEC A
(нелогично, ADD HL, HL
не меняет ее), и, поскольку я знаю, что A
в тот момент это было 0x40, гарантируется, что Z
она не установлена.
Первая инструкция во второй половине JR Z, #28
ничего не будет делать первые 255 раз, потому что флаг Z может быть установлен только в том случае, если A переполнился с 255 до 0. Однако после этого выходной сигнал будет неправильным, поскольку в любом случае он сохраняет только 8-битные значения, не должно иметь значения. Код не должен быть расширен более 255 раз.
Код должен быть выполнен как фрагмент кода, поскольку все доступные способы возврата полностью запрещены. Все инструкции RETurn превышают 0x80, и несколько разрешенных операций перехода могут переходить только к положительному смещению, поскольку все 8-битные отрицательные значения также запрещены!
#
тоже есть свое отражение, но, вы правы, не в консолах.