【问题标题】:(Assembly newbie) Unable to access 32-bit registers in x86-64 from GDB(汇编新手)无法从 GDB 访问 x86-64 中的 32 位寄存器
【发布时间】:2014-10-02 03:46:07
【问题描述】:

所以我只是想在这个简单的程序中使用 gdb 访问eax

C 代码:

int main(){
    int a = 1;
    int b = 3;
    int c = a + b;
    return 1;
 }

这是我的 gdb 尝试:

(gdb) disas 
Dump of assembler code for function main:
0x000000000040049c <+0>: push   %rbp
0x000000000040049d <+1>: mov    %rsp,%rbp
0x00000000004004a0 <+4>: movl   $0x1,-0x4(%rbp)
0x00000000004004a7 <+11>:    movl   $0x3,-0x8(%rbp)
0x00000000004004ae <+18>:    mov    -0x8(%rbp),%eax
0x00000000004004b1 <+21>:    mov    -0x4(%rbp),%edx
=>  0x00000000004004b4 <+24>:    add    %edx,%eax
0x00000000004004b6 <+26>:    mov    %eax,-0xc(%rbp)
0x00000000004004b9 <+29>:    pop    %rbp
0x00000000004004ba <+30>:    retq 
End of assembler dump.

(gdb) x $rbp
0x7fffffffe620: 0x00000000
(gdb) x $rbp-4
0x7fffffffe61c: 0x00000001
(gdb) x $rbp-8
0x7fffffffe618: 0x00000003
(gdb) x $eax
0x3:    Cannot access memory at address 0x3

所以你可以看到,我使用x $rbp 访问rbp 没有问题,但是我无法访问eax

在 64 位系统上,我需要打开一些设置才能从 gdb 访问 32 位寄存器吗?

【问题讨论】:

  • 改用p $rbpp $eax...(并执行“help x”和“help p”来了解这些命令之间的区别)

标签: assembly gdb x86-64


【解决方案1】:

x 命令代表examine。它接受一个指针作为输入并显示那里有什么。您正在寻找 print 命令或 p,它会打印其参数的值。

p $eax

通过x $rbp,您实际上是在查看堆栈中的内容。在您的示例中,rbp 似乎包含地址 0x7fffffffe620

您在执行x $eax 时收到的错误消息表明eax 的值为3,由于这不是一个有效的指针,它会向您显示一条错误消息。

【讨论】:

  • 您好,感谢您的回复。因此,如果 x 接受一个指针作为输入,为什么我键入 'x $eax' 和 'x $rax' 会发生什么不同?我可以很好地访问 $rax,但我不能访问 $eax,我会假设它们要么都是指针,要么都不是指针。
  • 您没有显示$rax,但我认为$rax 的高位使其成为有效指针,而低位本身并不指向任何有用的地方。通过执行x $eax,您将丢弃地址的上半部分(假设它是一个地址)。
  • 也就是说,你不能在rax的基础上假设eax是一个有效的指针,因为eax只不过是rax的低32位.它是指针大小的一半。举个更明显的例子,alrax 的低 8 位,但您(可能)不会将其视为指针。
  • 啊啊,好吧。因为我在 64 位平台上,所以内存地址是 64 位的,需要一个 64 位的指针来指向它们。因此,因为 rax 是 64 位,它可以用作指针,而 eax 是它的右 32 位,它不能。凉爽的。谢谢!
【解决方案2】:

chutiye...减加减值是多少..你需要添加到内存中的那么多......

** 0x000000000040049d : mov %rsp,%rbp

0x00000000004004a0 : movl $0x1,-0x4(%rbp)

0x00000000004004a7 : movl $0x3, error is here cos you can't add a string directly to the next memory instruction-0x8(%rbp)**

【讨论】:

  • 您正试图将内存中字符串的值乘以 8 位......
  • 在我看来,gcc -O0 的正常 AT&T 语法未经优化的编译器输出。您显示的任何说明中都没有字符串或添加内容。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-05-31
  • 2021-07-05
  • 1970-01-01
  • 2011-11-04
  • 2017-10-20
  • 2014-01-05
  • 1970-01-01
相关资源
最近更新 更多