内存访问

访问内存中的数据

关键点物理地址、DS寄存器

  1. mov ax, 1000H
  2. mov ds, ax
  3. mov bx, [1]

符号[ ]

汇编语言[ ]表示一块内存单元。[ ]里面的内容是偏移地址。默认的是数据段地址,但是也可以加上段前缀。
例子1[1]:表示数据段ds : 0001H的内存单元值。
例子2[bx]:表示数据段ds:bx的内存单元值。bx寄存器中的值作为偏移地址。
例子3cs:[bx]:表示代码段cs:bx的内存单元值。

访问内存中的代码

关键点物理地址、CS寄存器、IP寄存器

访问栈内存

关键点物理地址、SS寄存器、SP寄存器、push指令、pop指令

栈区

一块具有特殊访问方式的存储空间。具体访问方式是数据先进后出。

栈区的功能

  • 具体这块空间的地址是由SS、SP寄存器决定,另一方面也是告诉CPU栈内存空间的大小。SS:SP始终指向栈顶地址,刚开始设置时SP可以设置栈空间大小,一旦写入数据,SP就会指向栈顶元素。每增加数据,SP指向的地址做减法。
  • push 入栈指令。将指定寄存器中的内容入栈。
  • pop 出栈指令。
  • 重要应用功能在C语言中函数的参数值、局部变量等,由编译器自动分配和释放,通常函数在执行结束后内存就会自动释放。由于数据的存储和释放是通过硬件指令完成,所以速度很快。

例子初始化栈空间

mov ax, 1000H
mov ss, ax
mov sp, 0010H  //初始化栈顶

总结

例子一段内存,可以是代码空间、栈空间、数据段空间。关键在与CPU中寄存器的设置,通过寄存器来管理内存空间的状态。

//设置CS=1000H,IP=0
mov ax, 1000H
mov ss, ax
mov sp, 0020H        //初始化栈顶

mov ax, cs
mov ds, ax        //设置数据段地址

mov ax, [0]
push ax
pop ax

问:为什么栈空间向下增长,堆空间向上增长?

在没有MMU的时代,一段程序分配的内存,由低地址到高地址分别是code、data、堆、栈。我们知道堆栈空间在程序运行期间是不断变化的,堆栈空间不同的增长方向可以共享同一块内存空间,也不需要设置堆栈空间的分界线。
image.png