Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly INVD指令有什么用途?_Assembly_X86_Cpu Cache - Fatal编程技术网

Assembly INVD指令有什么用途?

Assembly INVD指令有什么用途?,assembly,x86,cpu-cache,Assembly,X86,Cpu Cache,显然,x86在不将内容写回内存的情况下使缓存层次结构无效 我很好奇,这样的指示有什么用?考虑到人们对不同缓存级别中的数据几乎没有控制权,对异步刷新的数据更没有控制权,这似乎只不过是一种确保您不知道内存中保存了哪些数据的方法。好问题 像invd这样的钝动作指令的一个用例是专门的或非常早期的引导代码,例如当RAM的存在或不存在尚未被验证时。由于我们可能不知道RAM是否存在,它的大小,甚至不知道它的特定部分是否正常工作,或者我们可能不想依赖它,因此CPU有时将自己缓存的一部分编程为RAM并将其作为RA

显然,x86在不将内容写回内存的情况下使缓存层次结构无效

我很好奇,这样的指示有什么用?考虑到人们对不同缓存级别中的数据几乎没有控制权,对异步刷新的数据更没有控制权,这似乎只不过是一种确保您不知道内存中保存了哪些数据的方法。

好问题

invd
这样的钝动作指令的一个用例是专门的或非常早期的引导代码,例如当RAM的存在或不存在尚未被验证时。由于我们可能不知道RAM是否存在,它的大小,甚至不知道它的特定部分是否正常工作,或者我们可能不想依赖它,因此CPU有时将自己缓存的一部分编程为RAM并将其作为RAM使用是很有用的。这称为缓存为RAM(汽车)。在设置CAR、使用CAR和拆除CAR模式的过程中,内核必须确保从未将任何内容从缓存写入内存

缓存为RAM 上车 要设置CAR,CPU必须设置为无填充缓存模式,并且必须将用于CAR的内存范围指定为写回。这可以通过以下步骤完成:

  • 设置一个MTRR(内存类型范围寄存器)以将内存块指定为WB(写回)
  • invd
    整个缓存,防止任何缓存写操作被写出并导致混乱
  • 将缓存模式设置为正常缓存模式(
    cr0.CD=0
  • 在正常缓存模式下,“触摸”要用作汽车的内存范围的所有缓存线,读取它,从而用它填充缓存。只能在正常缓存模式下填充缓存线
  • 将缓存模式设置为无填充缓存模式(
    cr0.CD=1
  • 使用汽车 设置CAR的动机是,一旦设置,CAR区域内的所有访问(读/写)都将命中缓存,而不会命中RAM,但缓存的内容将是可寻址的,其行为与RAM一样。因此,不再编写只使用寄存器的汇编代码,现在可以使用普通的C代码,前提是它访问的堆栈和局部/全局变量限制在CAR区域内

    退出车 当CAR退出时,这个“伪RAM”中产生的所有内存写入突然从缓存中跳出,并在RAM中的同一地址丢弃任何实际内容,这将是一件坏事。因此,当CAR退出时,再次使用
    invd
    完全删除CAR区域的内容,然后设置正常缓存模式

    英特尔80486手册 英特尔暗示高速缓存是内存在网络中的使用。英特尔80486是第一个引入
    invd
    指令的CPU。第12.2节改为:

    12.2内部缓存的操作 软件控制高速缓存的操作模式。可以启用缓存(重置初始化后的状态)、在存在有效缓存线时禁用缓存(缓存的行为类似于快速内部RAM的模式)或完全禁用缓存

    禁用缓存时必须遵循预防措施。每当CD设置为1时,如果副本仍在缓存中,i486处理器将不会读取外部内存。当NW设置为1时,如果数据在缓存中,i486处理器将不会写入外部内存。这意味着陈旧的数据可以在i486cpu缓存中生成。如果NW后来设置为0,或者缓存线后来由于缓存未命中而被覆盖,则此陈旧数据将不会写入外部内存。通常,禁用时应刷新缓存

    在设置CD和NW时,通过使用测试寄存器加载数据,可以冻结缓存中的数据。这对于为时间关键中断代码和数据提供有保证的缓存命中非常有用

    请注意,所有段应以16字节边界开始,以允许程序对齐缓存线中的代码/数据

    用法示例 coreboot有一个描述上述过程的。幻灯片21使用了
    invd
    指令

    AMD称之为缓存,作为通用存储

    其他用途
    在某些情况下,由于DMA(直接内存访问)硬件导致缓存不一致,
    invd
    也可能有用。

    要详细说明iwillnotexistidnotexists对CAR的回答:

    我认为它实际上是如何做到的

  • 设置WB MTRR(而不是PAT,因为必须禁用寻呼;PAT在PMH中运行,MTRR在加载/存储缓冲区或L1d中运行)以覆盖所需的车辆空间。我认为汽车范围需要正确地映射到SAD中,并且需要有一个后备存储器——在这种情况下,使用映射到SPI闪存的地址范围以及代码实际所在的地址范围是有意义的,然后您只需要将其读入缓存。您可以使用此范围UC并将其读取到缓存中,然后将其写入映射到其他地方的WB范围–可能不需要物理设备备份,但SAD中确实需要映射,否则您可能会在其到达L3时或仅在需要访问备份存储时获得MCA。实际上,在切换到CAR模式之前,您首先需要从该地址范围引入有效行(除非您可以对该范围执行无RFO写入,这样它就不需要引入任何行,
    rep stos
    应该使用类似ItoM的无RFO协议,即它只发送一个invalidate,而不发送RFO),所以我认为它需要映射到一个实际的设备,比如SPI flash,因为当从一个SAD中有映射但没有接收设备的设备读取数据时,当它到达IIO或IMC时,你会得到一个