PX-15-变量内存和cpu原理

1.变量和内存原理

内存是运行程序的场所,磁盘时存放数据的。运行程序实际是将文件从硬盘拖到内存里来。

游戏外挂为什么能实现更改数据?

因为,计算机中,指令代码、数据都存储于内存中。变量也需要存储在内存中。只要突破权限控制就可以对代码进行任意的更改!

 

2.调试器

cpu 和 内存 对变量如何发挥作用的?

 

3.查看变量在内存中断点查看

#include<stdio.h>

void main1()
{
    int a = 10;
    printf("%p", &a);//查看a的内存地址   
    printf("\n%d", a);
    getchar();
}

内存的原理: 同一个时间,内存空间里只能保存一份值,新值冲掉了原来的旧值。每个内存单元都有编号,这些是内存的地址。
变量变化的原理:在内存中存放不同的数据,当内存发生变化的时候,变量也会发生变化。

 

4.变量的内存机制

编译器的处理过程:

    (1)明确存储的类型,然后处理变量名

    (2)变量表

    

    例如计算,1+2=3,a=1,b=2,c=3,C =a+b

    当引用了a,b,c会创建变量表

    变量表的作用: 管理所有的变量

void main2()
{
    int a, b, c;  //变量表,管理所有的变量
  //会自动生成一张变量表


//没有声明d
//不能引用未曾声明的变量 printf("\n%d", d); getchar(); }

//执行后会报错 ,为声明的标识符

 

    

 

    (3)c / c++ 不会默认对变量进行初始化

    

    java c#会默认声明变量时候对变量进行初始化

 

    (4)

void main4()
{
    int a = 3; //赋值,只能给变量赋值,变量在内存    
    //a + 1 = 4; a+1属于寄存器,
    int b = 0;
    printf("%p", &b);
    b = a + 1;
    b = a + 2;

    getchar();
}

 

    

    上图分析出 a+1 不在内存中实现而是在寄存器中!      

  •       a+1=b 为什么是不对的?

    a+1 计算的过程发生在寄存器中!寄存器不能被赋值!

    赋值只能给变量,变量在内存中;计算不发生在内存中;

    计算并不在内存中进行因此无法赋值,计算发生在寄存器中。EAX中;

    结论: 对数据进行的所有操作都是通过cpu ,如果不通过cpu 内存是不能直接赋值的;

     只有变量可以进行赋值操作,变量必须要在内存里。

 

    (5)用汇编语言演示变量在内存中被赋值和被计算的过程

void main()
{
    int a;
    printf("%p", &a);
    //变量赋值,都是CPU的寄存器完成
    //a = 10;      //代码区的常量符号表10,100
    //printf("%p", &10);
_asm { mov eax ,10

mov a,eax } printf("\na=%d", a); _asm { mov eax,a add eax,5 mov a,eax } printf("\na=%d", a); getchar(); }

 

    

      变量赋值,都是CPU的寄存器完成

    (6)a=10

      10在寄存器里产生。首先从代码区的符号表中读取出来 然后再寄存器中产生;然后控制器将寄存器中的值赋值给,cpu分配给a的这块内存上,这样 a的值发生了变化

      //printf("%p", &10); 

      取地址取得是内存地址 10 在寄存器里产生 

      12345678910 ---等整数 cpu 要计算出二进制才能操作

      10是编译器有一个地方存储了一个10 通过cpu提取数据 将他存放在寄存器里面 在进行赋值

 

      10---存在 --代码区的常量符号表---里 用到什么就存了进去编译进去  //代码区 内存4区 只读不写!

      首先从代码区的符号表中读取出来 然后再寄存器中产生 然后再将值赋值给内存的变量  所以这片内存发生变化

      10 要进行赋值要通过cpu 将寄存器的值赋值给内存,内存不能直接赋值。

 

 

 

2.格式控制符“%p”


格式控制符“%p”中的p是pointer(指针)的缩写。指针的值是语言实现(编译程序)相关的,
但几乎所有实现中,指针的值都是一个表示地址空间中某个存储器单元的整数。
printf函数族中对于%p一般以十六进制整数方式输出指针的值,附加前缀0x。
示例: int i
= 1; printf("%p",&i);
相当于 int i
= 1; printf("0x%x",&i); 对于32位的指针,输出一般会是类似0xf0001234之类的结果。 %p存在的理由除了附加前缀输出的便利性以外,指针的大小是不确定的,由实现决定。根据地址空间的大小,一般有16位、32位、64位的指针。
尽管目前32位平台上的指针一般全是32位的,但旧的一些平台上可能有多种长度的指针(例如非标准的near、far、huge修饰的pointer)混用,
无法用%x、%lx、%hx、%llx(对应int、long、short、long long)中的任意一种保证能输出所有类型的指针。

 

 

 

 

-------------------------------------------------------------------------------------------------------------------

3.变量的内存机制

计算机中,指令代码、数据都存储于内存中。

变量之所以可以变化,就是这个存储空间可以存储不同的数值。存储空间里的值变化,则变量对应的值也变化。

同一个时间,内存空间里只能保存一份值,新值冲掉了原来的旧值。每个内存单元都有编号,这些是内存的地址。

 

4.变量表的概念

void main4()
{
    int a = 3; //赋值,只能给变量赋值,变量在内存    
    //a + 1 = 4; a+1属于寄存器,
    int b = 0;
    printf("%p", &b);
    b = a + 1;
    b = a + 2;

    getchar();
}

 

 

6.在c语言中嵌入汇编语言的方式

//变量赋值,都是CPU的寄存器完成
_asm
    {
        mov eax ,10
mov a,eax }

//相当于 a=10

 

7.

// a+ = 5 的实现过程   
_asm { mov eax,a add eax,
5 mov a,eax } printf("\na=%d", a); getchar(); }

 

8. a=10

10在寄存器里产生。

//printf("%p", &10); 

取地址取得是内存地址 10 在寄存器里产生 

12345678910 ---等整数 cpu 要计算出二进制才能操作

10是编译器有一个地方存储了一个10 通过cpu提取数据 将他存放在寄存器里面 在进行赋值

 

10---存在 --代码区的常量符号表---里 用到什么就存了进去编译进去

首先从代码区的符号表中读取出来 然后再寄存器中产生 然后再将值赋值给内存的变量  所以这片内存发生变化

//代码区 内存4区 只读不写!

 

---

10  不在内存里 ,所以 &10 是不对的; 是不可以 原因:变量可以取地址在内存中 ,10在寄存器中产生的, 无法在寄存器中取地址

10 -- 编译器有一个地方存储了10

//变量赋值,都是CPU的寄存器完成

//a = 10;

//代码区的常量符号表10,100

//printf("%p", &10);

 

 

程序示例代码:

#include<stdio.h>

void main1()
{
    int a = 10;
    printf("%p", &a);//查看a的内存地址   
    printf("\n%d", a);
    getchar();
}

void main2()
{
    int a, b, c;  //变量表,管理所有的变量
    //不能引用未曾声明的变量
    //printf("\n%d", d);
    getchar();
}

void  main3()
{
    int a = 1;
    int b = 2;
    int c;
    printf("a=%p,b=%p,c=%p", &a, &b, &c);

    c = a + b;
    getchar();
}

  

void main()
{
    int a;
    printf("%p", &a);
    //变量赋值,都是CPU的寄存器完成
    //a = 10;      //代码区的常量符号表10,100
    //printf("%p", &10);
    _asm
    {
        mov eax ,10
mov a,eax } printf("\na=%d", a);
_asm { mov eax,a add eax,5 mov a,eax } printf("\na=%d", a); getchar(); }

 

 

      //代码区 内存4区 只读不写!

posted @ 2016-12-09 20:33  silvercell  阅读(2473)  评论(0)    收藏  举报