Intel x86_64汇编:将32位整数转换为64位int的好方法是什么?

for*_*teu 2 int assembly x86-64 type-conversion

正如标题所说.我这样做的方法:

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

有没有更优雅/更好/更快的方式来做到这一点?

Pet*_*des 6

TL; DR : movsxd,或者对于eax特例,cdqe.


就像我在之前的一个问题中解释的那样,您可以通过查看编译器输出来自己回答这些问题.这是真的容易编写登录延伸的整数的函数,然后去查查它在手册中使用的指令:

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

    movsxd   rax, edi
    ret
Run Code Online (Sandbox Code Playgroud)

来自Godbolt编译器资源管理器上的clang -O3.


然后您查找movsxd指令集的参考,就大功告成了.(这是英特尔PDF(标签维基中的链接)的转换,其中包含每个指令的摘要行的目录.文本搜索通常会找到您需要的内容.)


rax有一个特例,叫做cdqe.8086 movsx直到386才有,只是al - > ax cbw.


这是和其他只有斧头的东西是英特尔xchg ax, reg在8086中为单字节编码花费了8个操作码的原因.为了在未来的指令集扩展中使用,AMD可能应该为AMD64回收这些操作,因为AMD64是第一个(并且可能只有很长一段时间)有机会打破与8086操作码或386的32位模式机器代码的向后兼容性.

这就是单字节NOP(90)编码的来源:xchg eax,eax被认为是一种有效执行的特殊情况(不是免费的,但比例如便宜mov eax,eax).在64位模式下,它不会将eax零扩展到rax中.(英特尔文档nop作为单独的指令(以及长NOP编码),并没有在条目中提及此特殊情况行为xchg)