当前位置: 首页 > 知识库问答 >
问题:

指令获取访问传递锁定指令

姜正初
2023-03-14

英特尔软件开发人员手册提到“指令获取和页表访问可以通过锁定指令”。这是什么意思,为什么重要?

有一篇文章说,许多Windows函数以MOV EDI,EDI指令开始,因为它对于安全的代码挂钩很有用:它可以原子地替换为两字节的相对跳转。但是如果对内存的提取访问可以“传递锁定的指令”,那么下面的情况是否可能发生呢?

    null

这样的事情也有可能发生吗?

  • CPU0原子地用相对跳转替换MOV EDI,EDI指令
  • 因为指令提取可以“传递锁定的指令”,所以从指令提取的上下文中可以认为指令的替换是非原子的,所以CPU1从陈旧指令和新指令中提取1个字节

摘自Intel64和IA-32体系结构软件开发人员手册,第3卷:“系统编程指南”

共有1个答案

谷星文
2023-03-14

关于第二个场景--“传递一个锁定的指令”并不意味着它破坏了原子性。如果存储以原子方式写入这2个指令字节,那么在任何时候都不能只看到其中的一个(存储只会在完整的缓存线上操作--请注意,如果这2个字节被分割到2行上,它就不是原子的了)。它的意思是,为了尝试同步而放置的任何锁指令都不会阻止代码提取,所以就内存排序而言,它可以发生在代码提取之前或之后。

现在,关于第一个场景和一般的问题,请注意,在您的描述中没有锁定。您描述的情况是完全有效的,即使它是数据读取而不是代码读取-除了您自己强制执行的顺序之外,两个内核之间没有固有的顺序。为了执行这样的顺序,您可以开始使用屏障和信号量或任何其他方法,最终归结为一些锁阻塞CPU1,直到CPU0发出写操作完成的信号。

在这种情况下,数据读取将被锁阻塞,但是年轻的代码读取实际上可以获取旧数据,尽管您试图保护旧数据。然而,x86内核通常实现一种机制,称为SMC(自修改代码)flush--来自CPU0的存储窥探CPU1中的指令缓存,检测那里的陈旧代码,并且由于它不能知道这些代码在管道中的确切位置,或者已经产生了什么影响(就我们所知,那里可能有一条halt指令,或者更糟)--它只会刷新整个管道。确切的细节可能在不同的产品之间有所不同,但概念是非常古老的。

页面遍历的情况稍微复杂一点,但这里也有一种机制可以检测使用过程中的大多数修改情况--看看“TLB shootdown”。注意,在某些情况下,SMC和TLB在运行过程中的修改都是完全有效的,而且是有目的的(SMC经常用于JITting,页面遍历是一种在进程之间传递数据而不必复制数据的廉价方式)。

 类似资料:
  • 问题内容: 我目前有一个AngularJS ,它基本上是通过调用异步获取的,然后将获取的数据链接到某个范围变量。 代码的恢复版本: 然后,我有一个自定义,它通过一个元素接收那些相同的作用域变量。 代码的恢复版本: 的恢复版本: 问题是,由于是异步的,因此该指令已被严重初始化(例如:未定义)。 尽管找到了一些似乎可以解决此问题的解决方案,但我找不到能为我解决该问题的任何方法。即,我试图观察变量,仅在

  • 问题内容: 这不是一件很难的事,但我无法弄清楚如何做到最好。 我有一个父指令,像这样: 和一个子指令: 如何从子指令轻松访问父指令的和属性?在我的链接函数中,我可以访问父级作用域-我应该用来观察这些属性吗? 放在一起,我想拥有的是: 这个想法是默认情况下显示一组字段。如果单击,它们将成为输入并可进行编辑。 问题答案: 从这篇SO帖子中汲取灵感,我在这个笨拙的人中有一个可行的解决方案。 我不得不改变

  • 我感到困惑的是,在向授权服务器发送授权请求时,似乎没有标准的方法来指定访问令牌的受众。 OAuth2将访问令牌指定为不透明字符串;规范中只有一处提到了“观众”,即访问令牌可以是“观众限制的”。许多最近的授权服务器实现似乎产生了JWT访问令牌,JWT指定了受众(aud)声明。 据我所知:-Auth0使用“audience”参数-Connect2id使用“resource”参数-Identity Se

  • 问题内容: 我的AngularJS模板包含一些自定义HTML语法,例如: 我创建了一个指令来处理它: 一切正常,但表达式始终返回,即使在执行时从Google Chrome浏览器的JavaScript控制台可见该属性,该表达式始终返回。 有什么建议吗? 更新:Artem提供了一种解决方案。它包括这样做: AngularJS + stackoverflow =幸福 问题答案: 请参阅指令文档中的属性一

  • 我的AngularJS模板包含一些自定义HTML语法,例如: AngularJS+stackoverflow=bliss

  • 问题内容: 这里有角的新手。我试图找出将对象传递给指令时出了什么问题。 这是我的指令: 这是我调用指令的模板: 是一组对象。 当我运行此,日志,而日志罚款的范围,甚至有一个与所有的数据,我找孩子。 我不确定我在这里做错了什么,因为这种确切的方法以前对我有用。 编辑: 我已经用所有必需的代码创建了一个插件:http ://plnkr.co/edit/uJCxrG 如您所见,该作用域在范围中可用,但我