为啥在进行 64 位操作时编译器会发生变化?

Posted

技术标签:

【中文标题】为啥在进行 64 位操作时编译器会发生变化?【英文标题】:Why the compiler changes movq to movd when doing 64bit operations?为什么在进行 64 位操作时编译器会发生变化? 【发布时间】:2015-08-05 23:32:15 【问题描述】:

我正在编写以下代码:

__asm__ volatile ("movq %%rax, %%mm1\n"
                  "movq %%rcx, %%mm2\n"
                  : : "a" (0xDEADBEEFDEADBEEF), "c" (0xBADFACE5BADFACE5));

在这种情况下,我将值从 rax 移动到 mm1,它们都是 64b 寄存器(将 qword 值从一个寄存器移动到另一个)。但是当我编译我的代码时,我看到:

mov  rax, 0xDEADBEEFDEADBEEF
mov  rcx, 0xBADFACE5BADFACE5
movd mm1, rax     <-------------- Why it is doing a dword operation ??
movd mm2, rcx     <-------------- Why it is doing a dword operation ?? 

我在 64 位模式下编译我的代码,我不确定它为什么将 64 位操作更改为 32 位。

【问题讨论】:

【参考方案1】:

来自thisbugzilla:

这样做是为了提供向后兼容性,因为 vmovq 不在原始 x86-64 规范中,并且较旧的汇编程序不支持它。 来自 binutils 中的 i386-opc.tbl:

这些确实不应该允许 Reg64(movq 是正确的助记符 在 Reg64/Mem64 和 RegXMM/RegMMX 之间进行复制,这是由 英特尔的规格)。 AMD 的规范已经存在了很长时间, 未能识别并指定 movd 为 32 位和 64 位 操作。

vmovd 确实不应该允许 64 位操作数(vmovq 是正确的 Reg64/Mem64 和 RegXMM 之间复制的助记符,由 英特尔 AVX 规范)。为了避免 gcc x86 后端中的额外模板和 支持 AMD64 的汇编器,我们在 vmovd 上接受 64 位操作数,这样 我们可以为 SSE 和 AVX 指令使用一个模板。

【讨论】:

所以尽管在两个 64b 寄存器之间有一个“movd”,它仍然会做一个 64b 的 mov 吗? 当目标操作数是 64 位时,如果是 64 位,movd 将从寄存器中复制所有 64 位。否则,如果寄存器是 32 位,它将用零扩展它。这里有一个有用的参考:x86.renejeschke.de/html/file_module_x86_id_181.html 所以是的,movd 会在适当的时候做一个 64b 的 mov。 @mareiou:这个答案不是很清楚。 GCC 不会修改您的指令。它仍然是movq 的reg,xmm 版本,但是您的反汇编程序在反汇编时使用的是AMD 约定。 (也许 AMD 想要区分 movq xmm, xmm/m64 形式(MMX 整个寄存器加载/复制操作码的 XMM 版本)和 movq xmm, r64/m64 形式(movd 带有 REX.W 前缀,仅限 64 位模式)felixcloutier.com/x86/movd:movq与felixcloutier.com/x86/movq. 如果您考虑一下 AMD64 存在之前的情况,这是有道理的,只有 movd 可以在向量和通用整数寄存器之间移动。 (SSE2 在 AMD64 之前就存在,所以 movd %eax, %xmm0 确实存在)。在 AMD64 之前,movq 助记符仅适用于访问向量 reg(以及可选的内存)而不是 GP 整数的操作码。所以英特尔的设计更有意义,但需要汇编器查看操作数来确定是哪个操作码。但这并不是什么新鲜事。【参考方案2】:

尽管有链接的错误报告,但我无法重现。

我测试了 gcc 4.4 到 4.9,有各种优化级别:

x86_64-linux-gnu-gcc-$VERSION $OPTIMIZATION -S -o x.s x.c

在所有情况下,生成的 x.s 文件仅包含 movq,而不包含 movd

【讨论】:

这并不能真正回答问题。无论如何,从问题中并不清楚,但他正在谈论他在反汇编编译器生成的对象或可执行文件后看到的内容。

以上是关于为啥在进行 64 位操作时编译器会发生变化?的主要内容,如果未能解决你的问题,请参考以下文章

PHP x64 仍然返回错误的文件大小

在vs2017上重新建立一个project和.c文件是啥意思?

(IStool)64位软件安装在32位操作系统时给出提示

在64位操作系统上,下面程序返回啥结构

为啥 64 位 VC++ 编译器在函数调用后添加 nop 指令?

为啥我的手提安装不了microsoft silverlight的更新(KB2617986)。错误代码643 我的win7 64位操作系统