无法设置寄存器x86-64中的最低字节?

问题描述

我正在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

我很困惑,因为我专门尝试将%dil移到%r11b,但是我仍然无法设置字节。谁能向我解释为什么会这样?谢谢!

解决方法

这里有多个问题:

  1. (报告为GDB bug。)使用显式格式说明符打印时,未定义的convenience variable(以$开头的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) 
  1. 寄存器值与便捷变量的值具有相同的语法。因此,当您错误输入寄存器名称时,例如使用r11b而不是GDB的r11l,则指的是(n个未定义)便捷变量。而且,即使您只是在不正确的情况下使用正确的名称(例如R11L),也会遇到这种情况。
  2. GDB对x86(_64)寄存器使用其自己的名称集。有时它们与给定的名称不同,例如英特尔手册中的内容(例如ftag,而不是英特尔的FTW)。无论如何,通用寄存器的最低字节在GDB中具有以下名称:
al
cl
dl
bl
spl
bpl
sil
dil
r8l
...
r15l

没有别名,例如r11b代表r11l,因此必须使用正确的名称。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...