【问题标题】:Imul in 64-assembly64 组装中的 Imul
【发布时间】:2020-01-08 19:22:36
【问题描述】:

我有这个代码:

mov rax, 0x93f3ffc2fbc7a1ce
mov rbx, 0x5862d8a05a385cbe
imul eax, ebx

imul 如何用于 64 位汇编?溢出的aex会写在rax的前32位吗?

【问题讨论】:

标签: assembly x86-64


【解决方案1】:

你的代码assembles

0:  48 b8 ce a1 c7 fb c2    movabs rax,0x93f3ffc2fbc7a1ce
7:  ff f3 93
a:  48 bb be 5c 38 5a a0    movabs rbx,0x5862d8a05a385cbe
11: d8 62 58
14: 0f af c3                imul   eax,ebx

它使用0F AF 的操作码imul。该指令具有 32 位操作数大小,因此它只读取 EAX 和 EBX,并且只写入 EAX。这个implicitly zero-extends into RAX,将高32位归零。

imul 的 1 操作数形式不同,32x32 => 64 位全乘法的高半部分不会写入 EDX(或其他任何地方,如 RAX 的高半部分);它只是被丢弃或根本没有计算效率。见documentation; 2 操作数 imul reg, r/m32 就像 add reg, r/m32or reg, r/m32 - 它没有做任何特别奇怪的事情。

在这个 32 位乘法完全没有意义之前使用 mov rax, imm64mov eax,0xfbc7a1ce 将给出完全相同的结果。 (imul 不会破坏 RBX,所以你放入 RBX 的值的高 32 位仍然存在,如果你想稍后读取它。它对imul 指令没有影响。)

更好的是,imul eax, ebx, 0xfbc7a1ce 可以避免使用 mov

【讨论】:

  • 写入 32 位寄存器 (EAX)总是零扩展到完整的 64 位寄存器。 Why do x86-64 instructions on 32-bit registers zero the upper part of the full 64-bit register?。但是,是的,mov r64,imm64 提供 32 位操作数大小的 imul 完全没有意义。乘法结果不会被截断,它始终是 32 位乘法,只读取 32 位输入。 (或者你的意思是 32x32 => 来自硬件乘法器执行单元的 64 位乘法被截断为 32 位,因为这是 2 操作数形式,而不是 imul ebx?这是真的)
  • @PeterCordes 我的意思是后者。我忘记了零扩展:感谢您的更正。
  • 我已为您确定了答案。不要在答案中留下错误的信息,只需将其修正为最初应该说的内容即可。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多