汇编:栈
本文最后更新于:2022年11月8日 上午
栈是一种常用的数据结构,具有先进后出的特点FILO(First In Last out)
栈
汇编中栈的使用
栈是一种常用的数据结构,具有先进后出的特点FILO(First In Last out)
,汇编中也有栈的概念,通过PUSH
和 POP
来操作栈
例如 push ax
表示将ax的值存到栈顶中,pop bx
表示将栈顶数据取出并给bx
赋值。在8086CPU
中,通过SS
段寄存器SP
寄存器来记录栈顶的位置(猜测SS和SP 寄存器的开头的S表示的是Stack
)
PUSH指令
POP指令
这里需要注意pop
指令,pop
指令之前我们知道pop bx
表示将栈顶数据取出并给bx
赋值,此时栈中其实还是保留原有的数据的,只是SP
寄存器的偏移量向前+2
了,下一次push
的时候才会把数据覆盖掉
栈越界的情况
当我们将一块区域视为栈空间后,SS
和SP
永远只会指向当前栈顶的位置,在8086CPU
中,它没有单独的寄存器来记录栈顶上限和栈底。所以在8086CPU
要自己操心栈顶越界的情况
push 导致栈越界
pop导致栈越界
PUSH, POP 在汇编中的具体使用
在汇编中,栈空间也是内存的空间的一部分,他只是可以通过一种特殊的方式进行访问的内存空间。主要就是通过push
和pop
来对栈空间进行操作
在对栈空间进行操作是,push
和pop
有以下几种用法
栈空间的操作是以字为单位的,也就是一个8086CPU
中一个寄存器的容量,也是一个字(两个字节,两个8位),所以以下的操作都是以字为单位的,可以注意看下
push 寄存器
push 段寄存器
push 内存单元
------------
pop 寄存器
pop 段寄存器
pop 内存单元
比如
mov ax, 1000H
mov ds, ax // 将段地址设置为 1000H
push [0] // 将 1000:0000 的处的字压入到栈中
pop [2] // 出栈,将出栈的数据送入到 1000:0002 的位置
示例
- 将
10000H - 1000FH
这段空间当做栈,初始状态是空的 - 设置
ax=001AH, bx=001BH
- 将
ax,bx
添加到栈中 - 将
ax,bx
清零(值变成0) - 从栈中恢复
ax,bx
的数据
mov ax, 1000H
mov ss, ax
mov sp, 00010;
mov ax, 001A;
mov bx, 001B;
push ax;
push bx;
sub ax, ax; // 自己减去自己,也可以用 mov ax, 0; sub ax, ax 的机器码为2个字节, mov ax, 0 的字节码是3个字节
sub bx, bx;
pop bx; // 先从栈顶取出内容
pop ax;
注意栈顶的位置,因为每次往栈中添加数据SP是做减的操作的,所以初始化时栈顶会设置在栈区域的最高位置。例如 push ax; sp -=2;
测试1
如果要在10000H中写入字型数据2266H,可以用以下方式
mov ax, 10000H
mov ds, ax
mov [0], 2266H
现在要求不能 mov 寄存器, 内存单元的方式来编写,换成以下方式
mox ax, 1000
mov ss, ax
mov sp, 2; // 这里需要注意先将sp=sp+2, 才能保证写入的时候写入的是1000H的位置
mov ax, 2266;
push ax;
push和pop的具体操作
push
和pop
执行的操作和mov
不一样,mov
指令CPU
只需要执行一步操作,就是传送。而push
和pop
需要两步。
push
1,先改变sp
2,再向ss:sp
的位置传送
pop
1, 先从ss:sp
的位置取出数据
2,再改变sp
push
和pop
的操作都是在修改sp
,sp
是一个16
位的寄存器,也就是说栈顶的变化范围最大是 0-FFFFH
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议,转载请注明出处。