Assembly ASM x86_64 AVX:xmm和ymm寄存器差异

Assembly ASM x86_64 AVX:xmm和ymm寄存器差异,assembly,nasm,x86-64,avx,Assembly,Nasm,X86 64,Avx,xmm和ymm寄存器之间有什么区别? 我以为xmm代表SSE,而ymm代表AVX,但我写了一些代码: vmovups ymm1, [r9] vcvtss2si rcx, ymm1 它给了我: error: invalid combination of opcode and operands 这是关于线路的: vcvtss2si rcx, ymm1 于是我写道: vcvtss2si rcx, xmm1 它按预期工作。ymm1向量的第一个值转换为整数,现在位于

xmm
ymm
寄存器之间有什么区别? 我以为
xmm
代表SSE,而
ymm
代表AVX,但我写了一些代码:

vmovups     ymm1, [r9]      
vcvtss2si   rcx, ymm1
它给了我:

error: invalid combination of opcode and operands
这是关于线路的:

vcvtss2si   rcx, ymm1
于是我写道:

vcvtss2si   rcx, xmm1
它按预期工作。
ymm1
向量的第一个值转换为整数,现在位于
rcx

这是怎么回事
ymm1
xmm1
是相同的寄存器吗?

根据,在AVX中:

YMM
寄存器长度256位

XMM
寄存器的长度为128位,代表
YMM
寄存器中较低的128位

YMM
XMM
寄存器重叠,
XMM
包含在
YMM

图表来源:


xmm0
ymm0
的下半部分,就像
eax
rax
的下半部分一样

写入
xmm0
(使用VEX编码指令,而不是传统SSE)将
ymm0
的上行链路归零。传统SSE指令的上限字节没有归零,这就是为什么会出现错误

大多数AVX指令的大小为128位或256位。e、 g.
vaddps xmm0、xmm1、xmm2
vaddps ymm0、ymm1、ymm2
。(大多数整数指令的256位版本仅在AVX2中可用,而AVX仅提供128位版本。有几个例外,如AVX1中的
vptest ymm,ymm
,以及
vmovdqu
(如果将其计算为“整数”指令)

vmovd
vcvtss2si
vcvtsi2ss
这样的标量指令仅适用于XMM寄存器。读取YMM寄存器在逻辑上与读取XMM寄存器没有什么不同,但是写入低位元素(并且不修改其他元素,就像设计糟糕的
vcvtsi2ss
所做的那样)对于XMM和YMM来说是不同的,因为YMM版本会使上层通道不归零


但机器代码编码中不存在带ymm的标量,即使对于指令而言,它也非常有用,如
vpinsrd
/
vpextrd
(插入/提取标量)。

请注意,即使读取XMM寄存器并仅获取低标量元素在逻辑上与YMM相同,但对于实际实现而言,它也不相同。读取YMM寄存器意味着一条AVX-256指令,该指令必须将CPU转换出“已保存上限”状态(对于具有SSE/AVX转换/状态的英特尔CPU)


在任何情况下,
vcvtss2si-rax,ymm0
都是不可编码的,并且汇编器不会神奇地将其组装为
vcvtss2si-rax,xmm0
。如果你在用asm写作,你应该知道自己在做什么。(虽然有些汇编程序会为您优化
mov-rax,1
mov-eax,1
,所以让您不用编写
ymm
作为源寄存器就行了。但是让您编写
ymm
作为
vcvtsi2ss
的目标寄存器会改变其含义,因此为了保持一致性,最好这样做。)
xmm1
ymm1
(以及其他索引)之间的主要区别是前者的长度为128位,而后者为256位。因此
xmm1'和
ymm1`共享相同的内存?如果我想使用只使用前128位的指令,那么使用
xmm
ymm
并不重要?或者可能每个只使用前128位的指令都需要使用
xmm
?好的,所以我要处理内存中的256位数据:
vmovups-ymm1,[r9]
,然后我转换
xmm1
的第一个元素(不是
ymm1
),并将其保存在
rcx
vcvtsss2si-rcx中,xmm1
rcx
中,怎么可能是
ymm1
的第一个值?它不应该是
xmm1
中的“随机”数吗?如果
xmm1
ymm1
是独立的寄存器,为什么
ymm1
xmm1
的第一个元素是相同的?感谢链接。我现在明白我错了。您是对的,低128位对两个寄存器都是通用的。请忽略我以前的评论。@LeandroCaniglia:你可以(也应该)删除你不正确的评论
xmm0
ymm0
的下半部分,就像
eax
rax
的下半部分一样。(写入
xmm0
ymm0
的上车道归零)