day13.内存地址的五种形式



第13节:内存地址的五种形式数组

上节课讲了内存相关知识,那么咱们一块儿回顾一下。
读取内存的值,好比例子:
MOV EAX,DWORD PTR DS:[0x13FFC4]
以上的代码意思从内存中取出四个字节的数据,那么咱们是怎么知道是四个字节的呢?有两个地方知道,一是从EAX寄存器知道它是32位寄存器,还有从数据的宽度DWORD知道。在上节课看到这种MOV指令先后两个指令操做数的宽度要同样,不然会报错在看上面的例子中的[0x13FFC4]内存地址编号,它指向了某一个内存单元,这个内存单元有多大呢?其实是八位一个字节,那么咱们知道是每个内存编号都对应着一个字节。那么这种形式,在咱们真正看汇编的时候还会有其余的形式出现吗?答案是有的,并且不只仅是当即数这一种状况,咱们来看一段C语言代码:工具

int x=1; //全局变量
int main()
{
    x = 2;
    int y = 3;  //局部变量
    int z[] ={0};  //数组
    for(int i=0;i<10;i++) //循环语句
    {
        z[i]=i;  //输出数组值
    }
}学习

咱们想了解C语言的某些特性,学习某些语法之类的,实际上是很容易的。好比上面的代码咱们不知道是什么意思的时候,若是你会汇编的话,经过切换到汇编的状况下,就一目了然了。因此你们不知道上面的代码什么意思,没关系,如今讲的是汇编。好比来看x = 2汇编代码的形式是:
dword ptr[x(00424d8c)],2debug

以上是将2的数存到00424d8c的内存地址里面,x加上中括号是为了让咱们更直观看懂代码的意思,也就是说它想告诉咱们这是一个内存编号,是有x进行生成的,也就是x的内存编号,这并非标准的写法,标准的写法是:
dword ptr ds:[0x00424d8c],2
若是指令是mov dwrod ptr[ebp-4],3的形式的时候,是将3存到ebp-4的内存编号里面。
若是指令是dword ptr [ebp+ecx* 4-8],edx,这个内存地址又是多少呢?实际上是ebp+ecx* 4-8的内存编号给edx。我想告诉你们的是咱们知道了[00424d8c]只有这种当即数方式后,还有其余的写法方式。这节课主要来了解一下内存地址的五种形式,就是内存编号有五种表示形式,只有这五种形式,没有第六种,若是五种都掌握之后在看汇编里有涉及到这五种形式你都能看的懂,好的我来介绍着五种形式:内存

1) MOV DWORD PTR DS:[0x123FFFD4],EAX
这种形式也是咱们以前学过的形式在中括号里面直接写一个数值,这个数值就表明内存的地址。编译器

2) MOV DWORD PTR DS:[reg]
reg表明32位寄存器,这个怎么用,咱们们打开olldebug工具在反汇编窗口中输入:
MOV DWORD PTR DS:[18FFF8],0x12345678
还能够将寄存器中的EAX改为0018FFF8,在MOV指令里面不写当即数了直接写[EAX],最终的结果是:
MOV DWORD PTR DS:[EAX].0x12345678
这样的结果是和当即数的方式是同样的,有人会说这个有意义吗?实际上是有意义的,咱们前面演示了当咱们将一个C语言转换成汇编,而后看汇编代码的时候,你怎么保证编译器按照你的要求方式生成汇编呢?我能保证的是不管你生成什么样的汇编,都能看的懂,因此你们要弄清楚咱们为何要学这个里面地址编号的五种形式。编译

3) [reg+当即数]
咱们在反汇编窗口中输入MOV EAX,DWORD PTR DS:[ECX+4],那么ECX是0取得ECX+4的值,首先咱们将ECX寄存器的值改为18FFF4,若是ECX=18FFF4内存编号在加4,那么取得的结果就是18FFF8的值,而后在把这个值传给EAX里,根据第2种形式中的值获得输出是EAX=12345678。(注意:这只是一个例子在大家的机子上用olldebug工具演示的话值是不同的。)变量

4)[reg+reg*{1,2,4,8}]
表示一个32位寄存器加上另外一个32位寄存器乘以一个值,这个值只有是一、二、四、8。举个例子:
 MOV EAX,13FFC4
 MOV ECX,2
 MOV EDX,DWORD PTR DS:[EAX+ECX* 4]
 最终的结果是:13FFC4+2 * 4=13FFCC 在将这个值给EDX
 
5)[reg +reg*{1,2,4,8}+当即数]
例子:
MOV EAX,13FFC4
MOV ECX,2
MOV EDX,DWORD PTR DS:[EAX+ECX*{1,2,4,8}+4]循环

这就是内存地址的五种形式。
语法