rbp: 0x7fffffffdd00
rbp-14: 0x7fffffffdcf2
C语言代码:
int *p=(int *)0x7fffffffdcf0;
rax(保存了0x7fffffffdcf2): 0x7fffffffdcec *0x7fffffffdcec=5
0x7fffffffdcec就是rbp -14的值, 0x14
0x7fffffffdcf2是rbp-14 14是10进制
注意: gdb print $rbp-14是10进制, 而汇编代码是0x14
rax:0x7fffffffdcec
rbp - 0x14: 0x7fffffffdcec
rbp -0x10: 0x7fffffffdcf0
C语言代码:
int *p=(int *)0x7fffffffdcf0;
反汇编代码:
Dump of assembler code for function main:
0x00000000004004d6 <+0>: push %rbp
0x00000000004004d7 <+1>: mov %rsp,%rbp
0x00000000004004da <+4>: movabs $0x7fffffffdcf0,%rax
0x00000000004004e4 <+14>: mov %rax,-0x8(%rbp)
=> 0x00000000004004e8 <+18>: mov $0x0,%eax
0x00000000004004ed <+23>: pop %rbp
0x00000000004004ee <+24>: retq
End of assembler dump.
(gdb) print /x $rax
$48 = 0x7fffffffdcf0
(gdb) print $rbp-0x8
$32 = (void *) 0x7fffffffdcf8
问题: 为什么print $rbp-0x8之后,是0x7fffffffdcf8???
$rax 之类的不是输出寄存器的值么, 为啥不是0x7fffffffdcf0???
(
(gdb) print /x *0x7fffffffdcf8
$46 = 0xffffdcf0 #rbp-0x8只保留了0x7fffffffdcf0的低八位
(gdb) print $rax
为啥只保留了低八位??
再看下一个案例
0x0000000000400546 <+0>: push %rbp
0x0000000000400547 <+1>: mov %rsp,%rbp
0x000000000040054a <+4>: sub $0x20,%rsp
0x000000000040054e <+8>: mov %fs:0x28,%rax
0x0000000000400557 <+17>: mov %rax,-0x8(%rbp)
=> 0x000000000040055b <+21>: xor %eax,%eax
0x000000000040055d <+23>: movl $0x5,-0x14(%rbp)
0x0000000000400564 <+30>: lea -0x14(%rbp),%rax
0x0000000000400568 <+34>: mov %rax,-0x10(%rbp)
0x000000000040056c <+38>: mov $0x0,%eax
0x0000000000400571 <+43>: mov -0x8(%rbp),%rdx
0x0000000000400575 <+47>: xor %fs:0x28,%rdx
0x000000000040057e <+56>: je 0x400585 <main+63>
0x0000000000400580 <+58>: callq 0x400420 <__stack_chk_fail@plt>
0x0000000000400585 <+63>: leaveq
0x0000000000400586 <+64>: retq
End of assembler dump.
(gdb) print /x $rax
$11 = 0xa28c803b6e299900 #这是原来的地址
(gdb) print $rbp-0x8
$12 = (void *) 0x7fffffffdcf8
(gdb) print /x *0x7fffffffdcf8
$14 = 0x6e299900 #这是被截断的剩下的32位地址
这两个的共同点都是被截断了高32位, 只传送了低32位, 并且都使用了mov指令,
奇怪的是CSAPP并没有介绍mov指令, 它介绍了movb, movw, movl, movq这四种,
(gdb) disas
Dump of assembler code for function main:
0x0000000000400546 <+0>: push %rbp
0x0000000000400547 <+1>: mov %rsp,%rbp
0x000000000040054a <+4>: sub $0x20,%rsp
0x000000000040054e <+8>: mov %fs:0x28,%rax
0x0000000000400557 <+17>: mov %rax,-0x8(%rbp)
0x000000000040055b <+21>: xor %eax,%eax
0x000000000040055d <+23>: movl $0x5,-0x14(%rbp)
=> 0x0000000000400564 <+30>: lea -0x14(%rbp),%rax
0x0000000000400568 <+34>: mov %rax,-0x10(%rbp)
0x000000000040056c <+38>: mov $0x0,%eax
0x0000000000400571 <+43>: mov -0x8(%rbp),%rdx
0x0000000000400575 <+47>: xor %fs:0x28,%rdx
0x000000000040057e <+56>: je 0x400585 <main+63>
0x0000000000400580 <+58>: callq 0x400420 <__stack_chk_fail@plt>
0x0000000000400585 <+63>: leaveq
0x0000000000400586 <+64>: retq
End of assembler dump.
(gdb) print /x $rbp-0x14
$15 = 0x7fffffffdcec
(gdb) print *0x7fffffffdcec 这是rbp-0x14保存的地址
0x0000000000400564 in main ()
(gdb) print *0x7fffffffdcec
$17 = 5
=================================================================
Dump of assembler code for function main:
0x0000000000400546 <+0>: push %rbp
0x0000000000400547 <+1>: mov %rsp,%rbp
0x000000000040054a <+4>: sub $0x20,%rsp
0x000000000040054e <+8>: mov %fs:0x28,%rax
0x0000000000400557 <+17>: mov %rax,-0x8(%rbp)
0x000000000040055b <+21>: xor %eax,%eax
0x000000000040055d <+23>: movl $0x5,-0x14(%rbp)
0x0000000000400564 <+30>: lea -0x14(%rbp),%rax
=> 0x0000000000400568 <+34>: mov %rax,-0x10(%rbp)
0x000000000040056c <+38>: mov $0x0,%eax
0x0000000000400571 <+43>: mov -0x8(%rbp),%rdx
0x0000000000400575 <+47>: xor %fs:0x28,%rdx
0x000000000040057e <+56>: je 0x400585 <main+63>
0x0000000000400580 <+58>: callq 0x400420 <__stack_chk_fail@plt>
(gdb) print $rax
$18 = 140737488346348
(gdb) print /x $rax
$19 = 0x7fffffffdcec //#传地址成功, 和rbp-0x14 保存的地址相同功能, rax保存了rbp-0x14传来的地址
(gdb) print *0x7fffffffdcec //#传地址成功, rax保存了rbp-0x14传来的地址
$20 = 5 //间接访问此地址空间, 这个空间里保存着一个数值5
========================================
(gdb) disas
Dump of assembler code for function main:
0x0000000000400546 <+0>: push %rbp
0x0000000000400547 <+1>: mov %rsp,%rbp
0x000000000040054a <+4>: sub $0x20,%rsp
0x000000000040054e <+8>: mov %fs:0x28,%rax
0x0000000000400557 <+17>: mov %rax,-0x8(%rbp)
0x000000000040055b <+21>: xor %eax,%eax
0x000000000040055d <+23>: movl $0x5,-0x14(%rbp)
0x0000000000400564 <+30>: lea -0x14(%rbp),%rax
0x0000000000400568 <+34>: mov %rax,-0x10(%rbp)
=> 0x000000000040056c <+38>: mov $0x0,%eax
0x0000000000400571 <+43>: mov -0x8(%rbp),%rdx
0x0000000000400575 <+47>: xor %fs:0x28,%rdx
0x000000000040057e <+56>: je 0x400585 <main+63>
0x0000000000400580 <+58>: callq 0x400420 <__stack_chk_fail@plt>
0x0000000000400585 <+63>: leaveq
0x0000000000400586 <+64>: retq
End of assembler dump.
(gdb)
(gdb) print $rbp-0x10
$21 = (void *) 0x7fffffffdcf0
(gdb) print *0x7fffffffdcf0
$22 = -8980
(gdb) print /x *0x7fffffffdcf0
$23 = 0xffffdcec ###坑点又出现了, rbp-0x10指向的空间, 又只保存了rax里的地址(0x7fffffffdcec)的低32位,
--------------------------------------------------------------------------
结论, 在64位系统中, mov指令就是将源操作数的低32位传送给目的操作数
.....未完待续.....