栈段

和代码段、数据段一样,栈也被定义为一个内存段,叫做栈段,由段寄存器ss指向

  • 定义栈段

    • 初始化段寄存器ss--->指向栈段的首地址
    • 初始化栈指针sp--->指向栈顶字节(以字为单位移动),初始化时指向栈段最后一个字节的下一字节,其实就等于分配给栈段的字节数
  • 栈操作

    • push:压栈,sp的值减2
    • pop:出栈,sp的值加2
  • 作用

    • 临时存储数据
    • 保护数据,比方说先将寄存器ax的值压入栈中,然后有个函数更改了ax的值,函数结束后再将栈中的值弹出,由ax接受,这样就保护了ax的内容
  • 注意点

    • push/pop指令的操作数是16位寄存器或16为内存单元,一个字的大小
    • 栈本质上只是普通的内存区域,用push/pop指令来访问
    • 保持栈的平衡,出栈与入栈要成对(即push和pop的数目一样)
    • 在编写程序前,充分估计所需要的栈空间,放置破坏有用的数据
    • 将栈定义到一个单独的段中,可以是错误仅局限于栈,sp的内容只会在栈段的地址范围来回滚动,不影响其他内存段
  • bochs调试显示栈的内容

    • print-stack命令用于显示栈顶以下的16个字的内容,第一个地址最低的就是栈顶

栈是由高地址向低地址生长的,即栈顶是低地址

寻址方式

  • 寄存器寻址:指令的操作数位于寄存器中
  • 立即寻址:指令的操作数是一个立即数
  • 内存寻址:实际上就是寻找偏移地址,这称为有效地址,段地址由4个段寄存器提供
    • 直接寻址:操作数是一个偏移地址,而且给出了该偏移地址的具体数值,无需计算(段超越前缀和标号,不涉及计算时也是直接寻址)
    • 基址寻址:在指令的地址部分使用bx或bp寄存器来提供偏移地址
      当我们使用栈时,我们只能访问栈顶元素,若是想不改变sp去访问元素,可以先将sp的值赋给bp,然后在去添加元素等等,这时候就可以通过bp访问栈顶以下的元素而不改变sp了
    • 变址寻址:类似基址寻址,只不过使用的是变址寄存器(si和di)
    • 基址变址寻址:同时使用bx/bp和si/di这两类寄存器
 posted on 2024-08-03 20:51  Dylaris  阅读(47)  评论(0)    收藏  举报