Debugging gdb:SSE寄存器输出格式

Debugging gdb:SSE寄存器输出格式,debugging,assembly,gdb,Debugging,Assembly,Gdb,当我使用print输出SSE寄存器时,我得到了预期的结果: (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},

当我使用
print
输出SSE寄存器时,我得到了预期的结果:

(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
}
是否有任何方法可以获得与我从
print
获得的相同的输出

编辑: 可能是一个无关的问题,但我如何解释
v4\u float
的值? 例如:

(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
}
(gdb)i r$xmm0
xmm0{
v4_float={0x1,0x0,0x0,0x0},
v2_double={0x0,0x0},
v16_int8={0x0,0x0,0xa0,0x3f,0x0},
v8_int16={0x0,0x3fa0,0x0,0x0,0x0,0x0,0x0,0x0},
v4_int32={0x3fa00000,0x0,0x0,0x0},
v2_int64={0x3fa00000,0x0},
uint128=0x0000000000000000000000003fa00000
}
v4\u float[0]
v4\u int32[0]
不应该都是
0x3fa00000
1.25f
)?如果我使用
print
我正确地得到
v4_float={1.25,0,0,0}
。那么,为什么在使用
信息寄存器时
v4\u float[0]=0x1

是否有任何方法可以获得与打印相同的输出?,

不过我对此做了一些研究,所以我想把它贴在这里,以备将来参考。以下是有关命令“info all registers和特殊寄存器的信息

有些机器有特殊的寄存器,其内容可以被解释 以几种不同的方式。例如,现代基于x86的机器 SSE和MMX寄存器,可将多个值打包在一个寄存器中 几种不同的格式

info registers命令显示规范名称 SPARC信息寄存器将处理器状态寄存器显示为 $psr,但您也可以将其称为$ps;并在基于x86的机器上使用 $ps是eflags寄存器的别名。gdb始终考虑 普通寄存器的内容为整数 这样检查

在显示寄存器时,似乎存在gdb的限制(由于各种原因,如不同类型的机器和其他原因)我们还应该记住,登记不是程序的简单变量,而是程序的特殊性和唯一性,它看起来像十六进制是显示这些寄存器的自然格式。然而,只要可能,GDB将以两种格式显示通用寄存器的值。以下输出:

//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
另一个重要的设置可以更改数字显示的默认基数

设置输出基数基数

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

这可用于更改GDB内正常变量/数字的默认显示。但是,这些设置也不会更改寄存器的默认视图(使用info寄存器时)但是,当我们使用打印命令显示它时,它将默认值从十进制改变为十六进制,而不是普通变量,也就是说,寄存器。
(gdb)显示输出基数10
打印值的默认输出基数为10。
(gdb)p ii
$26=(整数*)0x400369
(gdb)p结果
$27 = 0
(gdb)信息r$xmm0
xmm0{
v4_float={0x0,0x0,0x0,0x0},
v2_double={0x0,0x0},
v16_int8={0xff,0x0},
v8_int16={0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
v4_int32={0xff,0x0,0x0,0x0},
v2_int64={0xff,0x0},
uint128=0x000000000000000000000000FF
}
(gdb)p$xmm0
$28 = {
v4_float={3.57331108e-43,0,0,0},
v2_double={1.2598673968951787e-321,0},
v16_int8={-1,0},
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)p结果
$29=0x0
(gdb)信息r$xmm0
xmm0{
v4_float={0x0,0x0,0x0,0x0},
v2_double={0x0,0x0},
v16_int8={0xff,0x0},
v8_int16={0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
v4_int32={0xff,0x0,0x0,0x0},
v2_int64={0xff,0x0},
uint128=0x000000000000000000000000FF
}
(gdb)p$xmm0
$30 = {
v4_float={3.57331108e-43,0,0,0},
v2_double={1.2598673968951787e-321,0},
v16_int8={0xff,0x0},
v8_int16={0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
v4_int32={0xff,0x0,0x0,0x0},
v2_int64={0xff,0x0},
uint128=0x000000000000000000000000FF
}
因此,在使用info register命令时,似乎无法更改格式。但是,如果要使用print命令显示寄存器,则默认设置为
格式可以改变,因为GDB确实将寄存器视为普通寄存器,因此以不同的格式显示寄存器。因此,在调试会话中,我们应该使用两种类型的命令来显示不同情况下的寄存器。< /P>尝试追加<代码> /d < /代码>。decimal@FredrikPihl我似乎无法指定格式使用
info registers
时出错,还是我遗漏了什么?好的,我刚刚发现gdb将浮点值转换为整数,然后将它们以十六进制显示在
v4\u float
中,然后我必须单独打印每个寄存器。感谢您的研究!
//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
(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
}