【发布时间】:2021-01-14 19:15:34
【问题描述】:
我正在 x86-64 中编写一个函数来将一个 1 字节的值转换为一个十六进制字符串,该字符串表示该字节的 ASCII 码。在我的功能开始时,我尝试使用
movb %dil, %r11b
将 1 字节的值存储在寄存器 %r11 的最低字节中。但是,当我在 gdb 中检查它时,从未设置 %r11b。相反,正在设置 %r11 的较高字节。这是我在使用 gdb 时得到的:
Breakpoint 1, 0x00000000004011f0 in byte_as_hex ()
(gdb) print /x $r11b
$1 = 0x0
(gdb) print /x $r11
$2 = 0x246
(gdb) print /x $rdi
$3 = 0x48
(gdb) print /x $dil
$4 = 0x48
(gdb) stepi /* subq $8, %rsp */
0x00000000004011f4 in byte_as_hex ()
(gdb) print /x $r11b
$5 = 0x0
(gdb) print /x $r11
$6 = 0x246
(gdb) print /x $rdi
$7 = 0x48
(gdb) print /x $dil
$8 = 0x48
(gdb) stepi /* movb %dil, %r11b */
0x00000000004011f7 in byte_as_hex ()
(gdb) print /x $r11b
$9 = 0x0
(gdb) print /x $r11
$10 = 0x248
(gdb) print /x $rdi
$11 = 0x48
(gdb) print /x $dil
$12 = 0x48
(gdb) print /x $r11d
$13 = 0x248
(gdb) print /x $r11w
$14 = 0x248
(gdb) print /x $r11b
$15 = 0x0
我很困惑,因为我专门尝试将 movb 从 %dil 移动到 %r11b,但我仍然无法设置字节。谁能向我解释为什么会这样?谢谢!
【问题讨论】:
-
您能否展示每个步骤的说明,以便更容易理解假设发生的事情?这似乎是损坏/错误的 GDB 行为。
-
我想知道GDB是否会与
%r11l这样的reg名称不同?字节寄存器名称有两种不同的约定:r11b和r11l。我忘了是谁发明的。 GDB 似乎确实将r11b识别为寄存器名称,所以不应该这样,但您永远不知道可能存在错误。 -
我的函数的开头行是
byte_as_hex: subq $8, %rsp movb %dil, %r11b shr $4, %r11b在尝试 movb 之前我唯一做的就是调整堆栈指针,所以我不确定会出现什么问题。 -
当然,这很好,但是edit 你的问题是要为每个
stepi执行哪条指令,例如作为“注释”或 GDB 输出中的额外行。您的指令几乎可以肯定执行得很好,而 GDB 只是无法正常工作。 (GDB 已经不是第一次出现错误了。你有什么版本的 GDB?) -
我刚刚检查了
r11l而不是r11b,结果发现这是存储值的位置。我仍然不太确定发生了什么,但至少我知道该值存储在某个地方。我的 gdb 版本是 Fedora 8.3.50.20190824-30.fc31。我现在将编辑我的问题 - 这是我的第一个问题,所以我仍在学习如何在这里回复。感谢您的帮助!
标签: gdb x86-64 cpu-registers