汇编基础

寄存器

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

参考

汇编语言入门教程

既生堆何生栈

内存中的堆栈和数据结构堆栈区别

-------------本文结束感谢阅读-------------

欢迎关注我的其它发布渠道