0x01:毕竟学Linux就要学会gdb调试C语言啦,这里我们来看看指针在内存里到底是长什么样子的,毕竟眼见为实,不多说来调试看看吧;
0x02:代码如下所示
#include <stdio.h>
int main()
{
char a = 'c';
char *p = &a;
char **ptr = &p;
return 0;
}
gcc -g -o test test.c --> 生成调试文件
gdb ./test --> 启动gdb调试
show disassembly-flavor --> 查看gdb反汇编的格式,gdb默认为AT&T
set disassembly-flavor intel -->设置为intel汇编格式
disassemble main --> 主函数进行反汇编操作
我们一起来看看反汇编的代码,其中红色框中汇编代码是做栈溢出的保护机制,将0x28压入[rbp-0x8]所对应的地址,后续再检测是否有发生栈溢出;然后再看main()函数所对应的反汇编代码,xor eax,eax将寄存器清零,再将0x63的值写入[rbp-0x19]所对应的内存地址,0x63就是字母’c’所对应的ASCII码值,lea rax, [rbp-0x19],取[rbp-0x19]的内存地址存入寄存器rax,然后再将rax的值存入[rbp-0x18]所对应的内存地址,再取[rbp-0x18]的地址给rax,然后再将rax值存入[rbp-0x10]所对应的内存地址,由此可见*p的值存的是一个QWORD类型,占8个字节;
从汇编代码中我们可以看到,数据存放在[rbp-0x19]所对应的内存地址,使用命令 x/24xb $rbp-0x19查看内存中的信息,我们定义了一个字符变量a,那么在内存中占一个字节,而p和ptr存放的是地址信息,这里是64位的操作系统,占8个字节QWORD,这里的数据是以小端的方式存储数据,所以从0x63后开始,存储的就是p和ptr所对应的地址,0x7fffffffde87和0x7fffffffde88,这又是为什么呢?因为我们定义的是char型的数据,都是占一个字节;