解读GDB寄存器(SSE寄存器)

5
我已经使用GDB一天了,并且对它有了相当的了解。但是,当我在GDB中设置一个在最后分号处的断点,并打印寄存器时,我无法完全解释存储在XMM寄存器中的数据的含义。我不知道数据是以(MSB>LSB)格式还是反过来的。
    __m128i S = _mm_load_si128((__m128i*)Array16Bytes);

}

这是我得到的结果。
(gdb) print $xmm0
$1 = {
  v4_float = {1.2593182e-07, -4.1251766e-18, -5.43431603e-31, -2.73406277e-14}, 
  v2_double = {4.6236050467459811e-58, -3.7422963639201271e-245}, 
  v16_int8 = {52, 7, 55, -32, -94, -104, 49, 49, -115, 48, 90, -120, -88, -10, 67, 50}, 
  v8_int16 = {13319, 14304, -23912, 12593, -29392, 23176, -22282, 17202}, 
  v4_int32 = {872888288, -1567084239, -1926210936, -1460255950}, 
  v2_int64 = {3749026652749312305, -8273012972482837710}, 
  uint128 = 0x340737e0a29831318d305a88a8f64332
}

所以,能否有人指导我如何解释这些数据。
1个回答

11

SSE(XMM)寄存器可以以多种不同的方式进行解释。寄存器本身没有隐含数据表示的知识,它只是保存了128位的数据。XMM寄存器可以表示:

4 x 32 bit floats        __m128
2 x 64 bit doubles       __m128d
16 x 8 bit ints          __m128i
8 x 16 bit ints          __m128i
4 x 32 bit ints          __m128i
2 x 64 bit ints          __m128i
128 individual bits      __m128i

当gdb显示一个XMM寄存器时,它会给出所有可能的解释,就像你上面的例子一样。

如果你想使用特定的解释(例如16个8位整数)来显示寄存器,那么可以这样做:

(gdb) p $xmm0.v16_int8
$1 = {0, 0, 0, 0, 0, 0, 0, 0, -113, -32, 32, -50, 0, 0, 0, 2}

关于字节顺序,gdb按照自然顺序从高位到低位(从左往右)显示寄存器内容。

例如,如果你有以下代码:

#include <stdio.h>
#include <stdint.h>

#include <xmmintrin.h>
int main(int argc, char *argv[])
{
    int8_t buff[16] __attribute__ ((aligned(16))) = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };

    __m128i v = _mm_load_si128((__m128i *)buff);

    printf("v = %vd\n", v);

    return 0;
}

如果您编译并运行此代码,将会看到:
v = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

然而,如果你在gdb中逐步执行代码并检查v,你会看到:

v16_int8 = {15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}

所以我在使用内在函数_mm_load_si128加载数组,但我不知道数组中的最高有效字节是否会变成寄存器中的最低有效字节。 - Nocturnal
通常情况下,您不需要担心这个问题,但是普通的x86小端惯例适用,因此16字节负载的LS字节位于16字节寄存器的LS字节处。 gdb以自然顺序显示寄存器-请参见上面回答的编辑。 - Paul R

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接