00401041 mov eax,0CCCCCCCCh
00401046 rep stos dword ptr [edi]
12: ((apple*)(0))->print();
00401048 xor ecx,ecx
0040104A call @ILT+0(apple::print) (00401005)
13: }
0040104F pop edi
00401050 pop esi
00401051 pop ebx
00401052 add esp,40h
00401055 cmp ebp,esp
00401057 call __chkesp (004010e0)
0040105C mov esp,ebp
0040105E pop ebp
0040105F ret
通过运行函数,我们发现没有任何异常产生,为什么呢?因为我们发现ecx是作为0传给print函数的,也就是我们熟悉的this指针为0。但是我们发现在print函数内部没有用到this指针,因为我们根本没有对this->value进行访问,只是一个返回语句return。这说明指针作为class null指针并不可怕,可怕的是用null去访问内存中的数据。
(4)int m = 1; int n = m++ + ++m; 那么n是多少呢?
10: void process()
11: {
0040D4D0 push ebp
0040D4D1 mov ebp,esp
0040D4D3 sub esp,48h
0040D4D6 push ebx
0040D4D7 push esi
0040D4D8 push edi
0040D4D9 lea edi,[ebp-48h]
0040D4DC mov ecx,12h
0040D4E1 mov eax,0CCCCCCCCh
0040D4E6 rep stos dword ptr [edi]
12: int m = 1;
0040D4E8 mov dword ptr [ebp-4],1
13: int n = m++ + ++m;
0040D4EF mov eax,dword ptr [ebp-4]
0040D4F2 add eax,1
0040D4F5 mov dword ptr [ebp-4],eax
0040D4F8 mov ecx,dword ptr [ebp-4]
0040D4FB add ecx,dword ptr [ebp-4]
0040D4FE mov dword ptr [ebp-8],ecx
0040D501 mov edx,dword ptr [ebp-4]
0040D504 add edx,1
0040D507 mov dword ptr [ebp-4],edx
14: }
0040D50A pop edi
0040D50B pop esi
0040D50C pop ebx
0040D50D mov esp,ebp
0040D50F pop ebp
通过汇编代码,我们看到【ebp-4】就是m在堆栈中的地址,【ebp-8】就是n在堆栈中的地址。int n = m++ + ++m下面总共有9句汇编。我们可以分析一下:前面三句表示m自己增加1,第四句表示ecx = m,即ecx = 2。第五句ecx和m相加,翻译过来就是ecx = ecx + m。此时ecx = 4。第六句表示n = ecx。 第七句到第九句表示m自增加1。为什么会出现这样的情况呢,其实道理很简单,主要是因为我们的表达式是从右向左运算的。如果大家这样看就明白了,首先++m,然后n = m + m,最后m++。
(5)*p++和(*p)++区别是什么
10: void process()
11: {
0040D4D0 push ebp
0040D4D1 mov ebp,esp
0040D4D3 sub esp,48h
0040D4D6 push ebx
0040D4D7 push esi
0040D4D8 push edi
0040D4D9 lea edi,[ebp-48h]
0040D4DC mov ecx,12h
0040D4E1 mov eax,0CCCCCCCCh
0040D4E6 rep stos dword ptr [edi]
12: char data = 'a';
0040D4E8 mov byte ptr [ebp-4],61h
13: char* p = & data;
0040D4EC lea eax,[ebp-4]
0040D4EF mov dword ptr [ebp-8],eax
14: *p++;
0040D4F2 mov ecx,dword ptr [ebp-8]
0040D4F5 add ecx,1
0040D4F8 mov dword ptr [ebp-8],ecx
15: (*p)++;
0040D4FB mov edx,dword ptr [ebp-8]
0040D4FE mov al,byte ptr [edx]
0040D500 add al,1
0040D502 mov ecx,dword ptr [ebp-8]
0040D505 mov byte ptr [ecx],al
16: }
0040D507 pop edi
0040D508 pop esi
0040D509 pop ebx
0040D50A mov esp,ebp
0040D50C pop ebp
0040D50D ret
我们首先创建局部变量data。然后把data的指针复制给p。从汇编代码可以清楚的看出来:*p++就等于p++;(*p)++首先把指针复制给edx,然后获取edx地址指向的char数据复制给al,al自增加1,同时p地址复制给ecx,al复制给ecx指向的地址,就是这么简单。
类似的问题还有很多,大家不妨自己试一试: