因为自己不经常看汇编和调试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.
评论
Great works!