C 语言指针反汇编代码阅读

mac2024-10-31  12

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位传送给目的操作数 .....未完待续.....

 

最新回复(0)