代码之家  ›  专栏  ›  技术社区  ›  loxxy

在微控制器中将数据从存储器移动到存储器

  •  4
  • loxxy  · 技术社区  · 14 年前

    为什么我们不能直接将数据从一个内存位置移到另一个内存位置呢。

    我并不是真的在寻找移动数据的解决方案(例如,使用movs n all),但实际上是这个异常的原因。

    5 回复  |  直到 14 年前
        1
  •  2
  •   Carl Norum    14 年前

    大多数CPU不允许内存到内存的移动。通常情况下,CPU一次只能访问一个内存位置,这意味着您需要一个临时点来存储移动时的值(通常是一个通用寄存器)。如果你想一想,直接从一个内存位置移动到另一个内存位置将需要CPU能够同时访问RAM中的两个不同的位置——这意味着至少有两个满内存控制器,即使这样,它们“玩得好”到可以访问同一个RAM的机会也相当糟糕。芯片设计人员可能已经掌握了一些技巧,允许从一个RAM芯片直接复制到另一个RAM芯片,但这将是一种非常特殊的应用程序类型的功能,只会增加成本和复杂性,以解决一个非常罕见的问题。

    你可以使用一些特殊的DMA硬件,让你的程序看起来像是没有临时存储的内存在移动,至少从CPU的角度来看是这样。

        2
  •  5
  •   Michael Williamson    14 年前

    那怎么办 MOVS ? 它将esi寻址的8/16/32位值移动到edi寻址的位置。

        3
  •  5
  •   Ira Baxter    14 年前

    基本原因是大多数指令集允许一个寄存器操作数和一个内存操作数,而坚持这种格式可以使指令解码器的设计更容易。它还使CPU内的执行引擎更容易,因为指令通常可以只对一个内存位置发出内存操作,最多只能对一个寄存器块进行读写。

    要直接执行内存对内存指令,需要指定两个内存位置。如果给定一个寄存器/内存指令格式,这是很尴尬的。考虑到机器的性能,仅仅为此修改指令格式是没有道理的。

    知道 解码 问题。

    执行 问题有点难,但人们有很多晶体管。组织从一个寄存器间接读取,通过另一个寄存器间接写入,两者都递增在硅中是很尴尬的,但这只会消耗一些晶体管。 现在你可以有一个指令,从一个内存移动到另一个内存,就像你要求的那样。 在X86的另一个招贴画中,有一些指令(MOVB,MOVW,MOVS,…)正是这样做的,一个内存字节/字/。。。一次。

    移动 因为CPU可以产生高带宽的读写操作,所以内存的容量是理想的。x86使用MOV上的REP(repeat)前缀来移动更大的块。

    但是,如果一个指令可以做到这一点,您就有一个问题,即执行可能需要很长时间(移动1Gb需要多长时间?-->数百万个时钟周期!)这会破坏CPU的中断响应率。

    x86通过允许REP MOV-被中断来解决这个问题,PC被设置回指令的开头。通过在移动期间适当地更新寄存器,您可以中断并重新启动REP MOV指令,该指令具有快速块移动和高中断响应率。管里有更多的晶体管。

    copy: MOV   EAX,[ESI]
          ADD   ESI,4
          MOV   [EDI],EAX
          ADD   EDI,4
          DEC   ECX
          JNE   copy
    

    它和REP MOV做的基本相同-。现代的cpu(x86等)基本上都是这样执行的 快速(超标量等)的总线是一样的利用自定义移动指令,但现在你不需要所有浪费晶体管(或相应的热量)。

        4
  •  2
  •   Karl Bielefeldt    14 年前

    在CPU和RAM之间有一组地址线、一组数据线和一些控制线。如果RAM中没有第二组地址线和一大堆复杂的逻辑,就无法直接从一个内存移动到另一个内存。因此,我们必须将其临时存储在寄存器中。

    您可以使一条指令一起进行加载和存储,对程序员来说就像一条指令,但还有其他一些考虑因素,如指令大小、有效地址计算逻辑的不重复性、流水线等,使它更简单。

        5
  •  1
  •   Paul Nathan    14 年前

    内存机器通常比负载存储机器慢。这是RISC研究人员在1980年左右推导/发现/发明的。因此,较旧的体系结构(VAX/OS360)倾向于采用内存体系结构;较新的机器则采用负载存储。

    另一个有趣的变体是堆栈机器;它们似乎总是作为少数存在。