gdb 打印和检查命令给出浮点变量的错误结果

问题描述 投票:0回答:1

我正在阅读一本关于 x64 汇编的书。这本书描述了一些关于如何使用 gdb 的内容,我能够检查整数,但打印不起作用。 如果我通过像这样使用检查来包含诸如“db”之类的大小,则检查将适用于整数,

x/bu &bNum
这将按预期输出 123。

对于浮点值,如果我在检查浮点值之前没有检查整数,我会得到我认为不正确的结果。 运行

x/qf &qNum3
将输出结果 1.26443839e+11

如果我使用

x/bu &bNum
然后运行
x/qf &qNum3
它将给出预期结果 3.1400000000000001 那么为什么只有在检查整数之后检查浮点数才能给出正确的输出?

使用前面任何不带“&”符号的命令都会导致 gdb 响应 “‘qNum3’具有未知类型;将其转换为其声明的类型” 这是预期的反应吗?

打印似乎永远不会给出正确的结果。

我按照书中的指示使用下面的命令来汇编和链接程序

nasm -f elf64 -g -F dwarf move.asm -l move.lst
gcc -o move move.o -no-pie

这是书上给出的示例程序。

; move.asm
section .data
      bNum  db    123
      wNum  dw    12345
      dNum  dd    1234567890
      qNum1 dq    1234567890123456789
      qNum2 dq    123456
      qNum3 dq    3.14
section .bss
section .text
      global main
main:
push  rbp
mov   rbp,rsp
      mov rax, -1           ; fill rax with 1s
      mov al, byte [bNum]   ; does NOT clear upper bits of rax
      xor rax,rax           ; clear rax
      mov al, byte [bNum]   ; now rax has the correct value
      mov rax, -1           ; fill rax with 1s
      mov ax, word [wNum]   ; does NOT clear upper bits of rax
      xor rax,rax           ; clear rax
      mov ax, word [wNum]   ; now rax has the correct value
      mov rax, -1           ; fill rax with 1s
      mov eax, dword [dNum] ; does clear upper bits of rax
      mov rax, -1           ; fill rax with 1s
      mov rax, qword [qNum1] ; does clear upper bits of rax
      mov qword [qNum2], rax ; one operand always a register
      mov rax, 123456       ; source operand an immediate value
      movq xmm0, [qNum3]    ; instruction for floating point
mov rsp,rbp
pop rbp
ret

x/qf &qNum3
预计接近3.14
x/qf &qNum3
将输出结果“<0x404027> 1.26443839e+11”

x/qt &qNum3
预计接近 01000000 01001000 11110101 11000011
x/qt &qNum3
将输出结果 01010001 11101011 10000101 00011111

x/qx &qNum3
预计接近 0x4048F5C3
x/qx &qNum3
将输出结果 0x51eb851f

print /f &qNum3
预计接近3.14
print /f &qNum3
将输出“$2 = 2.0803755547161745e-317”

如果首先运行命令

x/bu &bNum
,之前的检查命令现在将输出与之前不同的结果。

命令

x/qf &qNum3
将输出预期结果 3.14

x/qt &qNum3
现在将输出结果 00011111

x/qx &qNum3
现在将输出结果 0x1f

assembly gdb 64-bit nasm dwarf
1个回答
1
投票

/q
不是 GDB 的大小修饰符。根据
h x
,8 字节大小为
/g
(巨型)。

x /gf &qNum3
正确地将内存检查为8字节双精度,
p (double)qNum3
p (double[3])qNum1
一样打印全部 3 个。

我不知道

/q
作为 /x 的修饰符做什么,但由于大小仍然是默认的 32 位,您将尾数的低 4 个字节解释为
float
(IEEE 二进制 32) ,与您从
p (float)qNum3

获得的数字相同
© www.soinside.com 2019 - 2024. All rights reserved.