法则。 你要生存, 就要不断在磨砺中改变自己。 幸运的是, 在虚拟机中做到这点要比在现代编译环境中容易的
多。
顺便说一句,很容易看出在磁芯世界中没有缓存一说。嗯,事实上当前指令是要被缓存的,这样你便不能 在
执行中改变指令,但这些我们要留到以后再说 ..........
The
The
The
The
Dwarf
Dwarf
Dwarf
Dwarf
(
(
(
(
魔戒中的矮人族
)
)
)
)
IMP 程序还是有一定缺点。 它并不能打败多少对手, 因为当它将自身覆盖对手时, 需要尽早执行以占得先
机,
这就束缚了自己。要干掉 IMP ,只需在它之后放一个结束指令。
下面是另一个经典的磁芯程序 Dwarf, 它是由 Dewdney 编写的。它每隔几个内存单元便用 DAT 炸弹轰炸, 当
然要确保不会自虐。
ADD #4, 3
MOV 2, @2
JMP -2
DAT
#0, #0
事实上,它与 Dewdney 所编写的最初版本有所不同,但工作原理相同(可以参考引自焦点的那篇文章) 。 指
令自第一行 ADD 指令执行。 ADD 指令是将源地址数据与目的地址数据相加,再存入目的地址单元。如果你熟 悉
其他的汇编语言,便会注意到 # 代表立即数。就是这样,第一条指令将内存地址为 3( 即相对于 IP 基址 +3, 下文均
同此 ) 处的 B 数据区加 4 ,这可不是将地址 4 中数据加到地址 3 的单元中( -_- 废话,我译不明白,大家知道真正
意思就好了) 。最后结果为:
ADD #4, 3
MOV 2, @2 ; next instruction
JMP -2
DAT
#0, #4 ; 注意改变
如果你同时对两个数据区进行操作,那么 A
、
B 数据区数据便会彼此相加再存入。如果指令中包含一个立 即
数,那么默认对 B 数据相加操作。因此将 A+B => B 时,一定要带 # 符。
立即数方式还比较亲切,但在 '94 标准中又对此进行了扩展,不过我们先按下不提,首要任务是搞明白这个
例子。
不同于我们当前接触的直接寻址模式, @ 代表 间接 寻址模式。他意味着数据并不是拷贝到当前单元所存放 的
内存地址处,而是将 B 中所指向的内存单元中的数据作为操作地址。就像这样 :
ADD #4, 3
MOV 2, @2 ; --.
JMP -2 ; | +2
DAT
#0, #4 ; <--' --. B 数据区直接指向
.
... |
... | +4
... |
DAT
#0, #4 ; <------' B 数据区间接(真正)指向
.
如你所见, DAT 标志被拷贝到程序后的第四个内存单元。 下一条指令将跳转会程序起始位置,即 ADD 指
令。
因为在 JMP 指令中的 B 数据区为空,系统将自动初始化 0 。
现在要再一次执行 ADD 与 MOV 指令。当再一次执行到 JMP 时,内核状态如下 :
ADD #4, 3
MOV 2, @2
JMP -2 ; next instruction
DAT
#0, #8
...
...
...
DAT
#0, #4
...