内在函数示例 - 这里发生了什么(包括完整代码)?

时间:2013-10-19 15:37:49

标签: c++ assembly intel sse intrinsics

我从以下代码中找到了以下代码:

http://msdn.microsoft.com/en-us/library/bb513993(v=vs.90).aspx

我试图准确理解代码正在做什么然后修补并满足我的需求。我很感兴趣使用intrincs来快速查找字符串中的空格字符,我认为这些字符串内在函数可以帮助我。

我真的不理解printf语句中提供的“评论”,为什么预期的结果是作者所说的?

(您应该可以复制并粘贴以下内容并立即运行)

#include <stdio.h>
#include <nmmintrin.h>
#include <iostream>

using namespace std;

int main ()
{
    __m128i a, b;


    const int mode = _SIDD_UWORD_OPS | _SIDD_CMP_EQUAL_EACH | _SIDD_LEAST_SIGNIFICANT;
    //      _SIDD_UWORD_OPS         a and b contain strings of unsigned 16-bit characters.  
    //      _SIDD_CMP_EQUAL_EACH    Find if equal each mode: This implements the string equality algorithm.
    //      _SIDD_LEAST_SIGNIFICANT sets the same bit as _SIDD_BIT_MASK


    a.m128i_u16[7] = 0xFFFF;
    a.m128i_u16[6] = 0xFFFF;
    a.m128i_u16[5] = 0xFFFF;
    a.m128i_u16[4] = 0xFFFF;
    a.m128i_u16[3] = 0xFFFF;
    a.m128i_u16[2] = 0xFFFF;
    a.m128i_u16[1] = 0xFFFF;
    a.m128i_u16[0] = 0xFFFF;

    b.m128i_u16[7] = 0x0001;
    b.m128i_u16[6] = 0x0001;
    b.m128i_u16[5] = 0x0001;
    b.m128i_u16[4] = 0x0001;
    b.m128i_u16[3] = 0x0001;
    b.m128i_u16[2] = 0x0001;
    b.m128i_u16[1] = 0x0001;
    b.m128i_u16[0] = 0x0001;

    int returnValue = _mm_cmpistra(a, b, mode);
    printf_s("_mm_cmpistra return value should be 1: %i\n", returnValue);

    b.m128i_u16[4] = 0x0000;
    returnValue = _mm_cmpistra(a, b, mode);
    printf_s("_mm_cmpistra return value should be 0: %i\n", returnValue);

    b.m128i_u16[5] = 0xFFFF;
    returnValue = _mm_cmpistrc(a, b, mode);
    printf_s("_mm_cmpistrc return value should be 0: %i\n", returnValue);

    b.m128i_u16[4] = 0x0001;
    returnValue = _mm_cmpistrc(a, b, mode);
    printf_s("_mm_cmpistrc return value should be 1: %i\n", returnValue);

    returnValue = _mm_cmpistri(a, b, mode);
    printf_s("_mm_cmpistri return value should be 5: %i\n", returnValue);

    b.m128i_u16[0] = 0xFFFF;
    __m128i fullResult = _mm_cmpistrm(a, b, mode);
    printf_s("_mm_cmpistrm return value: 0x%016I64x 0x%016I64x\n",
                fullResult.m128i_u64[1], fullResult.m128i_u64[0]);

    returnValue = _mm_cmpistro(a, b, mode);
    printf_s("_mm_cmpistro return value should be 1: %i\n", returnValue);

    returnValue = _mm_cmpistrs(a, b, mode);
    printf_s("_mm_cmpistrs return value should be 0: %i\n", returnValue);

    a.m128i_u16[7] = 0x0000;
    returnValue = _mm_cmpistrs(a, b, mode);
    printf_s("_mm_cmpistrs return value should be 1: %i\n", returnValue);

    returnValue = _mm_cmpistrz(a, b, mode);
    printf_s("_mm_cmpistrz return value should be 0: %i\n", returnValue);

    b.m128i_u16[7] = 0x0000;
    returnValue = _mm_cmpistrz(a, b, mode);
    printf_s("_mm_cmpistrz return value should be 1: %i\n", returnValue);

    int bb;
    cin >> bb;

    return 0;
}

1 个答案:

答案 0 :(得分:3)

你现在已经疯了,或者想出来了。但... 最终以“我”为中心的内在函数返回某个事件的索引。 内在的“内在函数”结束于&#39; m&#39;返回一个掩码(位/字节/字取决于...) 内在函数结尾于&#39;,&#39; o&#39; s&#39; s&#39;&#39; z&#39;返回一个EFLAGS位。 本能结束于&#39; a&#39;返回CFlag AND ZFlag的布尔结果。 (不是AFlag。)这样做是为了有一种简单的方法来测试你要查找的事件的发生以及一条指令的输入结束。 我真的在思考如何在高级语言中使用这些指令时做得非常糟糕。当时我非常满意地使用内联ASM来访问这些指令。他们真的有点......复杂......在更高级别的语言中有效使用,比如C.很抱歉。如果你真的进入ASM,他们可以很有趣。有点冷静你可以通过3或4指令循环完成多少工作。