【问题标题】:Intel x86_64 Assembly: What is good way to convert 32bit integer to 64bit int?英特尔 x86_64 汇编:将 32 位整数转换为 64 位整数的好方法是什么?
【发布时间】:2016-06-12 18:01:52
【问题描述】:

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

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

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

【问题讨论】:

  • @PeterCodes 我认为您的答案是有效的答案。我想您可以将其升级为答案,然后可以接受。你会得到加分:)
  • 完全同意。 @Peter Cordes,感谢您在过去几天提供的所有帮助。这一切都是无价的。你知识渊博。
  • @JoeyRoosing:我之前没有时间写一个完整的答案。我决定不将其发布为 2 行答案。我希望其他人可能会花时间将我的评论写成一个很好的答案,所以我不必这样做。

标签: assembly int type-conversion x86-64


【解决方案1】:

TL;DRmovsxd,或者对于 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


然后在instruction set reference 中查找movsxd,就完成了。 (这是英特尔 PDF( 标签 wiki 中的链接)的转换,它有一个目录,每条指令都有一个摘要行。其中的文本搜索通常会找到您需要的内容。)


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


这就是为什么英特尔在 8086 中为 xchg ax, reg 的单字节编码花费 8 个操作码的原因。AMD 可以说应该为 AMD64 回收这些操作码,以用于未来的指令集扩展,因为 AMD64 是第一次(并且可能只有很长时间)打破与 8086 操作码或 386 的 32 位模式机器码向后兼容性的机会。

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

【讨论】:

  • @DavidC.Rankin:这在 x86 标签 wiki 中已存在数月了:P 如果您喜欢该链接,请查看其中的其他内容;在过去的一年里,我添加了一些好东西。
  • 好信息,我上次查看该页面可能已经一年了。当时它很有用,但我一直在寻找方便的快速参考。很高兴看到它现在出现在页面上。
  • @DavidC.Rankin:为了我自己的使用,我通常只打开英特尔的 pdf 版本。在一个好的 PDF 查看器中导航条目真的很快,因为它具有内置到 PDF 元数据中的目录。所以例如我可以在索引窗格中单击 ctrl-f movsx。效果很好,除了你必须记住所有的班次都在以sal开头的条目中……Felix Cloutier 的 HTML 版本把表格/图表弄得一团糟,而这些正是 PDF 真正适合矢量洗牌指令的地方,与内在函数指南相比。
猜你喜欢
  • 2019-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-06
  • 1970-01-01
  • 2018-08-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多