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
从BASIC输入时最初为0。它递增A
n次,然后将n次写入相同的内存位置(BASIC将其设置为稍微随机的位置)!将JR
跳转相对操作从来不做事,因为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次中将不执行任何操作,因为仅当A从255溢出到0时才可以设置Z标志。此后输出将是错误的,但是由于无论如何它仅保存8位值没关系。该代码不应扩展超过255次。
由于不允许使用所有干净返回的方法,因此必须将代码作为摘要执行。所有的RETurn指令都在0x80以上,并且允许的几个跳转操作只能跳转到正偏移量,因为所有8位负值也都被禁止!
#
它也是自己的选择,但是,您是对的,而不是在consolas中。