为什么需要内存?
如果我们只需要这样的计算:1+2=?
,我们当然不需要内存。
如果有十亿个数相加呢?寄存器明显不够用。所以就需要内存了
这里所说的内存 严格意义上并不是 内存条 ,但是现在可以这样理解,内存就在内存条中,内存条提供了一个很大的容器
从存储角度来看的话,寄存器和内存条没有什么区别,都是容器,都存储着一些列0、1这样的数字。
寄存器和内存的区别

如何定位内存?
问题引出:
cpu寄存器的数量是有限的,我们可以给每一个寄存器定义名字。但是内存很大,我们如何定义,方便我们找到呢?
32位、64位计算机
32位计算机:
误解:cpu寄存器的最大宽度是32位,所以是32位计算机。这种说法是不对的。32位指的是寻址编号。
就是说计算机内部有32根线,每根线都可以代表0和1,每根线变化一下,就可以得到一个地址,就可以根据这个地址找到一块内存。32根线,也就是32位,就是寻找内存的范围。也就是寻址范围。
这里的一块指的是8bit | 1byte
根据寻址范围,我们就相当于给内存起好编号了。
注意
编号都是以字节为单位.

计算最大内存
32位计算机:
2^32个内存编号,一个内存编号代表1byte
2^32 byte
2^32 / 1024 = 2^32 / 2^10 =2^22 KB
2^22 / 1024 = 2^22 / 2^10 = 2^12 MB
2^12 / 1024 = 2^12 / 2^10 = 2^2 GB = 4GB
即使这里是4GB,不过一般我们看到的内存都是小于4GB的,这是有些系统固件会占用一部分内存。

这个问题仔细扣是不对的。因为计算机还可以扩展内存,正常情况下,计算如果按照32位的寻址规则的话,是4GB,但是计算机也可以打破这个寻址规则。其实,如何寻址,都是计算机自己内部定义的。
内存读写
内存的格式

内存的读写至少都是8位。涉及到内存,记住单位就是byte
内存地址和立即数
mov 0x12345678,0xFFFF
这条指令中,0x12345678
到底是立即数,还是内存地址。
不好区分,所以规定,我们用 []
来表示内存
mov [0x12345678],0xFFFF
上面这条指令还是不好(不是不对)?
因为
0x12345678
表示1byte
,而0xFFFF
是2 byte
.
内存不像寄存器,超过的会直接抛弃,所以我们应该指定宽度,下面就是标准格式。

演示
每个应用程序打开时,都会有一个4GB的空间
DTDebug打开一个应用

先认识一下我们的工具。
说明几点:
- 寄存器ESP一般就是用来处理堆栈的
- 右下角的堆栈区,我们初学者可以把他理解为内存
内存写
MOV DWORD PTR DS:[8FFFFFFF],0x12345678
执行报错。
每个应用程序打开时,都会有一个4GB的空间,但是有部分地址我们时无法访问的。
怎么知道我们可以访问的地址呢?寄存器ESP中存放的地址肯定时可以访问的。

我们更改一下指令
MOV DWORD PTR DS:[0x0019FF74],0x12345678
执行

可以看到已经写入了。
还有一个细节:
[0x0019FF74]
是1byte的地址,可是我们写入0x12345678
,4byte,怎么回事?注意看堆栈区的内存标号:

每四个才显示一个内存标号。
其实我们的
0x12345678
是存在4个内存标号里的。
内存读
MOV EAX,DWORD PTR DS:[0x13FFC4]
`
网友评论