找回密码
 register

QQ登录

只需一步,快速开始

查看: 27|回复: 0

[汇编语言] [零基础入门学习]·16·寄存器(内存访问)·问题3.7~3.10·栈的综述

[复制链接]

[汇编语言] [零基础入门学习]·16·寄存器(内存访问)·问题3.7~3.10·栈的综述

[复制链接]
  • 打卡等级:热心大叔
  • 打卡总天数:91
  • 打卡月天数:14
  • 打卡总奖励:91
  • 最近打卡:2025-01-15 02:59:34
Waylee

主题

0

回帖

1万

积分

仙帝

积分
11890
Waylee 2024-12-28 22:17 | 显示全部楼层 |阅读模式 | Google Chrome | Windows 10

马上注册,查看网站隐藏内容!!

您需要 登录 才可以下载或查看,没有账号?register

×


问题 3.7

编程,将10000H~1000FH这段空间当作栈,初始状态栈是空的,将AX、BX、DS中的数据入栈。

思考后看分析。

分析:

代码如下。

mov ax,1000H
mov ss,ax       ;设置栈的段地址,SS=1000H,不能直接向段寄存器SS中送入数据,所以用ax中转。
mov sp,0010H    ;设置栈顶的偏移地址,因栈为空,所以sp=0010H。如果
            ;对栈为空时SP的设置还有疑问,复习3.7节、问题3.6
            ;上面的三条指令设置栈顶地址。编程中要自己注意栈的大小。
push ax
push bx
push ds

问题 3.8

编程:
(1)将10000H~1000FH这段空间当作栈地址,初始状态是空的;
(2)设置AX=001AH,BX=001BH
(3)将AX、BX中的数据入栈;
(4)然后将AX、BX清零;
(5)从栈中恢复AX、BX原来的内容。

思考后看分析。

分析:

代码如下。

mov ax,1000H
mov ss,ax
mov sp,0010H    ;初始化栈顶,栈的情况如图3.15(a)所示
mov ax,001AH
mov bx,001BH
push ax
push bx     ;ax、bx入栈,栈的情况如图3.15(b)所示
sub ax,ax   ;将ax清零,也可以用mov ax,0,
            ;sub ax ax的机器码为2个字节,
            ;mov ax,0的机器码为3个字节。
sub bx,bx
pop bx      ;从栈中恢复ax,bx原来的数据,当前栈顶的内容是box中原来的内容: 
pop ax      ;001HB,ax中原来的内容001AH在栈顶的下面,所以要先pop bx,然后再pop ax。

001.webp

从上面的程序我们看到,用栈来暂存以后需要恢复的寄存器中的内容时,出栈的顺序要和入栈的顺序相反,因为最后入栈的寄存器的内容在栈顶,所以在恢复时,要最先出栈。

问题 3.9

编程:

(1)将10000H~1000FH这段空间当作栈,初始状态栈为空的;
(2)设置AX=001AH,BX=001BH;
(3)利用栈,交换AX和BX中的数据。

思考后看分析。

分析:

代码如下。

mov ax,1000H
mov ss,ax
mov sp,0010H    ;初始化栈顶,栈的情况如图3.16(a)所示
mov ax,001AH
mov bx,001BH
push ax
push bx     ;ax、bx入栈,栈的情况如图3.16(b)所示
pop ax      ;当前栈顶的数据是bx中原来的数据:001BH
            ;所以先pop ax,ax=001BH
pop bx      ;执行pop ax后,栈顶的数据为ax原来的数据;
            ;所以再pop bx,bx=001AH;

002.webp

问题 3.10

如果要在10000H处写入字型数据2266H,可以用以下的代码完成:

mov ax,1000H
mov ds,ax
mov ax,2266H
mov [0],ax

补全下面的代码,使他能够完成同样的功能:在10000H处写入字型数据2266H。
要求:不能使用“mov 内存单元,寄存器”这类指令。

_____________
_____________
_____________
mov ax,2266H
push ax

思考后看分析。

分析

我们来看需补全代码的最后两条指令,将ax中的2266H压入栈中,也就是说,最终应由push ax将2266H压入10000H处。问题的关键就在于:如何使push ax访问的内存单元是10000H。

push ax是入栈指令,它将在栈顶之上压入新的数据。一定要注意:它执行过程是,先将记录栈顶偏移地址的SP寄存器中的内容减2,使得SS:SP指向新的栈顶单元,然后再将寄存器中的数据送入SS:SP指向的新的栈顶单元。

所以,要在执行push ax之前,将SS:SP指向10002H(可以设SS=1000H,SP=0002H),这样,在执行push ax的时候,CPU先将SP=SP-2,使得SS:SP指向10000H,再将ax中的数据送入SS:SP指向的内存单元处,即10000H处。

完整的程序如下。

mov ax,1000H
mov ss,ax
mov sp,2
mov ax,2266H
push ax

从问题3.10的分析可以看出,push、pop实质上就是一种内存传送指令,可以在寄存器和内存之间传送数据,与mov指令不同的是,push和pop指令访问的内存单元的地址不是在指令中给出的,而是由SS:SP指出的。同时,push和pop指令还要改变SP中的内容。

我们要十分清楚的是,push和pop指令与mov指令不同,CPU执行mov指令只需一步操作,就是传送,而执行push、pop指令却需要两步操作。执行push时,CPU的两步操作是:先改变SP,后向SS:SP处传送。执行pop时,CPU的两步操作是:先读取SS:SP处的数据,后改变SP。

注意,push、pop等栈操作指令,修改的知识SP。也就是说,栈顶的变化范围最大为:0~FFFFH。

提供:SS、SP指示栈顶;改变SP后写内存的入栈指令;读内存后改变SP的出栈指令。这就是8086CPU提供的栈操作机制。

栈的综述

  1. 8086CPU提供了栈操作机制,方案如下。
    • 在SS、SP中存放栈顶的段地址和偏移地址;
    • 提供入栈和出栈指令,它们根据SS:SP指示的地址,按照栈的方式访问内存单元。
  2. push指令的执行步骤:①SP=SP-2;②向SS:SP指向的字单元中送入数据。
  3. pop指令的执行步骤:①从SS:SP指向的字单元中读取数据;②SP=SP+2
  4. 任意时刻,SS:SP指向栈顶元素。
  5. 8086CPU只记录栈顶,栈空间的大小我们要自己管理。
  6. 用栈来暂存以后需要恢复的寄存器的内容时,寄存器出栈的顺序要和入栈的顺序相反。
  7. push、pop实质上是一种内存传送指令,注意它们的灵活运用。

栈是一种非常重要的机制,一定要深入理解,灵活掌握。

您需要登录后才可以回帖 登录 | register

本版积分规则

雪舞知识库 | 浙ICP备15015590号-1 | 萌ICP备20232229号|浙公网安备33048102000118号 |天天打卡

GMT+8, 2025-1-15 17:48 , Processed in 0.124957 second(s), 7 queries , Redis On.

Powered by XueWu Licensed

Copyright © Tencent Cloud.

快速回复 返回顶部 返回列表