Blog

上下文切换比函数调用更加复杂

Content #

切换到异常处理程序,比起函数调用,还是要更复杂一些。原因有下面几点。

第一点,因为异常情况往往发生在程序正常执行的预期之外,比如中断、故障发生的时候。所以,除了本来程序压栈要做的事情之外,我们还需要把 CPU 内当前运行程序用到的所有寄存器,都放到栈里面。最典型的就是条件码寄存器里面的内容。

第二点,像陷阱这样的异常,涉及程序指令在用户态和内核态之间的切换。对应压栈的时候,对应的数据是压到内核栈里,而不是程序栈里。

第三点,像故障这样的异常,在异常处理程序执行完成之后。从栈里返回出来,继续执行的不是顺序的下一条指令,而是故障发生的当前指令。因为当前指令因为故障没有正常执行成功,必须重新去执行一次。

所以,对于异常这样的处理流程,不像是顺序执行的指令间的函数调用关系。而是更像两个不同的独立进程之间在 CPU 层面的切换,所以这个过程我们称之为上下文切换(Context Switch)。

Viewpoints #

From #

28 | 异常和中断:程序出错了怎么办?

中断、陷阱、故障和中止

中断、陷阱、故障和中止

Content #

异常可以由硬件触发,也可以由软件触发。

中断(Interrupt) #

自然就是程序在执行到一半的时候,被打断了。这个打断执行的信号,来自于 CPU 外部的 I/O 设备。你在键盘上按下一个按键,就会对应触发一个相应的信号到达 CPU 里面。CPU 里面某个开关的值发生了变化,也就触发了一个中断类型的异常。

陷阱(Trap) #

陷阱,其实是我们程序员“故意“主动触发的异常。就好像你在程序里面打了一个断点,这个断点就是设下的一个"陷阱"。当程序的指令执行到这个位置的时候,就掉到了这个陷阱当中。然后,对应的异常处理程序就会来处理这个"陷阱"当中的猎物。

最常见的一类陷阱,发生在我们的应用程序调用系统调用的时候,也就是从程序的用户态切换到内核态的时候。可以用Linux 下的 time 指令,去查看一个程序运行实际花费的时间,里面有在用户态花费的时间(user time),也有在内核态发生的时间(system time)。

我们的应用程序通过系统调用去读取文件、创建进程,其实也是通过触发一次陷阱来进行的。这是因为,我们用户态的应用程序没有权限来做这些事情,需要把对应的流程转交给有权限的异常处理程序来进行。

故障(Fault) #

它和陷阱的区别在于,陷阱是我们开发程序的时候刻意触发的异常,而故障通常不是。比如,我们在程序执行的过程中,进行加法计算发生了溢出,其实就是故障类型的异常。这个异常不是我们在开发的时候计划内的,也一样需要有对应的异常处理程序去处理。

故障和陷阱、中断的一个重要区别是,故障在异常程序处理完成之后,仍然回来处理当前的指令,而不是去执行程序中的下一条指令。因为当前的指令因为故障的原因并没有成功执行完成。

中止(Abort) #

与其说这是一种异常类型,不如说这是故障的一种特殊情况。当 CPU 遇到了故障,但是恢复不过来的时候,程序就不得不中止了。

在这四种异常里,中断异常的信号来自系统外部,而不是在程序自己执行的过程中,所以我们称之为“异步”类型的异常。而陷阱、故障以及中止类型的异常,是在程序执行的过程中发生的,所以我们称之为“同步“类型的异常。

在处理异常的过程当中,无论是异步的中断,还是同步的陷阱和故障,我们都是采用同一套处理流程,也就是上面所说的,“保存现场、异常代码查询、异常处理程序调用“。而中止类型的异常,其实是在故障类型异常的一种特殊情况。当故障发生,但是我们发现没有异常处理程序能够处理这种异常的情况下,程序就不得不进入中止状态,也就是最终会退出当前的程序执行。

Viewpoints #

From #

28 | 异常和中断:程序出错了怎么办?

关系性攻击

Content #

回想一下,我把攻击定义为伤害他人的意图,“伤害”并不总是指身体对抗。女性比男性更容易参与更具社会性的攻击行为,尼基·克里克(Nikki Crick)和她的同事称之为关系性攻击,即通过破坏他人的名誉和关系来伤害他人。回避、散布虚假谣言和恶意流言蜚语、诽谤以及“荡妇羞辱”都是最好的例子,其后果可能是毁灭性的。关系性攻击中的一般性别差异开始得很早:在一项研究中,三到五岁的儿童三人一组玩耍,实验者要求孩子们用蜡笔给白纸上的图片上色。他们提供了三支蜡笔,但只有一支是彩色的(橙色),另外两支是白色的。当然,孩子们都想得到橙色的蜡笔。男孩们用身体攻击来得到它,用手击打或推搡那个有橙色蜡笔的孩子。女孩们则利用关系性攻击,散布用橙色蜡笔孩子的有关谣言,或者孤立她让她哭泣。

根据为政府提供的一份关于儿童安全和在线技术的审查报告,青少年在互联网上面临的最大危险来源不是色情制品(很多青少年,通常是男孩,都会寻求色情制品),甚至不是成年人诱拐,更不是色情短信。报告发现,无论是线上还是线下,未成年人面对的最常见威胁,都是来自同龄人的关系性攻击。

From #

接种效应(inoculation effect)

Content #

在个人层面上,抗拒会导致我们抵消那些告诉我们必须如何行事的命令或指示。但是还有一种更有效的、更谨慎的方式来抵制说服。我们已经看到,对于说服大多数听众来说,双向的、包含赞成和反对两方面观点的呈现,比单向的呈现更有效。在这一现象的基础上,威廉·麦圭尔(William McGuire)和他的同事们提出了他们所称的接种效应(inoculation effect):如果让人们先接触某一简短的宣传,而且接着他们能够对其加以反驳,人们就会对后来大规模出现的同样观点产生“免疫”,这就如同在人体内注入少量经过稀释的病毒可以帮助人们对这种病毒的大规模进攻产生“免疫”。

通过接受“小剂量”反对他们观点的论据(轻微的攻击),人们便可以对后来更强有力的反对他们最初观点的论据免疫。相反,如果人们对某个问题没有太多的思考——也就是说,如果他们通过外围路径形成了自己的态度,比如通过情感、熟悉度或同龄人——他们特别容易受到对自己观点的全面攻击。他们在捍卫自己的观点时将缺乏现实依据。这就是为什么有实验研究发现,给人们接种9·11事件的事实,会增加他们对随后有关那场悲剧的阴谋论宣传的抵抗力。

接种“疫苗”增加了我们对后期说服的抵抗力,因为我们有动机去捍卫我们的信仰,我们通过强迫自己去审视为什么要坚持这些信仰而获得了一些现实依据。当然,有时对反对者的批评和合理的辩论持开放态度,可能会导致更好的选择:改变我们的观点!在我看来,这里值得强调的一点对于教育目的的实现至关重要:如果我们想减少单纯宣传的影响,就没有什么可以替代对各种思想的自由探索。最容易被洗脑的人,是那些信仰基于从未受到过严重挑战的口号的人。

对我而言,这项研究的结果是,让我们的想法受到挑战会有很大的好处——要么让我们相信我们所珍视的一些信仰可能是错误的,要么迫使我们思考我们信仰的原因,并比以往更深刻地理解这些原因。

From #

单向与双向观点

Content #

假设你要做一场演讲,试图说服你的听众死刑是必要的。如果你只是陈述了你的观点而忽略了反对死刑的观点,你会说服更多的人吗?如果你讨论了相反的观点并试图反驳它们,你会更有说服力吗?

在回答这个问题之前,让我们先看看这里都涉及到什么。如果沟通者提到了反对者的观点,这可能表明他(她)是一个客观、公正的人;这可以增强演讲者的可信度,从而提高其效力。但是,如果一个沟通者如此多地提到问题另一方的观点,它可能会提醒听众这个问题是有争议的;这可能给他们的思想带来混乱,使他们动摇,并最终降低沟通的说服力。

而且事实上,单向观点和它们的有效性之间没有简单的对应关系。如果听众对这个话题越了解,那么他们被单向观点说服的可能性就越小,此时提出重要的对立观点然后继续反驳这些观点,则会提高说服的可能性。这是合乎道理的:一个见多识广的人更有可能知道一些对立的观点。当沟通者避免提及这类观点时,知识渊博的听众很可能会得出这样的结论:沟通者要么不公平,要么无法反驳他们。

相反,一个事前不了解的人,对对立的观点知之甚少或一无所知,因此他们很可能被他们所听到的一方观点所说服;如果听到了相反的观点,他们则可能会对自己到底赞同哪一种观点感到困惑。

另一个因素是听众最初的观点。如果观众已经倾向于相信传播者的观点,那么单向的陈述对他们的观点产生的影响要大于双向陈述。然而,如果听众倾向于相反的观点,那么双面驳斥就会更有说服力。

大多数政治家都很清楚这种现象,这就是为什么他们倾向于做出截然不同的演讲,这完全取决于所面对的听众。在与党内忠诚人士交谈时,他们几乎总是提出一系列令人毛骨悚然的论据,支持他们自己的政党纲领和候选人资格。如果他们确实提到了反对意见,那也是以一种嘲弄的语气。但是,当他们出现在电视上,或是对忠诚于不同党派的听众演讲时,他们倾向于采取一种更为外交的立场,在着手反驳之前,就对方的观点给出一个相当准确的介绍。

From #

不要统计数字,要用生动的语言

Content #

几年前,我和我的学生尝试劝说房主进行必要的改造,以拥有一所节能的房子。我们与当地公用事业公司的家庭审计员合作,并指导他们在推荐家庭装修时使用生动的案例。大多数审计员在自行采取策略时,只是指出门周围的裂缝,并建议屋主安装挡风雨条。相反,我们训练他们告诉房主,如果所有门上的裂缝加起来,他们的客厅墙壁上就会有一个篮球大小的洞。“如果你的墙上有一个那么大的洞,你不想把它补起来吗?挡风雨条就是用来补洞的。”接受过使用这种生动语言培训的审计员将其效率提高了四倍。尽管此前接受建议的房主只有15%,但在审计员开始使用更生动的语言之后,这个数字增加到了61%。

因为大多数人受到一个个具体案例的影响要比接受大量统计数据的影响更大,所以Taco Loco的故事或者客厅里一个篮球大的洞的想法所带来的影响可能会非常巨大。毫无疑问,这是个别推荐(“我在珍妮·克雷格身上减掉了40磅!”)如此有效的一个原因,即使也会附有统计方面的免责声明(“这些结果可能不适用于所有人”)。这也是为什么专业的说客被训练如何说服国会议员投票赞成某项法案的原因:他们受到警告,不要提供太多的统计数据,只需讲述某个人的情感故事。

From #

GDTR格式

Content #

Global Descriptor Table Register 用于定位 Global Descriptor Table. GDTR中的内容含义如下: base address在保护模式下是32位,长模式下是64位。

GDTR.base提供GDT的基地址,GDTR.limit提供GDT的表限。

GDT在内存中的位置

Content #

全局描述符表可在内存中任何地方。但在进入保护模式之后,处理器就必须按新的内存模式工作。所以,必须在进入保护模式之前定义GDT。

由于实模式只能访问1MB的内存,因此,GDT通常定义在1MB以下的内存范围中。进入保护模式后也可以换个位置重新定义GDT。

From #

恐惧与自尊心

Content #

常识表明,恐惧会阻止我们行动。在某些条件下对某些人而言,的确如此。“某些人”指的是谁?

莱文塔尔和他的同事发现,对自己评价很高的人最有可能在恐惧的时候立即采取行动。然而,对自己评价不高的人最不可能立即采取行动,但是(有趣的是)如果延迟一段时间,他们知道可以稍后采取行动,那么他们的行为就很像那些具有高度自尊心的被试。自尊心低的人可能难以应对威胁,这就解释了为什么唤起高恐惧的沟通会压垮他们,让他们觉得自己很想爬上床,用被子蒙住脑袋。他们当时可能更容易处理低度或中度的恐惧。但如果给他们时间,也就是说如果他们不需要立即采取行动的话,他们更有可能采取行动。

那么,假如你想让低自尊心的人戒烟或更安全地开车,你会如何激励他们呢?

如果你构建了一条包含特定的、乐观指导的信息,它会使他们更有可能相信自己可以面对恐惧并应对危险。事实上,莱文塔尔和他的同事们发现,包含有关如何、何时以及在何处采取行动的特定指令的恐惧诱发信息,比没有处理建议的一般警报更为有效。

例如,在一所大学校园里开展的一项敦促学生注射破伤风疫苗的活动被分为两种条件:(1)仅仅提供指导:何时何地提供服务,学生健康服务的位置,每个学生预留出某个方便时间的建议;(2)指导加高度恐惧的诉求:描述一下假如你自愿选择不打防护性破伤风针,可能发生在你身上的可怕事情。

指导本身提高了学生对破伤风疫苗的积极态度,并增加了他们声称要注射破伤风疫苗的意愿,但指导仍不足以让所有学生去行动。可以说,唤起恐惧是必要的武器。在那些害怕如果没有注射破伤风疫苗会发生什么情况的学生中,有28%的人接受了破伤风疫苗的注射,而那些没有接受具体指导或高度恐惧诉求的学生中,只有3%接受了注射。

同样,莱文塔尔发现让吸烟者害怕尼古丁的危险会增加他们戒烟的意愿。但是,除非这条信息附有戒烟建议,否则它不会改变吸烟者的行为。相反,当他们有吸烟的冲动但不担心健康风险时,为他们提供具体的指导是相对无效的。

恐惧唤起和具体指导相结合产生了最好的效果;四个月后,处于这种状态的学生吸烟量明显减少。

From #