如标题所述。
我的方法是:

; eax holds 32bit integer
sal rax, 32
sar rax, 32
;after operation int is converted (rax holds the same value on 64 bits)

有没有更优雅/更好/更快的方法呢?

最佳答案

TL; DR :movsxd,或者对于eax特殊情况cdqe

就像我在您的previous questions中解释的那样,您可以通过查看编译器输出来自己回答这些问题。编写一个对整数进行符号扩展的函数真的很容易,然后去查找手册中使用的指令:

#include <stdint.h>
int64_t sign_extend(int32_t a) { return a; }

    movsxd   rax, edi
    ret

clang -O3 on the Godbolt compiler explorer

然后,您在 movsxd 中查找instruction set reference,就完成了。 (这是Intel PDF(在x86标签Wiki中的链接)的转换,其中包含目录和每条指令的摘要行。其中的文本搜索通常会找到您所需要的。)

rax有一种特殊情况,称为 cdqe 。 8086直到386才有movsx,只有al-> ax cbw

这就是为什么其他仅用斧头的东西,就是为什么英特尔在8086年将8个操作码用于 xchg ax, reg 的单字节编码。AMD可以认为应该为AMD64回收这些操作码,以便在将来的指令集扩展中使用,因为AMD64是第一个(并且可能是)仅在很长一段时间内)有机会打破与8086操作码或386的32位模式机器码的向后兼容性。

这是单字节NOP(90)编码的来源:xchg eax,eax被认为是一种有效执行的特殊情况(不是免费的,但比mov eax,eax便宜)。在64位模式下,它不会将eax零扩展为rax。 (英特尔将 nop 记录为单独的指令(以及long-NOP编码),并且在 xchg 的条目中未提及这种特殊情况的行为)

07-24 09:44
查看更多