Как напечатать значения регистров в 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.

Другие вопросы по тегам