如何更改GDB中的eflags寄存器值?

时间:2013-03-15 18:56:37

标签: debugging assembly gdb flags

set $eflags不会更改eflags值。

旧的eflags值在例如之后仍然存在。 =>$set $eflag=0x243 [这只是一个示例输入]。

或者,有没有办法设置eflags的个别标志?

我正在寻找类似:set ZF[zero flag]的东西。是否有gdb命令来执行此操作?

4 个答案:

答案 0 :(得分:15)

没有括号的

set $eflags适用于GDB 7.7.1

要设置单个标志,请使用其索引。例如,ZF是第6位,所以我们可以设置它:

set $ZF = 6                 # define a GDB variable: no effect on registers
set $eflags |= (1 << $ZF)   # set bit 6 in EFLAGS, the ZF bit.

所有其他按位操作也是如此:How do you set, clear, and toggle a single bit?

# Clear
set $eflags &= ~(1 << $ZF)

# Toggle
set $eflags ^= (1 << $ZF)

导致混淆的原因是许多位要么被保留,要么不能被任何指令直接修改,要么无法从用户模式修改,请参阅:How to read and write x86 flags registers directly?因此GDB不会触及它们。

例如:

(gdb) set $eflags = 0
(gdb) i r eflags
eflags         0x202    [ IF ]
(gdb) set $eflags = 0xFFFFFFFF
(gdb) i r eflags
eflags         0x54fd7  [ CF PF AF ZF SF TF IF DF OF NT RF AC ]
二进制文件中的

0x202是:

0010 0000 0010
二进制文件中的

0x54fd7是:

0101  0100 1111 1101 0111

通过查看手册http://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-vol-1-manual.pdf和GDB源代码,TODO理解为什么每个位都已设置。

我理解的那些:

  • 所有保留的寄存器都保留其固定值:1表示第1位,0表示第3,5,15和22-31位

答案 1 :(得分:6)

set ($eflags)=0x243

在我的测试中使用任何十六进制值。

答案 2 :(得分:0)

eflags [ ZF ]

如果你想设置任意值,请使用此

eflags 0x42

答案 3 :(得分:0)

eflags寄存器中设置所有标志是错误的。所以有些位保留,必须为0.(3,5,15,22和更高)位1必须为1.还有rflags。但所有hi dword都为零。因此,对于所有操作已更改标志,无需使用rflags而不是eflags。但我知道人们使用免费比特自己使用。

更合适rflags hi dword。所以在64位架构中有足够的免费寄存器可供使用。但在32位架构中,没有。所以强烈建议这样做。

因为在未来的架构中,可能会使用其中一些位。但是,从32位更改为64位不会触及这些标志。如果唯一的寄存器可能根本没有改变。因此,任何案例的所有可能原因都已使用过。我不认为任何情况可能会使用一些额外的标志,直到现在才使用。它可能是某些基本处理器架构的变化。我不认为有些人决定这样做是因为显而易见的原因所有软件都必须从一开始就被抛弃并重写。这是非常艰苦和巨大的工作。