如标题所述。
我的方法是:
; 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
的条目中未提及这种特殊情况的行为)