GDB:SSE寄存器输出格式 [英] gdb: SSE register output format

查看:323
本文介绍了GDB:SSE寄存器输出格式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我输出寄存器SSE使用打印我得到预期的结果:

 (GDB)p $ XMM0
$ 1 = {
    v4_float = {0,0,0,0},
    v2_double = {0,0},
    v16_int8 = {0℃,重复16次>},
    v8_int16 = {0,0,0,0,0,0,0,0},
    v4_int32 = {0,0,0,0},
    v2_int64 = {0,0},
    uint128 = 0
}

不过,如果我使用信息注册$ XMM0 一切都在十六进制:

 (GDB)I R $ XMM0
XMM0 {
    v4_float = {为0x0,为0x0,为0x0,为0x0},
    v2_double = {为0x0,为0x0},
    v16_int8 = {&为0x0 LT;重复16次>},
    v8_int16 = {为0x0,为0x0,为0x0,为0x0,为0x0,为0x0,为0x0,为0x0},
    v4_int32 = {为0x0,为0x0,为0x0,为0x0},
    v2_int64 = {为0x0,为0x0},
    uint128 = 0x00000000000000000000000000000000
}

有没有办法得到的结果相同,因为我从打印获得

编辑:
也许一个不相关的问题,但我怎么际preT v4_float 的价值?
举个例子:

 (GDB)I R $ XMM0
XMM0 {
    v4_float = {为0x1,为0x0,为0x0,为0x0},
    v2_double = {为0x0,为0x0},
    v16_int8 = {为0x0,为0x0,0XA0,0x3F的,为0x0<重复12次>},
    v8_int16 = {为0x0,0x3fa0,为0x0,为0x0,为0x0,为0x0,为0x0,为0x0},
    v4_int32 = {0x3fa00000,为0x0,为0x0,为0x0},
    v2_int64 = {0x3fa00000,为0x0},
    uint128 = 0x0000000000000000000000003fa00000
}

不应该 v4_float [0] v4_int32 [0] 同时为 0x3fa00000 1.25f )?如果我使用打印我得到正确 v4_float = {1.25,0,0,0} 。那么,为什么是 v4_float [0] =用时为0x1 信息登记


解决方案

  

有没有办法得到的结果相同,因为我从印刷得到?


不过,我做了一些这方面的研究,以便想它张贴在这里为今后的参考。以下是有关命令的信息信息所有寄存器和有关的特殊寄存器。


  

一些机器具有特殊功能寄存器,其内容可除preTED
  几种不同的方式。例如,现代基于x86的机器有
  SSE和MMX寄存器,可容纳在包装在一起的几个值
  几种不同的格式。


  
  

该信息登记命令显示的规范名称。例如,上
  在SPARC,信息登记显示处理器状态寄存器
  $ PSR但你也可以称其为$ ps的;而在基于x86的计算机
  $ PS是的别名EFLAGS登记。 GDB总是认为
  一个普通寄存器的内容作为一个整数当寄存器
  检验用这种方法


它看起来像有GDB的限制,显示寄存器(由于各种原因喜欢不同类型的机器和其他​​原因)时。我们还应该记住,寄存器没有你的程序的一个简单的变量,而这是特殊的,独特的一个程序,它看起来像十六进制是用于显示这些寄存器自然的格式。但是尽可能的gdb将在两种格式显示的通用寄存器的值的内容。只是为了说明它考虑以下的输出:

  //我们可以看到,GDB在两个格式显示寄存器(十六进制和十进制)
//并在某些情况下,十六进制和十六进制格式。
(GDB)信息 - [R
RAX 0x7ffff7dd6568 140737351869800
RBX为0x0 0
RCX 0x400620 4195872
RDX 0x7fffffffe218 140737488347672
RSI 0x7fffffffe208 140737488347656
RDI为0x1 1
RBP 0x7fffffffe120 0x7fffffffe120
RSP 0x7fffffffe070 0x7fffffffe070
R8 0x4006b0 4196016
.............................
DS为0x0 0
ES为0x0 0
FS为0x0 0
GS为0x0 0
// GDB会间preT在正常的变量类型的寄存器。但是,如果
//我们希望在小数中显示它,而十六进制格式。
(GDB)p $ RSP
$ 24 =(无效*)0x7fffffffe070
(GDB)P / D $ RSP
$ 25 = 140737488347248

有是可以更改默认的基地,为数字显示的另一个重要设置。


  

设置输出基数基础


  
  

设置数字显示的默认基地。为支持基地的选择
  是十进制8,10,或16基地本身必须要么指定
  明确地或使用当前输入基数。


这可以用来改变GDB内部正常的变量/数字的默认显示。然而,这些设置还(使用信息登记册时)不会改变寄存器的默认视图。然而,当我们使用print命令显示它,它改变其默认从十进制为十六进制正常变量和寄存器。只是想说明它认为我们有一个局部变量(结果)。

 (GDB)显示输出基数10
对于价值观的打印默认输出基数是10。
(GDB)p II
$ 26 =(INT *)0x400369
(GDB)芘结果
$ 27 = 0
(GDB)信息R $ XMM0
XMM0 {
  v4_float = {为0x0,为0x0,为0x0,为0x0},
  v2_double = {为0x0,为0x0},
  v16_int8 = {0xFF的,为0x0<重复15次>},
  v8_int16 = {0xFF的,为0x0,为0x0,为0x0,为0x0,为0x0,为0x0,为0x0},
  v4_int32 = {0xFF的,为0x0,为0x0,为0x0},
  v2_int64 = {0xFF的,为0x0},
  uint128 = 0x000000000000000000000000000000ff
}
(GDB)p $ XMM0
$ 28 = {
  v4_float = {3.57331108e-43,0,0,0},
  v2_double = {1.2598673968951787e-321,0},
  v16_int8 = {-1,0℃,重复15次>},
  v8_int16 = {255,0,0,0,0,0,0,0},
  v4_int32 = {255,0,0,0},
  v2_int64 = {255,0},
  uint128 = 255
}
(GDB)设定的输出基数的16
输出基数现在设置为十进制16,10进制,八进制20。
(GDB)芘结果
$ 29 =为0x0
(GDB)信息R $ XMM0
XMM0 {
  v4_float = {为0x0,为0x0,为0x0,为0x0},
  v2_double = {为0x0,为0x0},
  v16_int8 = {0xFF的,为0x0<重复15次>},
  v8_int16 = {0xFF的,为0x0,为0x0,为0x0,为0x0,为0x0,为0x0,为0x0},
  v4_int32 = {0xFF的,为0x0,为0x0,为0x0},
  v2_int64 = {0xFF的,为0x0},
  uint128 = 0x000000000000000000000000000000ff
}
(GDB)p $ XMM0
$ 30 = {
  v4_float = {3.57331108e-43,0,0,0},
  v2_double = {1.2598673968951787e-321,0},
  v16_int8 = {0xFF的,为0x0<重复15次>},
  v8_int16 = {0xFF的,为0x0,为0x0,为0x0,为0x0,为0x0,为0x0,为0x0},
  v4_int32 = {0xFF的,为0x0,为0x0,为0x0},
  v2_int64 = {0xFF的,为0x0},
  uint128 = 0x000000000000000000000000000000ff
}

因此​​,它的样子,也没有办法在使用信息寄存器命令来更改格式。但是,如果我们要使用打印命令来显示寄存器,其默认
格式可以改变GDB不认为寄存器作为普通寄存器,因此在不同的格式显示。因此,我们应该使用这两种类型的命令在我们的调试会话中显示不同情况下的寄存器。

When I output a SSE register using print I get the expected result:

(gdb) p $xmm0
$1 = {
    v4_float = {0, 0, 0, 0}, 
    v2_double = {0, 0}, 
    v16_int8 = {0 <repeats 16 times>}, 
    v8_int16 = {0, 0, 0, 0, 0, 0, 0, 0}, 
    v4_int32 = {0, 0, 0, 0}, 
    v2_int64 = {0, 0}, 
    uint128 = 0
}

However, if I use info registers $xmm0 everything is in hexadecimal:

(gdb) i r $xmm0
xmm0           {
    v4_float = {0x0, 0x0, 0x0, 0x0}, 
    v2_double = {0x0, 0x0}, 
    v16_int8 = {0x0 <repeats 16 times>}, 
    v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, 
    v4_int32 = {0x0, 0x0, 0x0, 0x0}, 
    v2_int64 = {0x0, 0x0}, 
    uint128 = 0x00000000000000000000000000000000
}

Is there any way to get the same output as I get from print?

EDIT: Maybe an unrelated question, but how do I interpret the values of v4_float? An example:

(gdb) i r $xmm0
xmm0           {
    v4_float = {0x1, 0x0, 0x0, 0x0}, 
    v2_double = {0x0, 0x0}, 
    v16_int8 = {0x0, 0x0, 0xa0, 0x3f, 0x0 <repeats 12 times>}, 
    v8_int16 = {0x0, 0x3fa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, 
    v4_int32 = {0x3fa00000, 0x0, 0x0, 0x0}, 
    v2_int64 = {0x3fa00000, 0x0}, 
    uint128 = 0x0000000000000000000000003fa00000
}

Shouldn't v4_float[0] and v4_int32[0] both be 0x3fa00000 (1.25f)? If I use print I correctly get v4_float = {1.25, 0, 0, 0}. So why is v4_float[0] = 0x1 when using info registers?

解决方案

Is there any way to get the same output as I get from print?, No

However I did some study on this so wanted to post it here for the reference in future. Following is the information about command "info all-registers and about the special registers.

Some machines have special registers whose contents can be interpreted in several different ways. For example, modern x86-based machines have SSE and MMX registers that can hold several values packed together in several different formats.

The info registers command shows the canonical names. For example, on the SPARC,info registers displays the processor status register as $psr but you can also refer to it as $ps; and on x86-based machines $ps is an alias for the eflags register. gdb always considers the contents of an ordinary register as an integer when the register is examined in this way.

It looks like that there is limitation of gdb when displaying the registers(due to various reasons like different types of machine and other reason).We should also remember that register is not a simple variable of your program rather it is special and unique for a program and it looks like hexadecimal is the natural format for displaying these registers. However wherever possible gdb would display the contents of general purpose registers value in both format. Just to illustrate it consider the following output:

//We can see that gdb is displaying the registers in both format(hex and decimal)
//and in some cases hex and hex format.
(gdb) info r
rax            0x7ffff7dd6568   140737351869800
rbx            0x0  0
rcx            0x400620 4195872
rdx            0x7fffffffe218   140737488347672
rsi            0x7fffffffe208   140737488347656
rdi            0x1  1
rbp            0x7fffffffe120   0x7fffffffe120
rsp            0x7fffffffe070   0x7fffffffe070
r8             0x4006b0 4196016
.............................
ds             0x0  0
es             0x0  0
fs             0x0  0
gs             0x0  0
//gdb would interpret the registers in the normal variable types. However if 
// we want to display it in decimal rather in hex format. 
(gdb) p $rsp
$24 = (void *) 0x7fffffffe070
(gdb) p/d $rsp
$25 = 140737488347248

There is another important setting which can change the default base for the numeric display.

set output-radix base

Set the default base for numeric display. Supported choices for base are decimal 8, 10, or 16. base must itself be specified either unambiguously or using the current input radix.

This can be used to change the default display of the normal variable/numbers inside GDB. However these setting also does not change the default view of registers(when using info register). However when we display it using print command, it changes its default from decimal to hex for normal variables as well registers. Just to illustrate it consider that we have one local variable(result).

(gdb) show output-radix 10
Default output radix for printing of values is 10.
(gdb) p ii
$26 = (int *) 0x400369
(gdb) p result
$27 = 0
(gdb) info r $xmm0
xmm0           {
  v4_float = {0x0, 0x0, 0x0, 0x0}, 
  v2_double = {0x0, 0x0}, 
  v16_int8 = {0xff, 0x0 <repeats 15 times>}, 
  v8_int16 = {0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, 
  v4_int32 = {0xff, 0x0, 0x0, 0x0}, 
  v2_int64 = {0xff, 0x0}, 
  uint128 = 0x000000000000000000000000000000ff
}
(gdb) p $xmm0
$28 = {
  v4_float = {3.57331108e-43, 0, 0, 0}, 
  v2_double = {1.2598673968951787e-321, 0}, 
  v16_int8 = {-1, 0 <repeats 15 times>}, 
  v8_int16 = {255, 0, 0, 0, 0, 0, 0, 0}, 
  v4_int32 = {255, 0, 0, 0}, 
  v2_int64 = {255, 0}, 
  uint128 = 255
}
(gdb) set output-radix 16
Output radix now set to decimal 16, hex 10, octal 20.
(gdb) p result
$29 = 0x0
(gdb) info r $xmm0
xmm0           {
  v4_float = {0x0, 0x0, 0x0, 0x0}, 
  v2_double = {0x0, 0x0}, 
  v16_int8 = {0xff, 0x0 <repeats 15 times>}, 
  v8_int16 = {0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, 
  v4_int32 = {0xff, 0x0, 0x0, 0x0}, 
  v2_int64 = {0xff, 0x0}, 
  uint128 = 0x000000000000000000000000000000ff
}
(gdb) p $xmm0
$30 = {
  v4_float = {3.57331108e-43, 0, 0, 0}, 
  v2_double = {1.2598673968951787e-321, 0}, 
  v16_int8 = {0xff, 0x0 <repeats 15 times>}, 
  v8_int16 = {0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, 
  v4_int32 = {0xff, 0x0, 0x0, 0x0}, 
  v2_int64 = {0xff, 0x0}, 
  uint128 = 0x000000000000000000000000000000ff
}

So it look like, there is no way to change the format while using the info register command. However if we want to display the register using print command, its default format can be changed as GDB does consider registers as normal registers and hence display it in different format. Hence we should use the both type of commands for displaying the registers under different circumstances in our debugging session.

这篇关于GDB:SSE寄存器输出格式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆