Assembly 一个变量应该在寄存器中存储多长时间?

Assembly 一个变量应该在寄存器中存储多长时间?,assembly,optimization,x86,Assembly,Optimization,X86,在汇编代码中,寄存器是存储和处理数据最强大的地方,但与主存相比,它的空间有限。因此,我认为确定何时将数据移动到寄存器以及何时将其移出对于优化汇编代码非常重要,特别是在需要大量使用寄存器的情况下 因此,在将数据移动到主存供以后使用(在寄存器中处理后)之前,数据应该存储在寄存器中多长时间?或者,当不再有寄存器可供我处理新数据时,我只是将它们放入内存中?(我个人认为这不合适:P) 考虑以下代码(第1个代码): 现在考虑另一个代码(第二代码); 在上面,我认为第二个代码很明显有优势,可以多保存一个寄存器

在汇编代码中,寄存器是存储和处理数据最强大的地方,但与主存相比,它的空间有限。因此,我认为确定何时将数据移动到寄存器以及何时将其移出对于优化汇编代码非常重要,特别是在需要大量使用寄存器的情况下

因此,在将数据移动到主存供以后使用(在寄存器中处理后)之前,数据应该存储在寄存器中多长时间?或者,当不再有寄存器可供我处理新数据时,我只是将它们放入内存中?(我个人认为这不合适:P)

考虑以下代码(第1个代码):

现在考虑另一个代码(第二代码); 在上面,我认为第二个代码很明显有优势,可以多保存一个寄存器用于37行汇编代码(除非这37行汇编代码不使用很多寄存器),但有时在这两种方法之间进行选择会非常混乱,例如,如果是10行代码而不是37行代码呢


总之,当确定将数据从寄存器移出时,是否有某种规则?

您完全是在向后看。当某些内容溢出到内存中时的规则实际上就像“寄存器用完时”一样简单

复杂的部分是决定重用哪个寄存器

一旦您决定了这一点,您就在代码中确定了两个关键点——该寄存器的最后一次用于旧用途,第一次用于新用途。溢出可能发生在这两者之间的任何一点,在这里,您要考虑处理器的特性,执行哪些需要内存访问的其他指令,依赖链在计算最终值时的长度——并最终得出执行溢出的最佳时间,以避免等待内存控制器的管道暂停

除此之外,还要考虑调用约定,例如哪些寄存器必须由被调用函数保留,哪些寄存器被视为暂存空间,在许多情况下,叶函数根本不需要对内存进行任何溢出


在某些体系结构上,处理器特性差异很大,以至于在对指令流进行排序时,优化所需的信息不可用。(x86就是一个很好的例子)。在这种情况下,CPU本身可能有一个无序的执行引擎,其中有大量的逻辑专门用于重新排序指令(或它们被拆分成的微操作),这种方式对于特定的微体系结构来说是最佳的。此执行时间优化还可以考虑分支预测统计信息,只有在收集了分析跟踪信息的情况下,提前编译才能做到这一点。

您真正想做的是在寄存器中计算/放置值,理想情况下,永远不要将值移到“很远”的内存(“溢出”)因此访问速度较慢

许多编译器处理这一问题的方法是首先假设每个计算值都在代码中某个点的寄存器中。这需要无限(好的,无限)数量的寄存器,这显然比机器拥有的要多,所以它不能真正工作。是的,对于真正的大型程序,在某个时间点,寄存器中可能有10000个值。(甚至更多!)

但是,如果您可以决定这些无界值中哪一个最不重要,您可以强制它们溢出/存储在内存中,现在包含值的寄存器就更少了。如果你洒得够多,你就可以把剩下的放进真正的寄存器

这是通过所谓的。其思想是构建一个图,其节点是代码中某个点的某个寄存器中的值,以及连接这些值必须同时存在的节点的弧;这些被称为“干涉弧”

着色算法所做的是用颜色(好的,寄存器编号)装饰节点。假设您的机器有8个寄存器,并且您希望在某个寄存器中包含变量X;图中有一个节点表示这一点

这有一个两阶段的过程来实现。第一阶段选择可以清晰着色的节点,这是因为节点的邻居少于寄存器,并且解决了节点的邻居多于寄存器的情况。第二阶段分配颜色/寄存器

  • 阶段1:重复直到图为空:选择一个邻居少于实际寄存器的节点;将其(及其弧)从图形中删除并推到堆栈上。如果没有选择余地,选择一个邻居太多的节点[通常最好选择邻居最多的节点],从图中删除,推到堆栈上[这样的节点可能会在第2阶段将其寄存器溢出到内存]

  • 阶段2:重复,直到堆栈为空:从堆栈中弹出一个节点,并将其及其弧添加回图形。如果可能,为该节点分配一个颜色/寄存器,该节点不是其相邻的任何颜色/寄存器;这是值将使用的实际寄存器。(此步骤有时会成功着色可能必须溢出的节点)如果无法拾取此类颜色/寄存器,则无法将此节点分配到寄存器,而不会溢出其中一个或其邻居;我们通过为该节点分配一个任意寄存器用于其计算,并在计算其相邻节点时在某处分配一个内存位置来保存其计算值来解决此问题

Viola,你给每一个值分配了一个寄存器号,实际上只溢出了几个寄存器

不,您不想手工完成这项工作,但是构建一个过程来完成这项工作很容易


你给了一个规则,说你不喜欢它。你能指出那个规则有什么不好的地方吗
MOV EBX,SomeAddressForLaterUse
;...-imagine 37 lines of assembly code here
MOV ESI,SomeAddress
MOV EDI,EBX
MOV ECX,SIZE_IN_BYTES
REP MOVSB
MOV EBX,SomeAddressForLaterUse
PUSH EBX
;...-imagine 37 lines of assembly code here
MOV ESI,SomeAddress
POP EDI
MOV ECX,SIZE_IN_BYTES
REP MOVSB