在给出答案之前我们先C语言编写一个程序来研究一下编译器如何对待那些没有被赋初值的变量
#include <stdio.h>
int main(void)
{
int variable,variable_1;
printf("values = %d x = %d y = %d\n",variable,variable_1);
return 0;
}
运行结果如下:
variable = -858993460 variable_1 = -858993460
为什么会是这这个,这个值从哪里来的呢?我们带着疑问进一步研究
这里用到vc++6.0的调试器,你们用其他IDE也可以(前提是必须有debug查看汇编功能)
光标移到按下F9 int variable,variable_1;会出现一个红点表示下断点成功,程序运行到这一句就会被断下
接下来按F5开始调试程序,程序断下来后鼠标右键->go to disassembly 查看反汇编,然后我们可以看到
00401010 push ebp
00401011 mov ebp,esp
00401013 sub esp,48h
00401016 push ebx
00401017 push esi
00401018 push edi
00401019 lea edi,[ebp-48h]
0040101C mov ecx,12h
00401021 mov eax,0CCCCCCCCh
00401026 rep stos dword ptr [edi] //对 ebp到 ebp - 0x48 的位置用0xcc填充
4: int variable,variable_1;
5: printf("variable = %d variable_1 = %d\n",variable,variable_1);
00401028 mov eax,dword ptr [ebp-8] //这个[ebp-0x8]就是我们的variable_1
0040102B push eax //c语言默认调用约定 最后一个参数第一个压栈
0040102C mov ecx,dword ptr [ebp-4] //[ebp -0x4]则是我们的variable
0040102F push ecx //c语言默认调用约定 第一个参数最后一个压栈
00401030 push offset string "j = %.2f k = %d z = %d\n" (0042601c) //最后把"j = %.2f k = %d z = %d\n" 压入堆栈
00401035 call printf (004010a0) //调用printf函数
0040103A add esp,0Ch
6:
7: return 0;
0040103D xor eax,eax
8: }
0040103F pop edi
00401040 pop esi
00401041 pop ebx
00401042 add esp,48h
00401045 cmp ebp,esp
00401047 call __chkesp (004011d0)
0040104C mov esp,ebp
0040104E pop ebp
0040104F ret
从上面反汇编代码我们可以看出:
variable:ebp - 0x4
variable_1:ebp -0x8
知道了这一点后我们就可以查看variable跟variable_1在内存中存储的值是多少了,我们切换后vc6.0然后按F10单步跟踪到
ebp -0x8 和 ebp -0x4 的地方就可以看到variable跟variable_1在内存中存储的值了
可以看到我们两个变量在内存存储的数值都是0xcccccccc 为什么呢?
因为上面分析反汇编代码的时候我已经注释了ebp 到 ebp-0x48 的位置都会被填充位0xcc
00401019 lea edi,[ebp-48h]
0040101C mov ecx,12h
00401021 mov eax,0CCCCCCCCh
00401026 rep stos dword ptr [edi] //对 ebp到 ebp - 0x48 的位置用0xcc填充
我们对变量进行赋初值的时候编译器会生成对应的汇编代码
例如:int variable = 10;------> mov dword ptr ds[ebp-4],0xA
只有对变量进行赋初值的时候才会修改ebp-4在内存的数值,如果不赋初值那么当我们用到这个变量的时候编译器就默认把0xcccccccc当作我们变量的初值对待。
现在搞清楚了不赋初值的问题你们是不是还有一个疑问:打印出来的是:-858993460 为什么内存显示的是0xcccccccc?
这涉及到<有符号整形的存储方式>这里就不一一解说我们用一段代码来演示一下!
#include <stdio.h>
int main(void)
{
int x = 0xcccccccc; //定义一个int有符号整型变量
printf("%d\n",x);
return 0;
}
编译->运行..........
0xcccccccc就是-858993460
我们让编译器把 int x; 当作有符号整型变量来使用他就是-858993460 如果我们要编译器当成无符号整型来看待呢?
#include <stdio.h>
int main(void)
{
int x = 0xcccccccc;
printf("%u\n",x); //%u打印无符号整型变量
return 0;
}
编译->运行..........
打印出来的值不再是-858993460 而是 3435973836 不管加不加unsigned变量在内存存储的数据都是0xcccccccc ,就看我们怎么使用罢了
#include <stdio.h>
int main(void)
{
int x = 0xcccccccc;
printf("ux = %u\n",x);
printf("sx = %d\n",x);
return 0;
}