汇编基础
寄存器
CPU 只负责运算,不负责存储数据,而数据都存储在磁盘中,磁盘速度无法满足运算时的速度,因此需要将数据先读取到内存中,CPU 需要的时候就去内存中读取,但 CPU 的运算速度远高与内存的读写速度,为避免被拖慢,CPU 都会自带一级、二级甚至三级缓存。基本上,CPU 缓存可看作是读写速度较快的内存。
但是,CPU 缓存的速度还是不够块,数据在缓存中的地址也是不固定的,CPU 每次读写都需要寻址也会拖慢速度。因此,CPU 自带寄存器(register) 用来存储常用的数据。CPU 优先读写寄存器,再由寄存器与内存交换数据。
寄存器 不依靠地址 来区分数据,而依靠名称。每一个寄存器都有自己的名称,通过告诉 CPU 去具体的哪个寄存器读写数据,这样速度是最快的。寄存器被比喻成零级缓存。
寄存器总类
早期 x86 CPU
只有 8 个寄存器,每个都有不同用途,现在的寄存器已经有一百多个了,都变成了通用寄存器,不特别指定用途,但早期寄存器的名字被保留了下来。
EAX
EBX
ECX
EDX
EDI
ESI
EBP
ESP
以上 8 个寄存器中,前 7 个都是通用的, ESP
寄存器有特殊用途,用于保存 Stack (栈) 的地址。
32 位 CPU 、64 位 CPU 指的是寄存器的大小,32 位 CPU 的寄存器大小是 32 Bit
(4 Byte), 64 位 CPU 的寄存器是 64 Bit
(8 Byte)。
-
1 Byte
=8 Bit
(1 B = 8 b
)。 -
一字节代表八个比特(八个二进制位)。
内存模型
寄存器只能存放很少量的数据,大多数时候, CPU 需要指挥寄存器直接与内存交换数据。而内存存储数据使用的是Heap
(堆) 和 Stack
(栈) 两种模型进行存储。
Heap (堆)
程序启动时,系统会给程序分配一段内存,用来存储程序和运行产生的数据,这段内存具有地址较低的起始地址和地址较高结束地址。
程序运行中,对于动态的内存占用请求(如新建对象),系统会从程序启动时分配的内存段中,从起始地址开始划分出请求大小的内存段来给用户,若需要更多内存段,则从前面的结束地址开始再堆积。
这种由用户主动请求划分出来的内存区域叫 Heap
(堆) ,它由起始地址开始从低位地址向高位地址增长,Heap
的一个重要特定就是不会自动消失,必须手动释放,或由垃圾回收机制来回收。
Stack (栈)
Stack
(栈) 是函数运行而临时占用的内存区域。系统开始执行函数时,会在分配给程序的内存段中建立一个帧 (frame
) ,函数中所有的内部变量都会保存在这个帧中,函数结束时这个帧会被回收,释放所有内部的变量,不再占用空间。
当函数调用另一个函数时,执行到调用函数时,系统会新建一个帧用于存储新函数的内部变量,这时就同时存在两个帧。一般来说,调用栈有多少层,就有多少帧。当被调用函数运行结束,它的帧就会被回收,系统会回到原函数中断执行的地方,继续往下执行。这种机制实现了函数的层层调用,且每层都能使用自己的本地变量。
所有的帧都存放在 Stack
,由于帧是一层层的堆叠,所以 Stack 被译为具有存储属性还有堆叠特定的 栈
。生成新帧,叫 入栈
(push
) ,栈的回收叫 出栈
(pop
) 。Stack 的特定就是 后入栈的先出栈(最内层的函数调用,最先结束运行) ,这就是 后进先出
的数据结构。每一次函数执行结束就自动释放一个帧,所有函数执行结束,整个 Stack 就都释放完。
Stack 由内存区的结束地址开始,从高地址向低地址分配,当新的帧产生时新帧地址会往低地址方向移动。
Stack 为什么叫栈
Heap 在词典中翻译 n. 堆,许多 ; vt. 使成堆
, Stack 在词典中翻译为 n. 堆,叠,垛 ; v. 堆积
,内存模型为什么要将 Heap 译为 堆
, Stack 译为 栈
? 内存模型又为什么选择 Heap 和 Stack 来描述内存模型?
堆
在中文字典中解释为:累积在一起的东西
栈
在中文词典汇解释为:存储货物或提供旅客住宿的房屋
。- Heap 在朗文英语词典中解释为
a large untidy pile of things
(一堆乱七八糟的东西) ,是物品的堆积。 - Stack 在朗文英语词典中解释为
a neat pile of things
(一堆整齐的东西) ,是整齐的堆叠。
为了区分这两 堆
从而找的相近的词 栈
来描述 Stack 。而内存模型中选择 Heap 和 Stack 来描述内存模型则是因为两个模型的特性的,杂乱的堆积和整齐的堆叠,存储货物的栈就是整齐的堆叠。
内存模型中的堆栈与数据结构中的堆栈
内存模型中的堆栈
- 堆区 : 从低地址向高地址划分,程序按需分配,需要手动释放
- 栈区 : 从高地址向低地址划分,函数调用自动扩展,自动回收
数据结构中的堆栈
- 堆 : 一颗完全二叉数结构,特点是父节点的值大于(小于)两个子节点的值(称为大(小)顶堆),常用于算法执行过程中的信息,应用场景: 堆排序、优先队列等。
- 栈 : 一种连续存储的数据结构,特点是存储的数据先进后出,后进先出。
CPU 指令
汇编语言的内容就是一条条的 CPU 指令,通过 CPU 指令完成对数据的处理运算。
常见 CPU 指令集:
- 复杂指令集(CISC): x86、AMD64
- 精简指令集(RISC): Alpha、MIPS、ARM、SPARC、PA-RISC
- 显示并发指令集(EPIC): IA-64
一些指令
- push
- call
- mov
- add
- pop
- ret