Kod maszynowy Z80, 8 6 bajtów *
<8ww8> * Przyjmuje określone warunki, wchodząc z 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
Apoczątkowo wynosi 0 po wprowadzeniu z BASIC. Przyrosty A n razy, a następnie zapisuje n razy do tej samej lokalizacji w pamięci (która jest ustawiona przez BASIC na nieco losową lokalizację)! Operacja JRJump Relative nigdy nie robi nic, ponieważ Cflaga jest zawsze rozbrojona, dlatego służy do „komentowania” następującego bajtu! Ta wersja nieco oszukuje, zakładając pewne warunki wejścia, a mianowicie wejście z gwarancji BASIC, która Azawsze wynosi 0. Lokalizacja (HL)nie jest gwarantowana jako bezpieczna, aw rzeczywistości jest to prawdopodobnie niebezpieczne miejsce. Poniższy kod jest znacznie bardziej niezawodny, dlatego jest o wiele dłuższy.
Kod maszynowy Z80, 30 bajtów
Jako ASCII:
o!.ww.!>A=o>{))((}<o=A<!.ww.!o
Zasadniczo pierwsza połowa gwarantuje utworzenie wartości zerowej, a druga połowa zwiększa ją i zapisuje w pamięci. W rozszerzonej wersji poniżej ##oznacza kod, który nie służy żadnemu celowi w jego połowie lustra.
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
Podział dozwolonych instrukcji:
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
Spośród 39 dozwolonych instrukcji 28 to operacje ładowania (blok od 0x40 do 0x7F to LDinstrukcje jednobajtowe ), z których większość tutaj nie pomaga! Jedyne dozwolone ładowanie do pamięci jest nadal dozwolone, LD (HL), Aco oznacza, że muszę zapisać wartość w A. Ponieważ Ajest to jedyny rejestr z dozwoloną INCinstrukcją, jest to całkiem przydatne!
Nie mogę załadować Az 0x00, ponieważ ASCII 0x00 nie jest dozwolonym znakiem! Wszystkie dostępne wartości są dalekie od 0, a wszystkie instrukcje matematyczne i logiczne zostały niedozwolone! Z wyjątkiem ... Nadal mogę ADD HL, HL, dodaj 16-bit HLdo siebie! Oprócz bezpośredniego ładowania wartości (tutaj nie ma zastosowania!), INKrementacji Ai DECrementacji A, Llub HLto jest jedyny sposób na zmianę wartości rejestru! W rzeczywistości jest jedna specjalistyczna instrukcja, która może być pomocna w pierwszej połowie, ale kłopot z obejściem w drugiej połowie, i instrukcja uzupełniająca, która jest prawie bezużyteczna tutaj i zajmuje tylko miejsce.
Znalazłem więc najbliższą wartość 0, którą mogłem: 0x41. Jak to jest bliskie zeru? W systemie binarnym jest to 0x01000001. Więc zmniejszam, ładuję Li robię ADD HL, HLdwa razy! Lma teraz zero, do którego ładuję ponownie A! Niestety kod ASCII dla ADD HL, HLjest, )więc muszę teraz użyć (dwa razy. Na szczęście (jest JR Z, e, gdzie ejest następny bajt. Więc pożera drugi bajt i muszę tylko upewnić się, że nic nie zrobi, uważając na Zflagę! Ostatnią instrukcją, która wpłynęła na Zflagę, była DEC A(sprzeczna z intuicją, ADD HL, HLnie zmienia jej), a ponieważ wiem, że Aw tym momencie była to 0x40, jest pewna, że Znie jest ustawiona.
Pierwsza instrukcja w drugiej połowie JR Z, #28nic nie zrobi przez pierwsze 255 razy, ponieważ flagę Z można ustawić tylko wtedy, gdy A przepełniło się z 255 do 0. Następnie dane wyjściowe będą błędne, jednak ponieważ i tak zapisuje tylko wartości 8-bitowe nie powinno mieć znaczenia. Kod nie powinien być rozszerzany więcej niż 255 razy.
Kod musi zostać wykonany jako fragment kodu, ponieważ wszystkie dostępne sposoby czystego powrotu zostały niedozwolone. Wszystkie instrukcje RETurn są powyżej 0x80, a kilka dozwolonych operacji Jump może przeskoczyć tylko do dodatniego przesunięcia, ponieważ wszystkie 8-bitowe wartości ujemne zostały również niedozwolone!
#jest to również jego własna relacja, ale masz rację, nie w konsolach.