取值运算符
1. 取值运算符
取值运算符 – "*"
之前我们认识的*可以做以下几种
乘法运算:a * b
定义指针:int * a
取值运算符: * 后面跟一个指针类型的变量
int* a = (int*)1; //定义一个指针类型的变量a赋值为1
printf("%x \n", *a);
我们在printf下断,如果程序运行起来会抛出异常出错,编译和语法检查没问题,我们看汇编代码
00401090 push ecx
00401091 push 402100h
在printf之前传递了两个参数
402100h是那个%x \n
ecx就是*a
那么也就是
0040108B mov eax,dword ptr [A]
0040108E mov ecx,dword ptr [eax]
把A(ebp-4)这个地址指向的dword长度的值放入eax(是1)
然后eax地址指向的值取出传给ecx
然后ecx压栈,最后输出
取值运算符举例
int x = 1;
int* p = &x;
printf("%x %x \n",p,*(p));
如下汇编
经过如下几步
1、mov dword ptr [ebp-8],1 //把1给变量x(ebp-8)
2、lea eax,[ebp-8] //取ebp-8这个地址给eax
3、mov dword ptr [ebp-0Ch],eax //把eax给ebp-C,也就是p
4、mov ecx,dword ptr [ebp-0Ch] //ebp-c存到ecx
5、mov edx,dword ptr [ecx] //取ecx地址指向的值存入edx
6、push edx //edx,也就是值(1)入栈
7、mov eax,dword ptr [ebp-0Ch] //ebp-c地址放入eax
8、push eax //eax,也就是地址入栈
最后输出了1和变量x的地址
int x = 1;
int* p = &x;
printf("%x %x \n",p,*(p));
//p = (int*)2;
*(p) = 2;
printf("%d \n",x);
看p=2和 * ( p ) =2有何不同?
p=2会直接把地址改为00000002,没分配,抛异常,运行就报错
而 * ( p )=2,会把p指向的那快内存地址的值改变了,也就是x的地址指向的值