assembly 将小数载入64位x86寄存器

o8x7eapl  于 2022-12-27  发布在  其他
关注(0)|答案(3)|浏览(169)

在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
    • 什么更快,什么更经济?**
dauxcl2d

dauxcl2d1#

有一个比所有提到的都短:第一个月
它有一个讨厌的属性,对我所知道的所有架构都有一个虚假的依赖性,但它不应该被IMO忽略。有合法的理由使用它。例如,如果结果是不需要的,直到很久以后,它在一个循环中,否则将不适合四个16字节的块。此外,如果速度不是一个特定代码段的大问题,我们也可以不浪费宝贵的缓存空间。2它也可以用于对齐的原因,但是几乎可以肯定的是,填充到下一个更高的对齐会更快。
至于告诉编译器这一点,我没有线索。

w41d8nur

w41d8nur2#

第一种要好得多。第一种根本没有依赖性。第二种依赖性是最差的一种--一条指令在开始之前需要紧挨在它前面的指令的最终结果。然而,如果你有一些其他的指令,你可以在xordec之间滑动,这将消除依赖性,然后第二种选择可能胜出。
第二个指令对rdx的值也有假依赖性,而第一个指令没有。有些CPU可能足够聪明,能够识别这种假依赖性,并且在rdx的值已知之前不会停止第一个指令(因为无论如何输出都是零)。有些x86 CPU确实有忽略某些假依赖性的逻辑。
比较代码的字节数不是很有用,在大多数实际情况下,代码占用的字节数不太可能非常大。

kx7yvsdv

kx7yvsdv3#

mov rdx, -1还有一种替代的7字节编码:48C7C2FFFFFFFF.
您可以尝试在代码中将指令编写为mov rdx, dword -1,以帮助编译器/汇编器使用这种较短的编码。

相关问题