你为什么使用位掩码?用一条 STTNI 指令检查所有这些事件,然后使用返回的索引来处理返回的事件(如果有)不是更好吗?
(编辑)让我尝试更有帮助......
(我假设您使用的是 8 位字符的空终止字符串。如果不是这种情况,请告诉我。)
我认为您最好将分隔符、换行符、引号和转义符放入单个寄存器(作为空终止字符串)并使用PCMPISTRI而不是 PCMPISTRM 使用每个值。对于您要指示的控制字:无符号字节、相等任意、正极性、最小。(很确定我没看错。)
然后,您可以使用 JA 同时检查是否命中了 4 个特殊字符中的任何一个或是否到达了字符串的末尾。如果是这样,请退出循环以处理它。如果没有,将 ECX 添加到 xmm2/m128 指针并跳回 PCMPISTRI。
处理“命中”的第一条代码指令是将 ECX 添加到 xmm2/m128 指针,然后依次处理每种可能性。我建议从最可能到最不可能订购它们。
因此,asm 最终应该看起来像:
XOR ECX, ECX
TAG1:
ADD EAX, ECX
PCMPISTRI XMM1, [EAX], 0x0 ; also writes ECX = index
JA TAG1
ADD EAX, ECX
CMP BYTE PTR[EAX], "delimiter"
JE "handle delimiter"
CMP BYTE PTR[EAX], "newline"
JE "handle newline"
CMP BYTE PTR[EAX], "quotation"
JE "handle quotation"
CMP BYTE PTR[EAX], "escape"
JE "handle escape"
CMP BYTE PTR[EAX], "end of string"
JE "handle end of string"
我会让你决定测试分隔符的最佳顺序是什么。:)
当我开发指令时,我曾经能够让编译器使用内在函数生成上面的 asm 代码。自从我完成了这些指令的工作以来已经有一段时间了,所以不确定普通编译器是否会做得很好。(听到你得到什么结果会很有趣。)
顺便说一句,指令的掩码版本确实有各种用途,它们只是不是查找第一个或最后一个东西的最佳选择,因为指令的“I”版本将为您计算偏移量。面具版本适用于计数或仅处理某些项目以及其他更奇特的事物。现在我正在使用它们来计算 DNA 字符串中的 A、CG 和 T。