大多数汇编程序使用4个通用寄存器eax
、ebx
、ecx
和edx
,但我发现很多时候我需要使用超过4个寄存器才能轻松完成任务,而不必从堆栈中频繁地push
和pop
。由于我的程序没有使用FPU或MMX寄存器进行浮点运算或其“预期用途”,因此在程序中使用这些额外的寄存器是否被认为是可接受的呢?
例如,使用mm0
作为循环增量计数器,释放ecx
寄存器来执行其他任务。
大多数汇编程序使用4个通用寄存器eax
、ebx
、ecx
和edx
,但我发现很多时候我需要使用超过4个寄存器才能轻松完成任务,而不必从堆栈中频繁地push
和pop
。由于我的程序没有使用FPU或MMX寄存器进行浮点运算或其“预期用途”,因此在程序中使用这些额外的寄存器是否被认为是可接受的呢?
例如,使用mm0
作为循环增量计数器,释放ecx
寄存器来执行其他任务。
eax
, ebx
, ecx
, edx
, esi
, edi
和 ebp
。那是七个。或者这还不够吗?ecx
*。基于MMX寄存器变为零的分支比dec ecx / jnz
要低效得多,并且在那一点上需要一个备用整数寄存器。但是,如果您想使用XMM寄存器和paddd
/ movd
存储填充数组,则可以使用它们来填充递增序列。或者更好的是,使用paddd
/ movdqu
存储一次填充4个元素。但是这样做只是以向量寄存器的正常方式向量化循环。 - Peter Cordesemms
,这将花费与XMM寄存器的SSE2相比的周期。 - Peter Cordes你需要多经常使用一个寄存器的全部32位?对于像小计数器之类的东西,可以自由地使用通用寄存器的字节大小的四分之一:AH/AL、BH/BL、CH/CL、DH/DL。通过一些位运算技巧,你也可以将通用寄存器的上16位用作字长变量的中间存储。
在实模式下(即DOS下),你还可以使用段寄存器ES、FS和GS作为中间值存储。但在受保护模式的操作系统(Windows、Linux、*nix)下,代码会崩溃。
inc ah
和inc al
彼此存在虚假依赖关系。请参见为什么GCC不使用部分寄存器?。即使在英特尔上(自Haswell或更高版本以来),写入AL实际上是合并到RAX中,这意味着mov al,6
不是破坏依赖性,而mov eax,6
是。(它不会强制合并单独重命名的AH,因此至少不会耦合这些dep链) - Peter Cordes当然,还有SI和DI,而在x64上,您还有额外的寄存器,但您可以将FP寄存器用于任何您想要的东西。