寄存器数量和容量有限,为了存储大量数据,所以我们需要内存
- 每个程序都会有自己的独立的4GB内存空间(
这里的内存其实是虚拟的,并不是真的给了程序4G内存,当程序读或者写这段内存的时候,操作系统才会把使用的内存映射到物理内存上
物理内存和内存条之间还有一层映射
1Bit 就是一个位 也就是可以存储1个0或者1
1Byte(字节) = 8Bit
1KB = 1024Byte
1MB = 1024KB
1GB = 1024MB
内存地址
- 内存太大没法起名字,所以只能用编号,当我们想读取或者写入数据到内存的时候,就必须用到编号
- 这个编号又称为内存地址(32位,前面0可以忽略),换算成16进制,那么就是8个16进制数表示
为何32位中单个应用程序只能用4G内存?
因为内存地址只有32位 那么寻址只能是
0x00000000
到0xffffffff
也就是0xffffffff +1(0x0也是一个地址) = 10000000
个Byte,
一个Byte(字节)可以存储8位(Bit) 那么可以存储100000000 * 8 = 800000000
个0或者1(16进制)
换算成10进制就是34359738368
个Byte
通过计算(34359738368/8(Byte)/1024(KB)/1024(MB)/1024(GB)
) 就是4GB
内存操作
- 立即数到内存(内存需要声明数据宽度,并且写入的数据必须和内存数据宽度匹配)
BYTE = 1字节 =8bit
WORD = 2字节 =16bit
DWORD = 4字节 =32bit
MOV BYTE PTR DS:[19FFF0],0xFF
MOV WORD PTR DS:[19FFF0],0xFFFF
MOV DWORD PTR DS:[19FFF0],0x12345678
- 寄存器值到内存
内存地址的每个编号,代表的是一个byte字节
那么我们写的word
(双字节)和dword
(四字节)的多出来宽度的数据哪里去了?
这里其实会往后写
比如往<code>写四字节
0x12345678
那么实际情况会是:
0x0019FFF0 | 12 |
---|---|
0x0019FFF1 | 34 |
0x0019FFF2 | 56 |
0x0019FFF3 | 78 |
会连续使用4个字节的内存
MOV DWORD PTR DS:[19FFF0],EAX
MOV WORD PTR DS:[19FFF0],AX
MOV BYTE PTR DS:[19FFF0],AL
- 内存到寄存器
MOV EAX,DWORD PTR DS:[19FFF0]
MOV AX,WORD PTR DS:[19FFF0]
MOV AL,BYTE PTR DS:[19FFF0]
- 内存到内存
在汇编中,大多数操作都不可以内存到内存
内存的5种形式
立即数
- 读取内存的值:
MOV EAX,DWORD PRT DS:[0X19FFC4]
- 向内存中写入数据:
MOV DWORD PTR DS:[0X13FFC4],EAX
[REG] reg代表寄存器,可以使8个通用寄存器中的任意一个
- 读取内存的值:
MOV ECX,0X13FFD0
MOV EAX,DWORD PTR DS:[ECX]
- 向内存中写入数据:
MOV EDX,0X13FFD8
MOV DWORD PTR DS:[EDX],0X87654321
[REG+立即数]
- 读取内存的值:
MOV ECX,0X13FFD0
MOV EAX,DWORD PRT DS:[ECX+4]
- 向内存中写入数据:
MOV EDX,0X13FFD8
MOV DWORD PTR DS:[EDX+0XC],0X87654321
[REG+REG*{1,2,4,8}]
- 读取内存的值:
MOV EAX,13FFC4
MOV ECX,2
MOV DWORD PTR DS:[EAX+ECX*4],87654321
- 向内存中写入值:
MOV EAX,13FFC4
MOV ECX,2
MOV DWORD PTR DS:[EAX+ECX*4],87654321
[REG+REG*{1,2,4,8}+立即数]
- 读取内存的值:
MOV EAX,13FFC4
MOV ECX,2
MOV DWORD PTR DS:[EAX+ECX*4+4],87654321
- 向内存中写入值:
MOV EAX,13FFC4
MOV ECX,2
MOV DWORD PTR DS:[EAX+ECX*4+4],87654321
小端存储模式
内存地址对应一个内存单元
每个单元的大小就是8位(byte) 一个字节
情况1:
MOV BYTE PTR DS:[0x00000000],0X1A
0x00000000 | 0x1A |
---|---|
0x00000001 | |
0x………. |
情况2:
MOV WORD PTR DS:[0x00000000],0x1A2C
分析:
以字节为单位:数据 0x1A2C
中 1A
为高位 2C
为低位
内存 0x00000000
为低位 0x00000001
为高位
大端模式:
0x00000000 | 1A |
---|---|
0x00000001 | 2C |
小端模式:
0x00000000 | 2C |
---|---|
0x00000001 | 1A |
那么我们的存储到底用的那种模式呢?
在x86架构中绝大多数都是用的小端存储(非绝对,受编译器影响)
在arm中绝大多数采用大端模式存储(非绝对,受编译器影响)