2014-10-02 107 views
1

所以我只是试图在这个简单的程序中用gdb访问eax(Assembly newbie)无法从GDB访问x86-64中的32位寄存器

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位寄存器?

+2

尝试'p $ rbp'和'p $ eax'来代替...(并且执行“help x”和“help p”来了解这些命令之间的差异) – Nemo 2014-10-02 03:48:11

回答

3

x命令代表examine。它接受一个指针作为输入并显示那里的内容。您正在查找print命令或p,该命令输出参数的值。

p $eax 

通过做x $rbp,你实际上看着什么在堆栈上。看起来rbp在你的例子中包含地址0x7fffffffe620

您得到的错误消息x $eax表示eax的值为3,并且由于这不是有效的指针,所以它会显示错误消息。

+0

嗨,谢谢你的回应。因此,如果x接受一个指针作为输入,为什么我会输入'x $ eax'和'x $ rax'之间会有什么区别?我可以访问$ rax,但是我无法访问$ eax,并且我会假设它们都是指针,或者都是非指针。 – user49404 2014-10-02 03:54:22

+0

您没有显示'$ rax',但我会假设'$ rax'的高位使它成为一个有效的指针,而低位本身并不指向任何有用的位置。通过执行'x $ eax',你丢弃了地址的上半部分(假设它是一个地址)。 – zneak 2014-10-02 04:00:28

+0

换句话说,你不能假设'eax'是'rax'的基础上的有效指针,因为'eax'只不过是'rax'的低32位。它是指针大小的一半。举一个更明显的例子,'al'是'rax'的低8位,但是你(可能)不会把它当作指针。 – zneak 2014-10-02 04:09:07

-1

chutiye ...负正负的价值是什么。那许多位,你需要添加内存....

** 0x000000000040049d < + 1>:MOV%RSP,RBP%

0x00000000004004a0 < +4>:MOVL $ 0x1,则-0x4(%RBP)

0x00000000004004a7 < +11>:MOVL $ 0x3,错误就在这里,因为你不能直接添加一个字符串下一存储指令0x8中(%rbp)**

+0

您试图将内存中字符串的值乘以8位.... – ciph3r 2016-11-18 12:46:34

+0

看起来像正常的AT&T语法从'gcc -O0'给我的未优化的编译器输出。您展示的任何说明中没有任何字符串或附加内容。 – 2016-11-19 00:54:24