Gdb 无法设置寄存器x86-64中的最低字节?
我正在x86-64中编写一个函数,将一个1字节的值转换为表示该字节ASCII码的十六进制字符串。在函数开始时,我尝试使用Gdb 无法设置寄存器x86-64中的最低字节?,gdb,x86-64,cpu-registers,Gdb,X86 64,Cpu Registers,我正在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) pri
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
我非常困惑,因为我特别尝试将B从%dil移动到%r11b,但仍然无法设置字节。谁能向我解释一下为什么会这样?谢谢 这里有多个问题:
$
开头的GDB局部变量)显示为0,而不是默认的void
,在未指定格式时显示:它们没有别名,例如
r11b
的r11l
,因此必须使用正确的名称。您能否显示这些步骤的说明,以便更容易地了解应该发生的情况?这看起来像是坏的/有缺陷的GDB行为。我想知道GDB是否会与注册名不同,如%r11l
?字节寄存器名有两种不同的约定:r11b
和r11l
。我忘了是谁发明的。GDB似乎正在将r11b
识别为寄存器名,所以不应该是这样,但您永远不会知道可能存在的错误。我的函数的开始行是byte\u as\u hex:subq$8,%rsp movb%dil,%r11b shr$4,%r11b
我在尝试movb之前做的唯一一件事就是调整堆栈指针,因此,我不确定会出什么问题。当然,这很好,但您的问题是,对于每个stepi
,您需要输入刚刚执行的指令,例如作为“注释”或GDB输出中的额外行。几乎可以肯定,您的指令执行得很好,而GDB不能正常工作。(这不是GDB第一次出现bug。你有什么版本的GDB?)我只是检查了r11l
,而不是r11b
,结果发现存储值的地方就是这里。我仍然不太确定发生了什么,但至少我知道这个值存储在某个地方。我的gdb版本是Fedora 8.3.50.20190824-30.fc31。我现在就编辑我的问题-这是我的第一个问题,所以我还在学习如何回答。谢谢你的帮助这些名字不是GDB独有的;我认为它们起源于AMD64中的AMD,它早于英特尔IA-32e。但是,是的,英特尔的手册只提到了r8..r15的r11b
名称。另见@PeterCordes哦,这现在有道理了。我“幸运地”选择了RSP
而不是R8
-R15
来测试:)上的低字节命名(注意,情况正好相反:根据您的第一个链接,是AMD使用了*B
作为编号寄存器)哦,谢谢,是的,我自己总是使用r8b
样式,忘记了哪个供应商在手册中使用了哪个。是针对第1点中GDB bug的规范问答。显然,未来的GDB版本应该打印void,而不是0,即使格式为。我认为这个问答实际上是重复的,尽管你的答案有一些更多的信息,如大写字母和其他注册名称,如ftag
$ 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)
al
cl
dl
bl
spl
bpl
sil
dil
r8l
...
r15l