无法设置寄存器x86-64中的最低字节? [英] Unable to set the lowest byte in a register x86-64?
问题描述
我正在x86-64中编写一个函数,将一个1字节的值转换为代表该字节ASCII码的十六进制字符串。在我的函数开始时,我尝试使用
I'm writing a function in x86-64 to convert a 1-byte value into a hexadecimal string representing the ASCII code for that byte. At the start of my function, I try to use
movb %dil, %r11b
将1字节的值存储在寄存器%r11的最低字节中。但是,当我在gdb中进行检查时,从未设置%r11b。而是设置了%r11的较高字节。这是使用gdb时得到的结果:
to store the 1-byte value in the lowest byte of register %r11. However, when I examine this in gdb, %r11b is never set. Instead, the higher bytes of %r11 are getting set. This is what I get when using 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
我很困惑,因为我专门尝试将%dil移到%r11b,但是我仍然没有设置字节。有人可以向我解释为什么会这样吗?谢谢!
I'm very confused because I specifically tried to movb from %dil into %r11b, but I still can't set the byte. Could anyone explain to me why this is this happening? Thanks!
推荐答案
这里有多个问题:
- (Reported as GDB bug.) An undefined convenience variable (a GDB-local variable that starts with
$
), when printed with an explicit format specifier, is shown as 0 instead of the defaultvoid
, which is displayed when format is not specified:
$ 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中具有以下名称:
- Register values have the same syntax as the values of convenience variables. Thus, when you mistake the name of a register, e.g. use
r11b
instead of GDB'sr11l
, you refer to a(n undefined) convenience variable. Moreover, even if you simply use the correct name in incorrect case, likeR11L
, you bump into this too. - GDB uses its own set of names for x86(_64) registers. Sometimes they differ from the names given e.g. in Intel manuals (e.g.
ftag
instead of Intel'sFTW
). In any case, the lowest bytes of the general purpose registers have the following names in GDB:
al
cl
dl
bl
spl
bpl
sil
dil
r8l
...
r15l
没有别名,例如 r11b
表示 r11l
,因此必须使用正确的名称。
There are no aliases for them like e.g. r11b
for r11l
, so one must use the correct names.
这篇关于无法设置寄存器x86-64中的最低字节?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!