在64位x86 CPU下,我们通常将数字加载到寄存器中,如下所示:
mov rdx, -1 // 48BAFFFFFFFFFFFFFFFF
...此指令采用旧版本NASM汇编方式的10个字节。
- 另一种方法是:**
xor rdx, rdx // 4831D2
dec rdx // 48FFCA
...此操作码仅占用6个字节。
- 编辑**:
正如Jens Björnhager所说(我已经测试过),xor edx, edx
操作码应该清除整个rdx寄存器:
xor edx, edx // 31D2
dec rdx // 48FFCA
...此操作码仅占用5个字节。
- 编辑:**
Alexey Frunze找到了另一个解决方案:
mov rdx, -1 // 48C7C2FFFFFFFF
...这条指令只需要7个字节。但是如何告诉汇编器使用更短的编码(不使用DB)?你可以提示NASM使用这种编码,如果你使用的是旧版本,它没有默认启用优化(代码大小),并且你没有手动使用nasm -Ox
。
mov rdx, dword -1
- 什么更快,什么更经济?**
3条答案
按热度按时间dauxcl2d1#
有一个比所有提到的都短:第一个月
它有一个讨厌的属性,对我所知道的所有架构都有一个虚假的依赖性,但它不应该被IMO忽略。有合法的理由使用它。例如,如果结果是不需要的,直到很久以后,它在一个循环中,否则将不适合四个16字节的块。此外,如果速度不是一个特定代码段的大问题,我们也可以不浪费宝贵的缓存空间。2它也可以用于对齐的原因,但是几乎可以肯定的是,填充到下一个更高的对齐会更快。
至于告诉编译器这一点,我没有线索。
w41d8nur2#
第一种要好得多。第一种根本没有依赖性。第二种依赖性是最差的一种--一条指令在开始之前需要紧挨在它前面的指令的最终结果。然而,如果你有一些其他的指令,你可以在
xor
和dec
之间滑动,这将消除依赖性,然后第二种选择可能胜出。第二个指令对
rdx
的值也有假依赖性,而第一个指令没有。有些CPU可能足够聪明,能够识别这种假依赖性,并且在rdx
的值已知之前不会停止第一个指令(因为无论如何输出都是零)。有些x86 CPU确实有忽略某些假依赖性的逻辑。比较代码的字节数不是很有用,在大多数实际情况下,代码占用的字节数不太可能非常大。
kx7yvsdv3#
mov rdx, -1
还有一种替代的7字节编码:48C7C2FFFFFFFF.您可以尝试在代码中将指令编写为
mov rdx, dword -1
,以帮助编译器/汇编器使用这种较短的编码。