2014-01-10 2 views
3

Я использую GDB в течение 1 дня, и я накопил достойное понимание этого. Однако, когда я устанавливаю точку останова в конечной точке с запятой, используя GDB и регистры печати, я не могу полностью интерпретировать значение данных, хранящихся в регистре XMM.Интерпретация регистров GDB (регистров SSE)

Я не знаю, находятся ли данные (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 
} 

Так бы кто-то любезно дал мне понять, как интерпретировать данные.

ответ

7

Регистры 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 отображает содержимое регистра в естественном порядке , т.е. слева направо, от MS до LS.

Так что если у вас есть следующий код:

#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 

Однако, если вы шагаете через код в БГД и исследовать v вы см.:

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

Так что я загружаю массив, используя встроенную функцию _mm_load_si128, однако я не знаете, что самый значительный байт в массиве становится наименее значимым байтом в регистре. – Nocturnal

+0

В общем, вам не нужно беспокоиться об этом, но применяются обычные правила x86 little endian, поэтому байт LS из байта с 16 байтами находится в байте LS из 16-байтового регистра. gdb отображает регистр в натуральном порядке - см. правки для ответа выше. –

Смежные вопросы