小白的汇编之路 (三)----栈

小白的汇编之路 (三)下

前言

这一部分将要涉及到栈,假设读者对栈有一定的认识。

栈是一种很有用的“工具”
它和队列区别在于队列是先进先出,栈是先进后出

CPU中的栈机制

在前面我们学过,栈也是一种段,它的段地址存在SS寄存器中,偏移地址存在SP寄存器中,SP我们可以理解为栈顶指针
8086CPU中对栈的操作,例如压栈(PUSH),出栈(POP)都是以字为单位的。
如下图:(表格中黄色部分为栈顶指针所指的内存单元)
假设我们把1001:0000H~1001:000AH这段内存空间作为栈,且其中每个内存单元都是空的,此时栈顶指针指的是栈底(1001:000BH)(此时对应栈0),则此时有SS:1001H,SP:000BH

地址栈0栈1栈2栈3
1000FH??12H12H
10010H8EH8EH
10011H00H00H
10012H00H00H
10013H00H00H
10014H00H00H
10015H00H00H
10016H00H00H
10017H00H00H
10018H00H00H
10019H23H23H23H
1001AH01H01H01H
1001BH????
1001CH????

图A

压栈

对这个栈进行压栈操作,把0123H存入AX寄存器中,再把AX压栈。
代码为:

mov ax,0123H 
push ax  //将ax寄存器的值压入栈中

(此时对应栈1)
压入后,此时SP=SP-2(栈顶指针偏移)
SS:1001H,SP:0009H

越界

若我们此时向栈中压入5个数据,分别是,0000H,0000H,0000H,0000H,8E12H,(此时对应栈2)代码为:

push 0000H 
push 0000H 
push 0000H 
push 0000H 
push 8E12H

此时SS:1000H,SP:000FH
在这一步你或许会有疑惑:我们明明定义10010H~1001AH为栈空间,但是对不在栈空间的内存单元(1000FH)赋了值,这样不会报错么?
事实上8086CPU是不保证使用者对栈的操作不会超界; CPU只关心当前的栈顶在哪里?要执行的指令是什么?
CPU并不知道使用者定义的栈空间的大小;

换句话说就是,对栈的操作是否越界只能由使用者自行管理。
而且由于越界操作可能会对某些存储重要数据的内存单元进行操作,极有可能造成重要数据的破坏,所以这是必须避免的!

出栈

若我们想要将栈顶指针所指的内存单元数据存入AX寄存器中?该怎么办?

pop ax	//将栈顶指针所指的内存单元赋给ax寄存器

(此时对应栈3)
SS:1001H,SP:0001H

PUSH和POP

push和pop实际上是一种内存传送指令,不同于mov指令,push和pop不需要在指令中指明数据存放的位置;push和pop依赖于栈顶指针sp的移动。
由图A不难看出:
当push一个数据进栈时,sp=sp-2;
当pop数据时,sp=sp+2。

栈的大小

之前提过段的大小为64KB,栈也是相同的原理,不过是受SP的影响。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值