汇编--学习笔记(九)-堆栈

堆栈:“先进后出”的存储区,存在于堆栈段中,SP在任何时候都指向栈顶。

一、PUSH指令(字入栈)

1、格式:PUSH 源操作数(字)

PUSH    AX   ;AX进栈

2、功能
(1)首先将栈顶指针减2,即(SP)-2=>SP;
(2)然后将源操作数(字)=>((SP)+1,(SP))。(高字节,低字节)
即执行操作:

  • (SP)<– (SP)-2
  • ((SP)+1,(SP)) <– (源操作数)

3、说明
高字节先进栈,低字节在栈顶
这里写图片描述


二、POP指令(字出栈)

1、格式:POP 目的操作数

POP AX   ;恢复AX

2、功能
(1)首先将栈顶的字((SP)+1,(SP))=>目的操作数;
(2)然后将堆栈指针SP加2,即(SP)+2=>SP。
即执行操作:

  • (DST)<– ((SP)+1,(SP))
  • (SP) <– (SP)+2

这里写图片描述


三、堆栈操作说明

1、栈顶SP指向数据
 因为堆栈指针SP总是指向已经存入数据的栈顶(不是空单元),所以PUSH指令时先将(SP)减2,后将内容压栈(即先修改SP使之指向空单元,后压入数),而POP是先从栈顶弹出一个字,后将堆栈指针SP加2.
2、对代码段寄存器
 PUSH CS是合法的,但POP CS是不合法的。
3、堆栈特点—–FILO
 因为SP总是指向栈顶,而用PUSH和POP指令存取数时都是在栈顶进行的,所以堆栈是“先进后出”或叫“后进先出”的。栈底在高地址,堆栈是从高地址向低地址延伸的,所以栈底就是最初的栈顶。
4、按字访问
 用PUSH指令和POP指令时只能按字访问堆栈,不能按字节访问堆栈。
5、不影响标志
 PUSH和POP都不影响标志。
6、不能用立即寻址方式
PUSH 1234H ;错误!!


小例子:

这里就是对AX清零。

PUSH    DS
SUB AX,AX
PUSH    AX
...
...
RET

下面就是一个保护现场的代码

PUSH    AX
PUSH    BX
PUSH    CX
......;期间用到了AX、BX、CX
POP CX
POP BX
POP AX

从键盘上键入10个字符,然后与键入字符的先后相反的顺序显示出来。(使用堆栈的办法)
分析:因为堆栈是“后进先出”的,因此,利用堆栈作为输出缓冲区极易实现按逆序输出。
 分配一个256个字的堆栈缓冲区,在其低字节中存放从键盘上键入的字符。我们将从键盘上接受来的10个字符依次进栈,存放在这片堆栈区里,然后再从最后一个字单元开始,弹出堆栈,即可逆序把它们显示出来。

STACKS SEGMENT PARA STACK 'STACK'
        DW 256 DUP(?) ;堆栈只能是一个字一个字的操作,多预留点栈空间
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,SS:STACKS
START:
    MOV AX,STACKS  ;这里就用STACKS,以前都是DATAS
    MOV SS,AX      ;这里就用SS了,以前都是用DS
    MOV CX,10   ;输入10个字符=>堆栈
READ:
    MOV AH,01H
    INT 21H
    PUSH AX    ;堆栈操作都是‘字’,不能用AL,浪费了AH的空间
    LOOP READ  ;读10个字符

    MOV DL,0AH  ;显示回车
    MOV AH,02H
    INT 21H
    MOV DL,0DH  ;显示换行
    INT 21H

    MOV CX,10   ;从栈顶依次弹出10个字符输出
DISP:
    POP DX      ;显示
    MOV AH,02H
    INT 21H
    LOOP DISP  ;显示10个字符

    MOV AH,4CH
    INT 21H
CODES ENDS
    END START

四、堆栈操作说明

(1)堆栈指针SP的自动赋值
 只要在堆栈段的SEGMENT伪指令中带有组合类型参数和组名参数:STACK ‘STACK’,汇编程序就会自动把栈底(也是最初的栈顶)的位移量赋给堆栈指针SP。
(2)空间有浪费
 因堆栈只对字操作,故10个字符的高字节虽然入了栈,但未用,浪费了一半空间。
(3)堆栈大小留有余地
 虽然只输入10个字符,但堆栈定义了256个字(100H)。一般定义时适当留有余地。

  • 9
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值