[英]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
生成以下错误消息:
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.