文章目录

  • 前言
  • 一、概念
  • 二、栈
  • 1.数据
  • 入栈
  • 出栈
  • 2.指令
  • push
  • pop
  • 3.设置
  • 4.栈顶越界
  • 5.栈的作用
  • 主要作用
  • 临时作用



前言

本文记录汇编语言中栈的概念和内容

一、概念

栈在汇编语言中,被定义为一段连续的内存单元
与数据结构类似,有数据入栈,出栈和栈顶的概念,但是在汇编语言中,我们可以直接接触到栈顶,也就是有相关标记表明栈顶的存在

二、栈

1.数据

在汇编语言中,入栈push和出栈pop可以对数据进行操作,这里进行操作的数据有如下的特征

  • 数据从寄存器和内存中来
  • 数据是字型数据,操作的是16位寄存器或内存中的字型数据
入栈

16位寄存器或内存中的字型数据放到栈顶标记的上方
修改栈顶标记

出栈

将栈顶标记的字型数据 放到16位寄存器或内存中
修改栈顶标记

从上面我们可以看出,栈顶标记本质是一个内存地址,往栈(连续内存区域中)写入和拿出数据,都是针对相关内存地址进行修改;而在8086CPU中,在任意时刻,将段地址寄存器SS偏移地址寄存器SP所组合出来的内存地址当作栈顶标记!

2.指令

push

push ax 所做的事情如下
修改SP寄存器中的数值:SP=SP-2
将AX中的字型数据->放到SS:SP所组合的内存地址中,入栈

pop

pop bx
将SS:SP所组合出的内存地址中的字型数据->bx
修改栈顶标记 SP=SP+2,出栈

3.设置

所谓栈所占据的空间,无非就是栈的起始地址和栈顶标记所在位置之间的距离

例如以下代码

mov ax,2000
mov ss,ax
mov ss,2000

mov sp,16
push ax

mov ax,2233
push ax
push ax 
push ax

pop bx
pop cx
pop dx

这段代码便将栈的起始位置的段地址设置为2000,且将栈顶的偏移地址设置为16,这种情况下,栈中支持存储的字型数据为8个

通常,将栈设定位为16的倍数

4.栈顶越界

当push入栈数据大小或者pop出栈数据大小大于栈顶标记与栈的起始地址所组成的栈空间时,便会发生栈顶越界问题,但汇编语言并不会像其他高级语言那样直接抛出异常和错误

汇编语言在任意时刻,都会将ss:sp所组成的地址认为为栈顶标记

例如以下情况

把一个字段里面的数据全部加起来Java怎么写 将一个字节数据入栈(push al)_汇编语言


在这段代码中,可以清楚地看到sp寄存器中的数值减到0后会跳转至FFFE,而这段存储空间所存储的指令或数据我们不得而知,也就是说,在汇编语言中,虽然栈顶越界不会带来直接的异常错误,但如果我们通过push或者pop破坏我们原已有的指令或者数据,也是十分致命的

从以上我们可以看到,SP寄存器的变化范围为0~FFFFH,也就是65536个字节,32768个字型数据,也就是我们原来所说的64KB

5.栈的作用

主要作用

栈的主要作用:临时性地保存数据

在call指令和ret指令中,call转移指令临时地将吓一跳指令所在的地址保存了栈中栈顶位置,再通过ret指令从栈顶将保存的指令拿出

临时作用
  • 用于数据交换
    例:
mov ax,1122
mov bx,3344
push ax
push bx
pop ax
pop bx
mov ax,1000H
mov ds,ax
push ds:[0]
push ds:[2]
pop ds:[0]
pop ds:[2]