第28节:什么是变量
变量是什么?在程序的进程中需要存储一些数据。大家之前学汇编的时候知道了,存储数据可以存到CPU中也就是存在寄存器里也可以存在内存中。但是在C语言中存储数据的时候我们要把这个数据存储到哪里呢?在C语言里所为的变量就是一个容器,也就是一块内存。
1、声明变量
变量类型 变量名
变量类型 用来说明宽度是多大
int 4个字节
short 2个字节
char 1个字节
例子1:
#include<stdio.h>
int x; //声明变量
void main()
{
x = 1; //给x赋值(局部变量)
return ; /./执行结束
}
变量名的命名规则:
1、只能以字母、数字、下划线组成且第1个字母必须字母下划线
2、区分大小写
3、不能使用C语言的关键字
以上的例子就是全局变量的例子,全局变量的特点:在函数里可以赋值,如:例子中的x = 1。全局变量是声明的时候没有放到函数里面,但是它有一个独一无二的内存编号。当x = 1时转换成汇编代码如下:
5: void main(){
00401010 push ebp
00401011 mov ebp,esp
00401013 sub esp,40h
00401016 push ebx
00401017 push esi
00401018 push edi
00401019 lea edi,[ebp-40h]
0040101C mov ecx,10h
00401021 mov eax,0CCCCCCCCh
00401026 rep stos dword ptr [edi]
6:
7: x = 1;
00401028 mov dword ptr [_x (00427e44)],1
8: return;
9: }
00401032 pop edi
00401033 pop esi
00401034 pop ebx
00401035 mov esp,ebp
00401037 pop ebp
00401038 ret
以上的汇编代码不是标准的汇编代码,这个汇编代码只是能容易读懂。
从以上的汇编代码我们很容易理解什么是函数,什么是变量名,实际上就是一个内存地址的编号,在这里x= 00427e44,就是一个内存编号,那么这块内存有多大呢?这块内存是4个字节(dwrod),在C语言中int就是对应着dword。可以简单的说变量就是容器,变量类型确定了变量的宽度,变量名就是内存的编号,所以有了汇编的底子看这种代码非常简单:
例子2:
#include<stdio.h>
#include<windows.h>
int plus()
{
int x;
x = 1234567;
while(1)
{
Sleep(3000);
}
return 0;
}
void main()
{
plus();
return;
}
以上是局部变量,局部变量和全局变量差别在于,局部变量在函数里面,函数用了才有值,函数不用没有值,而且它的地址没有办法确定,我们根本不知道值是多少,什么时候被函数调用。局部变量的值一旦执行完毕后就消失了,请看如下局部变量汇编代码:
6: int x;
7:
8: x = 1234567;
00401038 mov dword ptr [ebp-4],12D687h
9: while(1)
0040103F mov eax,1
00401044 test eax,eax
00401046 je plus+3Eh (0040105e)
10: {
11: Sleep(3000);
00401048 mov esi,esp
0040104A push 0BB8h
0040104F call dword ptr [__imp__Sleep@4 (0042a14c)]
00401055 cmp esi,esp
00401057 call __chkesp (004010d0)
12: }
0040105C jmp plus+1Fh (0040103f)
13: return 0;
0040105E xor eax,eax
14: }
00401060 pop edi
00401061 pop esi
00401062 pop ebx
00401063 add esp,44h
00401066 cmp ebp,esp
00401068 call __chkesp (004010d0)
0040106D mov esp,ebp
0040106F pop ebp
00401070 ret
16: void main()
17: {
00401090 push ebp
00401091 mov ebp,esp
00401093 sub esp,40h
00401096 push ebx
00401097 push esi
00401098 push edi
00401099 lea edi,[ebp-40h]
0040109C mov ecx,10h
004010A1 mov eax,0CCCCCCCCh
004010A6 rep stos dword ptr [edi]
18: plus();
004010A8 call @ILT+5(_plus) (0040100a)
19: return;
20: }
004010AD pop edi
004010AE pop esi
004010AF pop ebx
004010B0 add esp,40h
004010B3 cmp ebp,esp
004010B5 call __chkesp (004010d0)
004010BA mov esp,ebp
004010BC pop ebp
004010BD ret
变量是什么?在程序的进程中需要存储一些数据。大家之前学汇编的时候知道了,存储数据可以存到CPU中也就是存在寄存器里也可以存在内存中。但是在C语言中存储数据的时候我们要把这个数据存储到哪里呢?在C语言里所为的变量就是一个容器,也就是一块内存。
1、声明变量
变量类型 变量名
变量类型 用来说明宽度是多大
int 4个字节
short 2个字节
char 1个字节
例子1:
#include<stdio.h>
int x; //声明变量
void main()
{
x = 1; //给x赋值(局部变量)
return ; /./执行结束
}
变量名的命名规则:
1、只能以字母、数字、下划线组成且第1个字母必须字母下划线
2、区分大小写
3、不能使用C语言的关键字
以上的例子就是全局变量的例子,全局变量的特点:在函数里可以赋值,如:例子中的x = 1。全局变量是声明的时候没有放到函数里面,但是它有一个独一无二的内存编号。当x = 1时转换成汇编代码如下:
5: void main(){
00401010 push ebp
00401011 mov ebp,esp
00401013 sub esp,40h
00401016 push ebx
00401017 push esi
00401018 push edi
00401019 lea edi,[ebp-40h]
0040101C mov ecx,10h
00401021 mov eax,0CCCCCCCCh
00401026 rep stos dword ptr [edi]
6:
7: x = 1;
00401028 mov dword ptr [_x (00427e44)],1
8: return;
9: }
00401032 pop edi
00401033 pop esi
00401034 pop ebx
00401035 mov esp,ebp
00401037 pop ebp
00401038 ret
以上的汇编代码不是标准的汇编代码,这个汇编代码只是能容易读懂。
从以上的汇编代码我们很容易理解什么是函数,什么是变量名,实际上就是一个内存地址的编号,在这里x= 00427e44,就是一个内存编号,那么这块内存有多大呢?这块内存是4个字节(dwrod),在C语言中int就是对应着dword。可以简单的说变量就是容器,变量类型确定了变量的宽度,变量名就是内存的编号,所以有了汇编的底子看这种代码非常简单:
例子2:
#include<stdio.h>
#include<windows.h>
int plus()
{
int x;
x = 1234567;
while(1)
{
Sleep(3000);
}
return 0;
}
void main()
{
plus();
return;
}
以上是局部变量,局部变量和全局变量差别在于,局部变量在函数里面,函数用了才有值,函数不用没有值,而且它的地址没有办法确定,我们根本不知道值是多少,什么时候被函数调用。局部变量的值一旦执行完毕后就消失了,请看如下局部变量汇编代码:
6: int x;
7:
8: x = 1234567;
00401038 mov dword ptr [ebp-4],12D687h
9: while(1)
0040103F mov eax,1
00401044 test eax,eax
00401046 je plus+3Eh (0040105e)
10: {
11: Sleep(3000);
00401048 mov esi,esp
0040104A push 0BB8h
0040104F call dword ptr [__imp__Sleep@4 (0042a14c)]
00401055 cmp esi,esp
00401057 call __chkesp (004010d0)
12: }
0040105C jmp plus+1Fh (0040103f)
13: return 0;
0040105E xor eax,eax
14: }
00401060 pop edi
00401061 pop esi
00401062 pop ebx
00401063 add esp,44h
00401066 cmp ebp,esp
00401068 call __chkesp (004010d0)
0040106D mov esp,ebp
0040106F pop ebp
00401070 ret
16: void main()
17: {
00401090 push ebp
00401091 mov ebp,esp
00401093 sub esp,40h
00401096 push ebx
00401097 push esi
00401098 push edi
00401099 lea edi,[ebp-40h]
0040109C mov ecx,10h
004010A1 mov eax,0CCCCCCCCh
004010A6 rep stos dword ptr [edi]
18: plus();
004010A8 call @ILT+5(_plus) (0040100a)
19: return;
20: }
004010AD pop edi
004010AE pop esi
004010AF pop ebx
004010B0 add esp,40h
004010B3 cmp ebp,esp
004010B5 call __chkesp (004010d0)
004010BA mov esp,ebp
004010BC pop ebp
004010BD ret