Unix中的奇怪评论和奇怪行为(丹尼斯·里奇)

2020-09-07 08:56:18

在Unix的贝尔实验室研究发布中,它经常被引用为对评论数量或质量的诽谤。我担心总体上不是错误的观察,但在这种情况下是不合理的。实际的代码和围绕它的其他注释恰恰是这样的:/**切换到新进程的堆栈并设置*HIS分段寄存器。*/retu(rp->;p_addr);sureg();/**如果新进程因为*换出而暂停,请将堆栈级别设置为对savu(U_Ssav)的最后一次调用*。这意味着,在调用aretu*之后立即执行的return*实际上是从执行*savu的最后一个例程返回的。**您不需要理解这一点。*/if(rp->;p_flag&;SSWAP){rp->;p_flag=&;~SSWAP;aretu(U.U_ssav);}/**此处返回的值有许多微妙的含义。*见newproc评论。*/return(1);

因此,我们试图解释到底是怎么回事。你不应该理解这是本着“这不会出现在考试中”的精神,而不是作为一种厚颜无耻的挑战。真正的问题是,我们也不知道发生了什么。进行进程交换的SAVU/RETU机制从根本上被破坏了,因为它依赖于切换到前一个堆栈帧,并在与保存较早状态的过程不同的过程中执行函数返回代码。这在PDP-11上有效,因为它的编译器总是使用相同的上下文保存机制;对于InterData编译器,过程返回代码根据保存的寄存器而有所不同。所以,对于Steve Johnson和我来说,第一次试图将内核移到一台新机器上,这段代码确实在考试中。我们花了大约一周的时间苦苦挣扎,才最终让对方相信这个机制是错误的,没有摆弄编译器是有用的。我们完全重新做了协程控制传递原语,这段代码和注释,进入了历史。在像PDP-11这样的16位机器上做32位乘除需要很聪明。我的PDP-11 C编译器使用子例程来执行long*和/。乘法例程是用于固定pt硬件的//32位乘法例程。/Implementes*运算符/信用给一个将其偷偷溜到门下的未知作者。globl lmul.globl CSV,cretlmul:JSR R5,CSV mov 6(R5),R2 SXT R1 sub4(R5),R1 mov 10.(R5),R0 SXT R3 sub8。(R5)。

这很巧妙,而且我还不够聪明,弄不明白。不过,我并不感到内疚,因为我当时不知道是谁推荐的,而且我承认了这一事实。但我会暂时记住这一点。除法例程包括1:MOV R4,-(Sp)CLR R0 div R3,R0 mov R0,R4/高商mov R1,R0 mov R2,R1 div R3,R0 BVC 1f sub R3,R0/这是巧妙的部分div R3,R0 TST R1 SXT R1加上R1,R0/不能溢出!1:

我几乎(或者甚至完全)弄明白了它为什么会起作用。灵魂上的位置是";这是最聪明的部分。NSOF的阿莫斯·沙皮尔(而且记忆力很好!)。只是在一封邮件中把这个地方弄黑(或加宽)了一点,也就是说:我收集了几乎所有的信息,这是因为这个把戏几乎奏效了。它有一个令人讨厌的虫子,我不得不费了好大劲才找到的!聪明的部分依赖于这样一个事实,即如果不取";bvc 1f&34;,则意味着结果不能容纳在16位中;在这种情况下,R0、R1中的长值保持不变。错误在于这种行为没有文档记录;在后来的模型中(我在11/34上发现了这一点),当结果适合16位而不是15位时(即,有符号类型的溢出,但不是无符号类型的溢出),溢出位被设置,但是无符号的结果会覆盖原始值--这使得这个例程提供非常奇怪的结果!

回到1970-71年左右,PDP-11/20上的Unix运行在硬件上,这些硬件不仅不支持虚拟内存,而且不支持任何类型的硬件内存映射或保护,例如防止覆盖内核。这很痛苦,因为我们要为多个用户使用这台机器。当任何人在编写程序时,在尝试之前大喊一声,以警告其他人保存他们正在编辑的内容,这被认为是一种礼貌。[一个小故事:有几个人在某个时候坐在那里工作。鲍勃·莫里斯几乎是在交谈中问道,有什么理由支持身份证?有人告诉了他。接下来的一分钟,我们继续打字,因为一种思想开始渗透,还没有完全达到大脑的顶端--换句话说,还不够快。终端在任何人停下来说等一下鲍勃,你想做什么?";]我们知道PDP-11/45确实支持内核和其他进程的内存映射和保护,但不会立即出现;考虑到这一点,我们与Digital Special Systems安排购买了带有KS-11附加组件的APDP-11/20。这是一个额外的系统单位符号