将8个16位SSE寄存器转换为8位数据

2024-02-17

假设我有一个包含 16 位数据的 SSE 数组:

{1,2,3,4,5,6,7,8}

现在我需要通过在前 8 个字节中仅存储 16 位数据的低字节来将此 SSE 数组转换为 8 位数据,如下所示:

{1,2,3,4,5,6,7,8,0,0,0,0,0,0,0,0}.

有没有SSE指令来执行这个操作?


As @harold https://stackoverflow.com/users/555045/harold在上面的评论中说,你可以很容易地做到这一点, e.g.

#include <stdio.h>
#include <tmmintrin.h>

static __m128i pack_16_to_8(const __m128i v)
{
    const __m128i vperm = _mm_setr_epi8(0, 2, 4, 6, 8, 10, 12, 14, -1, -1, -1, -1, -1, -1, -1, -1);

    return _mm_shuffle_epi8(v, vperm);
}

int main(void)
{
    const __m128i v = _mm_setr_epi16(1, 2, 3, 4, 5, 6, 7, 8);

    printf("%vhd -> %vd\n", v, pack_16_to_8(v));
    return 0;
}

编译并运行:

$ gcc -Wall -mssse3 pack_16_to_8.c && ./a.out

1 2 3 4 5 6 7 8 -> 1 2 3 4 5 6 7 8 0 0 0 0 0 0 0 0
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将8个16位SSE寄存器转换为8位数据 的相关文章

  • 比“add esp, 4”更小的指令

    又是我 我的程序中有很多 add esp 4 我正在尝试减小它的大小 是否有任何更小的指令可以替代 add esp 4 pop edx 或者您不介意破坏的任何其他整数寄存器 这就是现代编译器实际上所做的 https stackoverflo
  • x86 asm 图形设置的分辨率高于 640x480?

    我刚刚开始使用汇编语言 感觉像学习新东西 并且遇到了一些问题 到目前为止 我一直在浏览的所有教程都没有回答 或者太旧而无法知道 1 我尝试了一些搜索 也许我只是不知道正确的关键字 但我找不到用于更改屏幕分辨率等的图形模式的更新列表 我发现的
  • 气体:内存引用太多

    编译时指令如下 movl 4 ebp 8 ebp I got 内存引用过多 它出什么问题了 括号之前的数字是字节偏移量 这会导致发生内存引用 并且不能有两个movl 您需要先将值暂时移至寄存器 movl 4 ebp ecx movl ecx
  • 为什么 VC++ 编译器 MOV+PUSH args 而不是仅仅 PUSH 它们? x86

    在 VC 的反汇编中 正在进行函数调用 编译器在压入本地指针之前将其 MOV 到寄存器 memcpy nodeNewLocation pNode sizeCurrentNode 0041A5DA 8B 45 F8 mov eax dword
  • 对齐与未对齐 x86 SIMD 指令之间的选择

    SIMD指令一般有两种类型 A 使用对齐的内存地址 如果地址未在操作数大小边界上对齐 则会引发一般保护 GP 异常 movaps xmm0 xmmword ptr rax vmovaps ymm0 ymmword ptr rax vmova
  • 内在数组访问比 std::vector 访问快得多——黑魔法?

    我已经设置了一个测试程序来将数组访问性能与 std vector 的访问性能进行比较 我发现了几个类似的问题 但似乎没有一个问题能解决我的具体问题 一段时间以来 我一直在摸不着头脑 为什么数组访问似乎比向量访问快 6 倍 而我过去读到它们应
  • 同时使用 SSE2 内在函数和 gcc 内联汇编器

    我尝试在 gcc 中混合 SSE2 内在函数和内联汇编器 但是 如果我将变量指定为 xmm0 register 作为输入 那么在某些情况下我会收到编译器错误 例子 include
  • x86 程序执行期间方向标志 (DF) 的默认状态

    在反汇编中 我经常看到使用字符串操作指令而不考虑方向标志 DF 的状态 如下所示 or ecx 0FFFFFFFFh xor eax eax mov edi ebp repne scasb CLD or STD自函数开始以来未找到指令 也未
  • Intel 和 AMD 处理器有相同的汇编程序吗?

    C语言被用来编写Unix以实现可移植性 使用不同编译器编译的同一个C语言程序会产生不同的机器指令 为什么 Windows 操作系统能够在两者上运行Intel https en wikipedia org wiki Intel and AMD
  • 如何使用 LOCK ASM 前缀来读取值?

    我知道如何使用 LOCK 来线程安全地递增一个值 lock inc J 但是如何以线程安全的方式读取 J 或任何值 LOCK 前缀不能与 mov 一起使用 如果我执行以下操作 xor eax eax lock add eax J mov J
  • 为什么 NASM 在使用有效的指令助记符作为操作数中的符号名称方面没有问题?

    我编写了以下简单程序 但 nasm 拒绝编译它 section text global start start mov rax 0x01 mov rdi 0x01 mov rsi str mov rdx 0x03 syscall mov r
  • 在 clang 中向量化函数

    我正在尝试根据此用 clang 对以下函数进行矢量化铿锵参考 http llvm org docs Vectorizers html 它采用字节数组向量并根据以下条件应用掩码this RFC https www rfc editor org
  • 在 SSE 和 AVX512 寄存器之间移动数据?

    我想将四个 xmm 寄存器移动到一个 zmm 寄存器中 使用 AVX512 指令执行一些计算并将结果返回到 XMM 寄存器 不通过内存来做到这一点的最有效方法是什么 None
  • 给寄存器赋值并加减

    我对此完全迷失了 我需要使用寄存器来计算以下表达式的编程 varA varA varB varC varD 其中 varA varB 等是变量 将整数值分配给上述变量的 EAX EBX ECX 和 EDX 寄存器 这意味着 您可以对输入进行
  • 汇编:使用数据段寄存器(DS)

    目前我正在学习 x86 汇编 因为我喜欢微控制器编程 所以我熟悉汇编 目前我一直在到处寻找这个问题的答案 但似乎找不到它 DS寄存器 我知道它应该指向我程序中的全局数据 但我不知道知道它到底是如何工作的 我正在使用 NASM 在大多数简单的
  • 使用 XCHG 解锁的自旋锁

    维基百科提供的使用 x86 XCHG 命令的自旋锁的示例实现是 Intel syntax locked The lock variable 1 locked 0 unlocked dd 0 spin lock mov eax 1 Set t
  • MS-DOS - 是否可以对 24 位图形进行编程?

    是否可以在 DOS 机器上以 24 位颜色深度进行编程 我知道 VGA 支持 8 位色深 但是有没有办法弄出 24 位色深 谷歌的研究没有发现任何结果 我正在 FreeDOS 而不是 MS DOS 上编程 如果这会影响答案的话 对的 这是可
  • int 13h 42h 不会在 Bochs 中加载任何内容

    我将引导加载程序从 CHS 更改为 LBA 因此我更换了int 13h 02h with int 13h 42h 它在 QEMU 中工作正常 但是 我在 Bochs 和我的笔记本电脑上运行它时遇到问题 我将引导加载程序写入 USB 闪存驱动
  • 段寄存器如何参与内存地址转换?

    到目前为止我所学到的有关细分的知识 虚拟地址包含段选择器和偏移量 段选择器与GDTR配合使用 查找段描述符的线性地址 段描述符保存有关所选段的信息 包括其线性地址 所以 我的问题是 根据我所读到的内容 虚拟地址被加载到段寄存器中 然后以某种
  • 在汇编中,指令指定数据类型吗?

    我是汇编语言编程 x86 的初学者 以下说法是否正确 在汇编中 BYTE WORD DWORD 等数据类型分别表示 8 位 16 位和 32 位模式 而不仅仅是整数 它们本身没有意义 它们只是位模式 使用它们的指令赋予了它们意义 汇编 代码

随机推荐