Как напечатать значения регистров в GDB?
Как мне распечатать значение %eax
а также %ebp
?
(gdb) p $eax
$1 = void
7 ответов
info registers
показывает все регистры; info registers eax
показывает только регистр eax
, Команда может быть сокращена до i r
Если вы пытаетесь напечатать определенный регистр в GDB, вы должны опустить знак%. Например,
info registers eip
Если ваш исполняемый файл 64-битный, регистры начинаются с r. Начиная их с е, недопустимо.
info registers rip
Они могут быть сокращены до:
i r rip
Существует также:
info all-registers
Затем вы можете получить интересующее вас имя регистра - очень полезное для поиска регистров, специфичных для платформы (например, NEON Q... в ARM).
- Если только хотите проверить это один раз,
info registers
показать регистры. - Если только хотите посмотреть один регистр, например,
display $esp
продолжить отображение регистров esp в командной строке GDB. - Если хотите посмотреть все регистры,
layout regs
продолжить показ регистров, в режиме TUI.
GDB команды:
i r <register_name>
: распечатать один регистр, напримерi r rax
,i r eax
i r <register_name_1> <register_name_2> ...
: распечатать несколько регистров, напримерi r rdi rsi
,i r
: вывести все регистры, кроме плавающего и векторного регистров (xmm, ymm, zmm).i r a
: печать всех регистров, включая регистр с плавающей точкой и вектор (xmm, ymm, zmm).i r f
: распечатать все плавающие регистры FPU (st0-7
и несколько другихf*
)
Другие группы регистров, кроме a
(all
) а также f
(float
) можно найти с помощью:
maint print reggroups
как задокументировано по адресу: https://sourceware.org/gdb/current/onlinedocs/gdb/Registers.html
Советы
xmm0
~xmm15
, 128 бит, почти каждая современная машина имеет его, они выпущены в 1999 году.ymm0
~ymm15
, 256 бит, новые машины обычно есть, они выпущены в 2011 году.zmm0
~zmm31
, 512 бит, нормальный компьютер, вероятно, не имеет (как 2016 год), они выпущены в 2013 году и до сих пор используются в основном на серверах.- Будет показан только один серийный номер xmm / ymm / zmm, потому что это разные регистры в разных режимах. На моей машине показывается ymm.
p $eax
работает с GDB 7.7.1
Начиная с GDB 7.7.1, команда, которую вы пробовали, работает:
set $eax = 0
p $eax
# $1 = 0
set $eax = 1
p $eax
# $2 = 1
Этот синтаксис также можно использовать для выбора между различными членами объединения, например, для регистров ARM с плавающей запятой, которые могут быть либо с плавающей запятой, либо с целыми числами:
p $s0.f
p $s0.u
Из документов:
Любое имя, которому предшествует '$', может использоваться для вспомогательной переменной, если только оно не является одним из предварительно определенных машинно-специфических имен регистров.
и:
Вы можете ссылаться на содержимое регистра машины в выражениях как на переменные с именами, начинающимися с '$'. Имена регистров различны для каждой машины; используйте информационные регистры, чтобы увидеть имена, используемые на вашем компьютере.
Но мне пока не повезло с регистрами управления: OSDev 2012 http://f.osdev.org/viewtopic.php?f=1&t=25968 || Запрос функции 2005 года https://www.sourceware.org/ml/gdb/2005-03/msg00158.html || alt.lang.asm 2013 https://groups.google.com/forum/
Для меня проще всего:
(gdb) x/x $eax
Первый обозначает e x амин, а второй
x
шестнадцатеричный. Вы можете увидеть другие форматы, используя:
(gdb) help x
Вы можете легко распечатать строки с помощью
x/s $eax
или возвращать адреса с
x/a $ebp+4
.