指针学习
来源:互联网 发布:淡雅女士香水知乎 编辑:程序博客网 时间:2024/06/10 08:00
PS:话说当时脑浊,学不明白指针,还因幻想Java没有指针而欣喜一番,后来发现这种不明不白的太难受了,还是认真啃掉这块硬骨头吧,此文就是当时为了理解指针,从汇编的角度去学习的一个过程。
#include <stdio.h>int main(){ int count, num; //定义两个整型变量count和num int *pointer; //一个整形指针pointer count = 10; pointer = &count; //把count的内存地址赋给pointer,“&”是C语中的地址运算符,用于取内存地址 num = *pointer; //用*获得指针指向的内容,即 num = 10 return 0;}
这时num的值就是10,可以加句printf("%d \n", num);看到。进调试器解释,编译环境VC6.0,调试器是VC6.0默认的调试器。
先在int count = 10;处下断点(右键--Insert/Remove Breakpoint),然后按F5,进入调试状态后,会自动在断点处停下来,此时点在断点行处右键--Go To Disassembly,来到汇编窗口。
这个时候断点处的代码如下:mov dword ptr [ebp-4],0Ah
0x0A是10的16进制,ebp-4是第一个变量count的地址,mov是传送指令。此句的意思是把10赋值给ebp-4,即count = 10。按一下F10单步运行,然后打开Watch窗口,在名称里键入&count,就看到了count的地址。
在这里顺便说下,定义了三个变量,分别是count、num和pointer,那么分别对应的地址是ebp-4、ebp-8、ebp-0Ch,因为整型变量占4字节内存,每次ebp都会减少4。
根据刚才代码中的顺序,下一句是pointer = &count;,将pointer指向count的内存地址。对应的汇编代码为:
lea eax,[ebp-4]mov dword ptr [ebp-0Ch],eax
前面提到,ebp-4是count变量的内存地址,为了直观点,把上面的汇编代码改一下:
lea eax,[count]mov dword ptr [pointer],eax
ea指令就是把一个内存变量有效的地址传送给指定的寄存器。
第一句lea eax,[ebp-4]是把count的地址传到eax寄存器,根据刚才在Watch窗口中看到的count地址是0012ff7c,那么eax里面的值 就是0012ff7c。第二句mov dword ptr [ebp-0Ch],eax是把eax中的值传到ebp-0Ch(pointer)中。
很明显,pointer = &count;这句代码就等同于pointer = 0012ff7c;。
为了直观点,打开Registers窗口,观察寄存器。按三下F10执行三次单步运行,执行完mov dword ptr [ebp-0Ch],eax指令,这个时候寄存器内容如图:
看EAX的值正好是count变量的内存地址0012FF7C。然后在Watch窗口中输入pointer,可以看到pointer的内容是0x0012ff7c,如图:
说明pointer已经指到了count的内存地址了。接下来看下一句代码lx = *pointer;,对应的汇编代码如下:
mov ecx,dword ptr [ebp-0Ch]mov edx,dword ptr [ecx]mov dword ptr [ebp-8],edx
为了直观,我改一下代码:
mov ecx,dword ptr [pointer]mov edx,dword ptr [ecx]mov dword ptr [lx],edx
这行代码意思是取出pointer指向的内容赋给变量num。
汇编代第一句mov ecx,dword ptr [ebp-0Ch]意思是把ebp-0Ch(pointer)中的值传入到ecx寄存器中,pointer的内容是0x0012ff7c, 那么这个时候ecx的值就是0x0012ff7c。
第二句mov edx,dword ptr [ecx]意思是取出ecx寄存器中的地址对应的值放入edx寄存器,此时edx寄存器的值就是count的值10了。最后再mov dword ptr [ebp-8],edx,把edx寄存器中的值传到变量num中。
为了观察到整个过程,单步运行,直到运行完mov edx,dword ptr [ecx]这句指令,然后观察Registers窗口,看到ECX的值是0012FF7C。ECX的值已经是count的内存地址了:
再单步运行一次,运行完指令mov edx,dword ptr [ecx],再看Registers窗口,EDX的值是0000000A,A是10的十六进制表示。
简单总结下,首先将变量的地址放入寄存器中,然后再取出寄存器中存放地址对应的值。
C指针就这样,自己跟着调试一次代码,就能够理解了。
- 学习指针
- 指针学习
- 指针学习
- 指针学习
- 指针学习
- 指针学习
- 指针学习
- 指针学习
- 指针学习
- 指针学习
- 指针学习
- 指针学习
- 指针学习
- 指针学习
- 指针学习
- 指针学习
- 指针学习
- 指针学习
- CSS样式1
- 一些特殊HTML显示格式
- sock_ev——linux平台socket事件框架(基于数据报的测试程序)
- 坚持、努力——记录一下acm破百
- 项目自动化之道-5.安装与部署之诊断测试
- 指针学习
- 光线追踪(RayTracing)算法理论与实践(三)光照
- php试题与答案(二)
- libc.so.6: not found
- 判断输入的日期是一年中第几天(调用函数)
- 虚拟机VMware3种网络模式(桥接、nat、Host-only)的工作原理
- android SIM卡状态
- Android控件拖动
- 【基础知识】使用Darts