- /*
- C/C++中规定,在变量前加const修饰符是将变量定义为常量,其值是不能修改的
- 但这个不能修改也只是针对编译器而言
- */
- #include <stdio h="">
- int main()
- {
- const int a = 2;
- int *b,i = 0;
- printf("%d\n",a);
- b = (int*)&a;//强制转换一下,让编译通过
- *b = 10;
- __asm
- {
- push eax
- mov eax,a//把变量a的值给寄存器EAX(上边已经用*b=10改变了a的值了)
- mov i,eax//再把寄存器EAX的值给i
- pop eax
- }
- printf("a:%d\n",a);//有使用a的地方全被改成push 2了,而并没有去a的内存空间取值
- printf("*b:%d\n",*b);
- printf("i:%d\n",i);//其实a的内存空间的数值是被改变掉的
- //只是编译做了手脚,将有a出现的地方全改成a刚开始的值了
- return 0;
- }//VC6.0编译通过
- /*以下是VC6.0调试的汇编代码*/
- 1: /*
- 2: C/C++中规定,在变量前加const修饰符是将变量定义为常量,其值是不能修改的
- 3:
- 4: 但这个不能修改也只是针对编译器而言
- 5: */
- 6: #include <stdio.h>
- 7:
- 8: int main()
- 9: {
- 0040D720 55 push ebp
- 0040D721 8B EC mov ebp,esp
- 0040D723 83 EC 4C sub esp,4Ch
- 0040D726 53 push ebx
- 0040D727 56 push esi
- 0040D728 57 push edi
- 0040D729 8D 7D B4 lea edi,[ebp-4Ch]
- 0040D72C B9 13 00 00 00 mov ecx,13h
- 0040D731 B8 CC CC CC CC mov eax,0CCCCCCCCh
- 0040D736 F3 AB rep stos dword ptr [edi]
- 10: const int a = 2;
- 0040D738 C7 45 FC 02 00 00 00 mov dword ptr [ebp-4],2
- 11: int *b,i = 0;
- 0040D73F C7 45 F4 00 00 00 00 mov dword ptr [ebp-0Ch],0
- 12: printf("%d\n",a);
- 0040D746 6A 02 push 2 /*是直接将2压入堆栈,并不是去取a的值*/
- 0040D748 68 1C 20 42 00 push offset string "%d/n" (0042201c)
- 0040D74D E8 3E 39 FF FF call printf (00401090)
- 0040D752 83 C4 08 add esp,8
- 13: b = (int*)&a;//强制转换一下,让编译通过
- 0040D755 8D 45 FC lea eax,[ebp-4]
- 0040D758 89 45 F8 mov dword ptr [ebp-8],eax
- 14: *b = 10;
- 0040D75B 8B 4D F8 mov ecx,dword ptr [ebp-8]
- 0040D75E C7 01 0A 00 00 00 mov dword ptr [ecx],0Ah
- 15: __asm
- 16: {
- 17: push eax
- 0040D764 50 push eax
- 18: mov eax,a
- 0040D765 8B 45 FC mov eax,dword ptr [ebp-4]
- 19: mov i,eax
- 0040D768 89 45 F4 mov dword ptr [ebp-0Ch],eax
- 20: pop eax
- 0040D76B 58 pop eax
- 21: }
- 22: printf("a:%d\n",a);//有使用a的地方全被改成push 2了,而并没有去a的内存空间取值
- 0040D76C 6A 02 push 2 /*第二次使用到a,还是直接将定义时的值给压入堆栈*/
- 0040D76E 68 B4 2F 42 00 push offset string "a:%d/n" (00422fb4)
- 0040D773 E8 18 39 FF FF call printf (00401090)
- 0040D778 83 C4 08 add esp,8
- 23: printf("*b:%d\n",*b);
- 0040D77B 8B 55 F8 mov edx,dword ptr [ebp-8]
- 0040D77E 8B 02 mov eax,dword ptr [edx] /*取a的内存空间的值*/
- 0040D780 50 push eax /*再压入堆栈*/
- 0040D781 68 AC 2F 42 00 push offset string "*b:%d\n" (00422fac)
- 0040D786 E8 05 39 FF FF call printf (00401090)
- 0040D78B 83 C4 08 add esp,8
- 24: printf("i:%d\n",i);//其实a的内存空间的数值是被改变掉的
- 0040D78E 8B 4D F4 mov ecx,dword ptr [ebp-0Ch]
- 0040D791 51 push ecx
- 0040D792 68 A4 2F 42 00 push offset string "i:%d/n" (00422fa4)
- 0040D797 E8 F4 38 FF FF call printf (00401090)
- 0040D79C 83 C4 08 add esp,8
- 25: //只是编译做了手脚,将有a出现的地方全改成a刚开始的值了
- 26: return 0;
- 0040D79F 33 C0 xor eax,eax
- 27: }//VC6.0编译通过
- 0040D7A1 5F pop edi
- 0040D7A2 5E pop esi
- 0040D7A3 5B pop ebx
- 0040D7A4 83 C4 4C add esp,4Ch
- 0040D7A7 3B EC cmp ebp,esp
- 0040D7A9 E8 62 39 FF FF call __chkesp (00401110)
- 0040D7AE 8B E5 mov esp,ebp
- 0040D7B0 5D pop ebp
- 0040D7B1 C3 ret
- /*
- 总结,const修饰的变量是由编译在编译连接阶段进行检测的,检测到有代码段修改了其值就会提示语法错误
- 而且每次使用该变量的值时,不是去内存空间去取,而是由编译直接将其值拿来参于编译连接
- */