一、C程序
现有C程序如下:
int main(void) {
int a = 1; // 定义变量a,值为1
int *p = &a; // 定义指针p,指向a
return 0;
}
二、对应的汇编代码
以上C程序中的第2行、第3行对应的汇编代码如下(每行右边有参考注释):
mov DWORD PTR [rbp-0xc],0x1 ; 把数字1存放到内存单元[rbx-0xc]处,占4个字节
lea rax,[rbp-0xc] ; 内存单元[rbx-0xc]的地址存入rax寄存器
mov QWORD PTR [rbp-0x8],rax ; 把rax寄存器中的值存放到内存单元[rbp-0x8]处,占8个字节
C程序中的 int a = 1;
对应汇编代码中的第1行。
C程序中的 int *p = &a;
对应汇编代码中的第2、第3行。
三、内存布局
内存布局如下:
变量 | 变量地址 | 内存地址 | 内存值 |
---|---|---|---|
p | &p | 0x61fe18 | 0x61fe14 |
a | &a | 0x61fe14 | 0x01 |
四、p
、*p
、&p
的区别
p
、*p
、&p
的值如下:
说明:
p
是指向变量a
的指针。
p
的值是变量a
的地址。
*p
的作用是访问指针所指向的对象(这是一个动作),即访问变量a
。
*p
的值是指针所指向的对象的值(这是动作的结果),即变量a
的值,也就是1。
&p
的作用是获取指针p
的地址(这是一个动作)。指针是一种特殊的变量,因此也可以说&p
的作用是获取变量p
的地址。
&p
的值是指针变量p
的地址(这是动作的结果)。
五、指针的定义
按照《C程序设计语言(K&R)第2版》书中的定义:“指针是能够存放一个地址的一组存储单元”。这个定义其实就是从内存的角度出发的。
对应于本例中,指针p
就是下图红框中的那8个字节的存储单元,8个存储单元的起始地址是00x000000000061fe18
(简写0x61fe18
),存储单元中存储的内容是0x000000000061fe14
(简写0x61fe14
),即变量a
的地址。
六、个人记忆方法
以下为我个人的记忆方法,供参考。
a
:变量。或:所指变量。
p
:指针变量。或:所指变量的地址。
*p
:所指变量的值。
&p
:指针变量本身的地址。
强调一下,谈到指针
时,脑海里就要反应过来它存放的值是另一个变量的地址:指针就是地址,指针就是地址,指针就是地址。