在x86汇编中将单个存储单元设置为零或常量的最快方法?

Tyl*_*den 2 x86 assembly x86-64 zero micro-optimization

在x86中将单个存储单元设置为零的最快方法是什么?通常,我这样做的方式是这样的:

C745D800000000  MOV [ebp-28], 0
Run Code Online (Sandbox Code Playgroud)

如您所见,由于它使用所有4个字节作为常量,因此它具有相当大的块编码。使用普通寄存器,我可以使用MVZE更紧凑的寄存器,但MVZE不能用于内存。

我在想也许先清除一个寄存器,然后MOV将寄存器的值存入内存。这样,它将是两条指令,但是总共只有5个字节,而不是上面的一个7字节指令。遵循“如果更短,通常更快”的规则,这可能是更可取的。

Dan*_*zar 5

不幸的是,您在这里写的是将存储单元“直接”清零的唯一方法。当然,对寄存器进行XOR运算,然后将其移至某个内存位置也可以,但是我不知道这样做是否会更快。

如果您碰巧有一个值为零的寄存器并且您确定该寄存器,则一定要使用它。否则,请坚持使用mov [ebp-28], 0。请记住,mem, imm已知操作数是最慢的操作数之一:如果您分析代码并发现这是一个瓶颈,请尝试在函数的开头(或其他任何地方)将寄存器初始化为零,然后在整个过程中使用它代码,作为一种预定义的常量。

  • @Björn在x86-64上,`xor eax,eax` +`mov [r14d],rax`只有5个字节。(您不需要对64位寄存器rax进行XOR,因为对32位寄存器进行的所有操作都隐式清除了上半部分,并且它们的编码时间更短。)不过,这不一定比“更快”。 `mov mem,imm`。但是就像丹尼尔说的那样,如果您在同一函数中将值0用作其他用途,那将是显而易见的,巨大的胜利,尤其是因为在x86-64上,您实际上总是拥有空间寄存器。在x86-32上,这个决定要困难一些,因为您会放弃一个有价值的寄存器为零寄存器。 (4认同)