简体   繁体   English

在ml64中的xmm和通用寄存器之间移动四字?

[英]Move quadword between xmm and general-purpose register in ml64?

In a simple program written for Microsoft's x64 assembler, I want to move a 64-bit value between an SSE register (say xmm0) and a general-purpose register (say rcx), as in <Intel syntax in MASM>:在为 Microsoft 的 x64 汇编程序编写的简单程序中,我想在 SSE 寄存器(例如 xmm0)和通用寄存器(例如 rcx)之间移动 64 位值,如 <MASM 中的英特尔语法>:

mov xmm0, rcx
...
mov rcx, xmm0

These two lines generate the following error messages, respectively, from ml64.exe :这两行分别从ml64.exe生成以下错误消息:

  • error A2152: coprocessor register cannot be first operand错误 A2152:协处理器寄存器不能是第一个操作数
  • error A2070: invalid instruction operands错误 A2070:指令操作数无效

However, it is clearly possible to accomplish this simple task in x64.然而,在 x64 中完成这个简单的任务显然是可能的。 For example, the following is a functioning x64 program that I can assemble and run in GAS <AT&T syntax using GCC 4.8.2>:例如,以下是一个正常运行的 x64 程序,我可以使用 GCC 4.8.2> 在 GAS <AT&T 语法中组装和运行它:

.text
    .globl main
main:
    movl $1, %ecx
    movq %rcx, %xmm0
    movq %xmm0, %rax
    ret

As expected, the return value of this program is 1 and the objdump output for main() is:正如预期的那样,该程序的返回值为 1, main()objdump输出为:

1004010d0:   b9 01 00 00 00          mov    $0x1,%ecx
1004010d5:   66 48 0f 6e c1          movq   %rcx,%xmm0
1004010da:   66 48 0f 7e c0          movq   %xmm0,%rax
1004010df:   c3                      retq

So my question is, how can I accomplish this in MASM given that ml64.exe is producing the above errors?所以我的问题是,鉴于ml64.exe产生上述错误,我如何在 MASM 中完成此操作?

The MOV instruction cannot move data between a general-purpose register and an xmm register. MOV指令不能在通用寄存器和xmm寄存器之间移动数据。 The instruction you are looking for is MOVQ (like in the A&T syntax code you show), as defined in Intel's instruction set manuals .您正在寻找的指令是MOVQ (如您显示的 A&T 语法代码),如英特尔指令集手册中所定义。 (HTML extract here: https://www.felixcloutier.com/x86/movd:movq ) (此处的 HTML 摘录: https : //www.felixcloutier.com/x86/movd : movq

The fact that ML64 does not accept MOVQ is in disagreement with Intel's manuals, and therefore - in my view at least - a bug (or at least an inconsistency). ML64 不接受MOVQ的事实与英特尔的手册不一致,因此 - 至少在我看来 - 一个错误(或至少不一致)。

ML64 does seem to use MOVD in its place, even for 64-bit registers. ML64 似乎确实使用MOVD代替,即使对于 64 位寄存器也是如此。 You can verify this by disassembling the code it generates.您可以通过反汇编它生成的代码来验证这一点。


Note that there are two different movq instructions (not counting load and store forms as separate):请注意,有两种不同的movq指令(不将加载和存储形式单独计算):

  • One is movq xmm, xmm/m64 form, the MMX/SSE2 instruction that copies between vector registers or loads/stores.一种是movq xmm, xmm/m64形式,MMX/SSE2 指令在向量寄存器之间复制或加载/存储。 This existed in 32-bit mode with MMX (and SSE2), and the opcode always implies a 64-bit transfer (zero-extending to 128 with an XMM destination).这存在于带有 MMX(和 SSE2)的 32 位模式中,并且操作码总是暗示 64 位传输(零扩展到 128 与 XMM 目的地)。 ML64 uses movq for this form. ML64 对这种形式使用movq

  • The other is the 64-bit version of movd xmm, r/m32 that can move data between XMM or MMX registers and GP-integer registers like RCX, or memory.另一个是movd xmm, r/m32的 64 位版本,可以在 XMM 或 MMX 寄存器和 GP 整数寄存器(如 RCX 或内存)之间移动数据。 This form is new with x86-64 (which includes MMX and SSE2);这种形式是 x86-64(包括 MMX 和 SSE2)的新形式; the opcode is the same as movd , with a REX.W prefix for 64-bit operand-size.操作码与movd相同,64 位操作数大小带有 REX.W 前缀。 ML64 apparently always uses movd for this form, regardless of the actual operand-size. ML64显然始终使用movd这种形式,而不管实际的操作数大小的。

A 64-bit load or store between an XMM register and memory can use either opcode, but the first form is shorter, not needing a REX prefix. XMM 寄存器和内存之间的 64 位加载或存储可以使用任一操作码,但第一种形式更短,不需要 REX 前缀。

(AT&T syntax movq %rax, %rcx is just mov with a q operand-size suffix; in that case the q is not part of the true mnemonic.) (AT&T 语法movq %rax, %rcx只是带有q操作数大小后缀的mov ;在这种情况下, q不是真正助记符的一部分。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM