const int a = 10;
int* p = (int *)(&a);
*p = 20;
printf("%d %d\n",a,*p);
题目问这个会输出什么?
开始觉得会输出20,20,但是答案错了,于是就开始想为什么,在Linux环境下面的汇编代码看的有点苦涩,在Windows环境下的汇编代码一看便豁然开朗。
int main()
{
00F926F0 push ebp
00F926F1 mov ebp,esp
00F926F3 sub esp,0DCh
00F926F9 push ebx
00F926FA push esi
00F926FB push edi
00F926FC lea edi,[ebp-0DCh]
00F92702 mov ecx,37h
00F92707 mov eax,0CCCCCCCCh
00F9270C rep stos dword ptr es:[edi]
00F9270E mov eax,dword ptr [__security_cookie (0F9C004h)]
00F92713 xor eax,ebp
00F92715 mov dword ptr [ebp-4],eax
const int a = 10;
00F92718 mov dword ptr [a],0Ah
int* p = (int *)(&a);
00F9271F lea eax,[a]
00F92722 mov dword ptr [p],eax
*p = 20;
00F92725 mov eax,dword ptr [p]
*p = 20;
00F92728 mov dword ptr [eax],14h
printf("%d %d\n",a,*p);
00F9272E mov eax,dword ptr [p]
00F92731 mov ecx,dword ptr [eax]
00F92733 push ecx
00F92734 push 0Ah (常量编译器认为不会进行修改于是作了一部优化操作,将10直接入栈,这样做的省去了访问内存的步骤)
00F92736 push offset string "%d %d\n" (0F99C48h)
00F9273B call _printf (0F9141Fh)
00F92740 add esp,0Ch
如下代码将其改成volatile,当需要读取这个变量的时候一定要从内存中读取出来。
volatile const int a = 10;
int* p = (int *)(&a);
*p = 20;
printf("%d %d\n",a,*p);
return 0;
对应的反汇编代码
int main()
{
00B926F0 push ebp
00B926F1 mov ebp,esp
00B926F3 sub esp,0DCh
00B926F9 push ebx
00B926FA push esi
00B926FB push edi
00B926FC lea edi,[ebp-0DCh]
00B92702 mov ecx,37h
00B92707 mov eax,0CCCCCCCCh
00B9270C rep stos dword ptr es:[edi]
00B9270E mov eax,dword ptr [__security_cookie (0B9C004h)]
00B92713 xor eax,ebp
00B92715 mov dword ptr [ebp-4],eax
volatile const int a = 10;
00B92718 mov dword ptr [a],0Ah
int* p = (int *)(&a);
00B9271F lea eax,[a]
00B92722 mov dword ptr [p],eax
*p = 20;
00B92725 mov eax,dword ptr [p]
00B92728 mov dword ptr [eax],14h
printf("%d %d\n",a,*p);
00B9272E mov eax,dword ptr [p]
00B92731 mov ecx,dword ptr [eax]
00B92733 push ecx
00B92734 mov edx,dword ptr [a]
00B92737 push edx
00B92738 push offset string "%d %d\n" (0B99C48h)
00B9273D call _printf (0B9141Fh)
00B92742 add esp,0Ch
return 0;
还是自己不够强