如何将 XMM 寄存器中的数字存储到 asm 循环中的 char 数组中 -
Posted
技术标签:
【中文标题】如何将 XMM 寄存器中的数字存储到 asm 循环中的 char 数组中 -【英文标题】:How to store numbers from a XMM register into a char array within an asm loop - 【发布时间】:2014-03-28 17:51:07 【问题描述】:我有一个 xmm 寄存器,其中包含四个 32 位数字。
XMM4 = 00000035000000350000003500000035
我有一个循环反复计算这些数字,然后我需要以某种方式将它们存储在一个数组中。如何在循环的每次迭代中使用 asm 存储 XMM 寄存器中的每个单独的数字?
编辑:
我尝试在我的 __asm 块之外创建一个 char 数组,如下所示:char numbers[20];
然后我尝试使用movdqa [numbers], xmm4
将我的注册值移入其中。这适用于循环的第一次迭代,但我不知道如何在顺序迭代中增加数组的索引。
Edit2:这是我的代码
__m128i stuff = _mm_setr_epi32 ( 87, 137, 202, 222 );
__m128i zeros = _mm_setr_epi32 ( 0x0, 0x0, 0x0, 0x0 );
__m128i fives = _mm_setr_epi32 ( 0x5, 0x5, 0x5, 0x5 );
__m128i fortyEights = _mm_setr_epi32 ( 0x30, 0x30,0x30, 0x30 );
__m128i magicNumber = _mm_setr_epi32 ( 0x66666667, 0x66666667, 0x66666667, 0x66666667 );
__asm
movdqa xmm0, stuff //Move data into xmm0
movdqa xmm1, magicNumber //Move magic numbers into xmm1
movdqa xmm2, xmm0 //Copy data into xmm2
vpcmpeqb xmm2, xmm0, xmm2 //Compare data against zeros
je bail //if data is all zeros then bail
nextdigit: pmulhw xmm2, xmm1 //Multiply data in xmm2 by the magic numbers in xmm1
psrad xmm2, 2 //Divide [wip]data by 4
movdqa xmm3, fives //Copy the fives into xmm3
pmullw xmm3, xmm2 //Multiply [wip]data in xmm2 by the fives in xmm3
paddd xmm3, xmm3 //Multiply the [wip]data by 2
movdqa xmm4, xmm0 //Copy the original into xmm4
psubd xmm4, xmm3 //Subtract the [wip]data from the original data
paddd xmm4, fortyEights //Add 48 to the [wip]data in xmm4 in order to get the ascii value
// HERE IS WHERE I WANT TO SAVE THE VALUES TO AN ARRAY
comiss xmm0, zeros
jne nextdigit
bail:
mov eax, 0
【问题讨论】:
向我们展示您的代码,您将获得帮助。 如果您在 C++ 中执行此操作,为什么要使用内部函数而不是内联汇编? @Mysticial: ITYM“为什么不使用内在函数...”? 该死,来不及编辑我的评论。是的,这就是我的意思,“为什么不使用内在函数?” 我已经用代码编辑了我的帖子。 【参考方案1】:使用通用寄存器之一进行索引,例如:
movdqa [oword ptr numbers + edx], xmm4 //Store xmm4 to numbers array
add edx, 16 //Increment index
【讨论】:
嗨@GJ.,感谢您的回答。当我将您的代码段放入上面显示的代码中时 // HERE IS WHERE... 我得到的错误是“context”中 PTR 运算符的非法类型 @Ste Prescott:抱歉,在 C++ 中使用OWORD
PTR
感谢您的回复。但是,当我这样做时,寄存器值会附加到每个循环的数组末尾,并且我最终会在每个字符之间添加一堆“0”。理想情况下,我想要的是递增和索引,以便我控制填充数组中的哪些位置。知道怎么做吗?
@Ste Prescott:据我了解,您有 16 字节对齐的数组,每个成员都是 16 字节长或四个 32 位数字。因此,如果 edx
为 0,则您将寻址数组的第一个成员,如果您将 16 与 add edx, 16
指令添加到 edx
,而不是索引指向第二个成员,依此类推!【参考方案2】:
这段代码有很多错误。我不知道你甚至想做什么,但这些都是大问题:
您只想在 16B 寄存器的底部字节中存储一两个字符?为什么需要向量?pcmpeqb
生成 0 或 0xff 字节的掩码,并且不为 jcc
设置标志。 (为此使用 SSE4.1 PTEST
)。
comiss xmm0, zeros
对保存整数数据的 xmm0 的低 4 个字节进行 浮点 比较。 (ss
= 标量单精度)。我不确定当整数数据恰好是NaN
时会发生什么。与零比较是唯一有希望的比较。
您可以使用_mm_set1_epi32(0x66666667)
进行广播。
扔掉你当前的所有代码,重新开始整个事情的内在函数。查看https://***.com/tags/x86/info的一些资源
【讨论】:
以上是关于如何将 XMM 寄存器中的数字存储到 asm 循环中的 char 数组中 -的主要内容,如果未能解决你的问题,请参考以下文章