Stay Hungry.Stay Foolish.
GDB查看C程序编译后的内存地址

因为自己不经常看汇编和调试GDB,所以老是忘记,老了,记忆下降了

#include <stdio.h>
#include <unistd.h>

int
main()
{
   FILE *file = fopen("2.txt", "rb");
   char buf[1024];
   while(fgets(buf, 1024, file)) {
       printf("%s", buf);
   }
   return 0;
}

适用gcc -g编译之后,适用gdb ./a.out载入gdb. 适用disassemble指令可以看到如下的汇编

Dump of assembler code for function main:
   0x00000000004005c6 <+0>: push   rbp
   0x00000000004005c7 <+1>: mov    rbp,rsp
   0x00000000004005ca <+4>: sub    rsp,0x410
   0x00000000004005d1 <+11>:    mov    esi,0x4006c0
   0x00000000004005d6 <+16>:    mov    edi,0x4006c3
   0x00000000004005db <+21>:    call   0x4004c0 <fopen@plt>
   0x00000000004005e0 <+26>:    mov    QWORD PTR [rbp-0x8],rax
=> 0x00000000004005e4 <+30>:    jmp    0x4005ff <main+57>
   0x00000000004005e6 <+32>:    lea    rax,[rbp-0x410]
   0x00000000004005ed <+39>:    mov    rsi,rax
   0x00000000004005f0 <+42>:    mov    edi,0x4006c9
   0x00000000004005f5 <+47>:    mov    eax,0x0
   0x00000000004005fa <+52>:    call   0x400480 <printf@plt>
   0x00000000004005ff <+57>:    mov    rdx,QWORD PTR [rbp-0x8]
   0x0000000000400603 <+61>:    lea    rax,[rbp-0x410]
   0x000000000040060a <+68>:    mov    esi,0x400
   0x000000000040060f <+73>:    mov    rdi,rax
   0x0000000000400612 <+76>:    call   0x4004a0 <fgets@plt>
   0x0000000000400617 <+81>:    test   rax,rax
   0x000000000040061a <+84>:    jne    0x4005e6 <main+32>
   0x000000000040061c <+86>:    mov    eax,0x0
   0x0000000000400621 <+91>:    leave  
   0x0000000000400622 <+92>:    ret    
End of assembler dump.

想要查看fopen的第一个参数内容,也就是edi处的内存地址,可以适用x/20g 0x4006c0指令dump出0x4006c0处的内存数据

0x4006c0:   0x7478742e32006272  0x3b031b0100732500
0x4006d0:   0x0000000500000030  0x0000007cfffffda4
0x4006e0:   0x0000004cfffffe04  0x000000a4fffffefa
0x4006f0:   0x000000c4ffffff64  0x0000010cffffffd4
0x400700:   0x0000000000000014  0x0110780100527a01
0x400710:   0x1007019008070c1b  0x0000001c00000014
0x400720:   0x0000002afffffdb0  0x0000000000000000
0x400730:   0x0000000000000014  0x0110780100527a01
0x400740:   0x0000019008070c1b  0x0000001c00000024
0x400750:   0x00000060fffffd20  0x0f4a180e46100e00

gdb是把内存按照8个字节(可以理解为一个long类型变量)为一个块打印数据,如上图所示,0x4006c0地址的数据就是0x72,应为”rb”是一个字符串,所以内存中是一个char *指针,根据intel处理器的小端序(高位保存到高地址,低位保存到低地址),字符串”rb”的最高位是0x00,在0x4006c2位置,’b’是第二位,保存在0x4006c1, ‘r’是char *的最低位,所以地址是0x4006c0.

自由转载-非商用-非衍生-保持署名(创意共享3.0许可证
评论
2016-12-24 08:59:57

Great works!