我正在 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 bug.) 未定义便利变量(一个 GDB 局部变量,以
$
),当使用显式格式说明符打印时,显示为 0 而不是默认值void
,未指定格式时显示:
$ gdb /bin/true
Reading symbols from /bin/true...
(gdb) p $asdf
$1 = void <------ undefined, OK
(gdb) p/x $asdf
$2 = 0x0 <------ the problem
(gdb) set $asdf=4345
(gdb) p $asdf
$3 = 4345
(gdb) p/x $asdf
$4 = 0x10f9
(gdb)
- 寄存器值与便利变量的值具有相同的语法。因此,当您弄错寄存器的名称时,例如使用
r11b
而不是 GDB 的r11l
,您引用一个(n个未定义)便利变量。此外,即使您只是在不正确的情况下使用正确的名称,例如R11L
,你也碰到这个了。
- GDB 使用自己的 x86(_64) 寄存器名称集。有时它们与给出的名称不同,例如在英特尔手册中(例如
ftag
而不是英特尔的FTW
)。无论如何,通用寄存器的最低字节在 GDB 中具有以下名称:
al
cl
dl
bl
spl
bpl
sil
dil
r8l
...
r15l
他们没有别名,例如r11b
for r11l
,因此必须使用正确的名称。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)