我一直在研究1950年代“飞马”(Pegasus)计算机的仿真,并遇到了“自我修改的链接”一词。这是如何运作的?
最佳答案
首先请注意:
Pegasus计算机通过传递关于被调用方应如何返回的两条指令(在一个寄存器中)来支持子例程/函数调用-作为数据,即作为参数。然后,被调用方将采用该参数,将其存储到其自己的本地内存中,然后将控制权转移给该本地内存,从而执行调用方作为数据传递的两条指令。
call 者会这样做:
load instructions from L1: into X1 register
... pass other parameters ...
load callee's first block into U0
transfer control to U0 at start
L1: load instructions from main block back into U0
transfer control to U0 at desired caller resume point (e.g. L2)
L2: ...caller resumes...
call 者会这样做:
... compute something ...
store X1 into L4 # writes the two instruction pair in X1 into L4
transfer control to L4 # may or may not be present depending on location of L4
L4: # starts empty but contains the two instructions that came from L1
# so control is transferred back to the caller
L1上的序列永远不会直接执行,而是一个模板的模板,这些指令将作为参数传递给被调用方,被调用方将把该模板存储到自己的本地内存中,然后执行该副本。
他们使用术语“cue”进行调用(子例程调用,例如,将控制权转移到被调用方)和“链接”进行返回(将控制权从子例程转移回正确的调用者)(术语“orders”用于机器代码指令) 。
因此,当他们说“自修改链接”时,它们意味着子例程返回其调用者的机制使用self-modfying code,https://en.wikipedia.org/wiki/Ferranti_Pegasus是在执行时改变其自身指令的代码,即,写入指令存储器的代码即将执行。这是X1(L1处代码的副本)向L4的写入,写入后即立即执行。
如今,自修改代码通常会皱眉,因为它具有一些负面影响:指令高速缓存必须与自修改保持同步,这会影响性能,并且指令存储器必须是可写的,从而会影响安全性。 。
由于我们今天认为这是指令集中缺少的指令,例如在PDP-8中具有I / O指令,但I / O端口已被硬编码到指令中,因此在较旧的处理器中经常使用自我修改。没有间接I / O端口访问。因此,为了使子例程访问作为参数的I / O端口,使用了自修改代码来构造对该端口的I / O指令。 (也可以使用大的switch语句,但是会花费更多的代码。)这些较旧的处理器没有指令缓存,程序员和开发工具也没有强制将指令部分与数据部分分开(即它们没有)尝试保护说明)。
对于Pegasus,没有间接分支,从而阻碍了返回到 call 者提供的地址的功能。事实证明,调用者的代码实际上也可能被覆盖了-传递两条指令以使被调用者执行的能力既可以恢复调用者代码的寄存器块,又可以在该块中跳转。
(与其他自修改方案相比,传递完整格式的指令作为参数所产生的返回链接指令要少得多:动态地给定地址参数来构造一条跳转指令-这将需要更多条指令来进行位域操作。)
http://bitsavers.org/pdf/ferranti/pegasus/PegasusProgrammingMan_1962.pdf
ojit_a
关于assembly - “self-modified link”在Pegasus编程中如何工作?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/60207110/