将小数字加载到64位x86寄存器中

时间:2011-12-14 10:21:40

标签: optimization assembly x86-64

在64位x86 CPU下,我们通常将数字-1加载到寄存器中,如:

mov     rdx, -1  //  48BAFFFFFFFFFFFFFFFF

......这个操作码需要10个字节。

另一种方式是:

xor     rdx, rdx //  4831D2        
dec     rdx      //  48FFCA  

......这个操作码只需要6个字节。

修改

正如JensBjörnhager所说(我已经测试过)xor edx, edx操作码应该清除整个rdx寄存器:

xor     edx, edx //  31D2        
dec     rdx      //  48FFCA 

......这个操作码只需要5个字节。

修改

Alex找到另一个解决方案:

mov     rdx, -1  // 48C7C2FFFFFFFF

...此操作码只需7个字节。 但是如何告诉编译器使用更短的操作码(不使用DB)?

...

什么是更快,什么更经济?

3 个答案:

答案 0 :(得分:7)

比所有提及的更短:4883CAFF OR rdx,-1
它具有对我所知道的所有体系结构具有错误依赖性的令人讨厌的特性,但它不应该被提及IMO。有合理的理由使用它。例如,如果直到很久之后才需要结果,并且它处于循环中,否则它将不适合四个16字节块。此外,如果速度对于特定代码片段并不是一个大问题,那么也不要浪费宝贵的缓存空间。它也可以用于对齐原因,但是填充到下一个更高的对齐几乎肯定会更快。

至于告诉编译器这个,我还没有线索。

答案 1 :(得分:5)

第一个要好得多。第一个没有依赖关系。第二种具有最差的依赖性之一 - 指令在它开始之前需要紧接在它之前的指令的最终结果。但是,如果您有其他指示可以在xordec之间滑动,那么这将消除依赖关系,然后第二个选项可能会胜出。

第二个也对rdx的值有假依赖,而第一个则没有。某些CPU可能足够聪明以识别这种错误依赖性,并且在rdx的值已知之前不会停止第一条指令(因为输出为零,无论如何)。一些x86 CPU确实有逻辑来忽略一些错误的依赖。

比较代码字节数并不是很有用。在大多数现实条件下,代码占用的字节数非常大,这是非常不可能的。

答案 2 :(得分:3)

还有一个替代的7字节编码mov rdx, -1:48C7C2FFFFFFFF。

您可以尝试在代码中将指令写为mov rdx, dword -1,以帮助编译器/汇编器使用这种更短的编码。