2.3 汇编学习环境
我们通过上一章笔记,得知 计算机好像 只会通过位运算 进行 数字的加法。
而机器语言的魅力就是 位运算,解析规则。它们也都是通过 电路 来进行实现的。这就是 计算机最底层的本质了!!!
- 汇编语言
所谓的汇编语言,不就是 通过助记符,来替代我们的 二进制嘛。只是为了 简化 我们的操作。而被发明出来的。
32 位 和 64位 的本质架构区别不大,只是寻址能力得到了增强。
目前 学习汇编 其实不需要什么 IDE 去写代码写程序了。而是 直接 下载 反汇编 工具 就可以。比如 OD、CE、x64dbg 这些。当然 搭配 VC++6.0 食用更佳。
2.4 通用寄存器(可以存储任何的值)
存储数据的过程:CPU --> 内存 --> 硬盘
32 位 CPU :8 16 32
64 位 CPU :8 16 32 64
现在的 操作系统其实都是向下兼容的!也就是说 32 位 的软件有很多很多呀。但是 都可以 运行在 64 位的系统上。
- 32位的通用寄存器 只有 8个
存值的范围只有:0 ~ FFFF FFFF
计算机如果向寄存器里存值,怎么存 ?
答:mov指令 直接 就能 存。
mov 目标地址,存储的数值
mov 目标地址,被传输的地址
mov 目标寄存器,存储的数值
mov 目标寄存器,被传输的寄存器
不同的寄存器(存储的数据宽度也不同)
32位 | 16位 | 8位 |
---|---|---|
EAX | AX | AL(AX的低八位) |
EBX | BX | BL (BX的低八位) |
ECX | CX | CL (CX的低八位) |
EDX | DX | DL (DX的低八位) |
ESP | SP | AH(AX的高八位) |
EBP | BP | BH (BX的高八位) |
ESI | SI | CH(CX的高八位) |
EDI | DI | DH (DX的高八位) |
ESP:通常存储栈顶的地址
EBP:通常存储栈底的地址
EIP:通常存储的是 调用的 CALL 的地址。(跳转地址)
2.4 内存
寄存器是很小的,不够用。所以说,我们的数据怎么存储呢?就诞生了一个东西,叫做 内存。
我们规定每个应用程序进程 其实 都可以 使用 4GB 的内存空间。(也被我们称为 虚拟内存)但实际上我们并不能用那么多的内存空间。所以相当于 空头支票。
内存地址:其实就是 为我们的每一块内存 起的一个名字。方便我们找到它。
寻址能力:就是能够 找到多大 范围的 地址。x86(32位) 能够找到 0x FFFF FFFF 的地址。 这其实 不算 庞大。
32 位 内存地址的数量是 FFFF FFFF + 1 = 4,294,967,297 个地址。
一个地址 对应着 一个 八位的 二进制串。也就是说 一个地址 相当于 一个字节。
所以理论上 能存 4,294,967,297 /1024 /1024 /1024 = 4GB
所以我们才说,32位 理论上 4GB 就是它的极限。
- x64 位寻址能力 和 极限
x64 位寻址能力:0 - 0xFFFF FFFF FFFF FFFF
1,152,921,504,606,846,976 * 16 个内存地址。
x64 的 极限:17,179,869,184 GB
其实指针是什么呢?就是用来存储 内存地址的 类型变量。或指向内存地址的东西。是方便我们 操作 内存地址和其值的。
当你学会了 这个 底层,你会发现 指针 很容易!
比如说:我们存储的数据一般情况下,没有特别小的数据类型,可以小到 一个字节的。当然 JAVA有个 Byte 类型。如果 超过了 一个字节的类型,它在 内存中 怎么存储呢?
根据连续的内存空间,进行存储。因为 我们说 一个内存地址只对应一个 字节的 内存空间。那么4字节的 类型数据,我们就需要用到 4个 连续的内存空间 来进行 存储。
最标准mov代码:mov dword ptr ds:[内存地址]
byte、word、dword:数据宽度
ptr:相当于 Type类型
CS (Code Segment) 代码段
DS (Data Segment) 数据段
ES (Extra Segment) 附加段
SS (Stack Segment) 栈段
FS:(Flag segment) 标志段寄存器
GS:(Global segment) 全局段寄存器