栈Stack和段寄存器SS,SP(学习汇编)

1. 栈有2个基本操作:入栈、出栈 

2. 栈顶的元素总是最后入栈,最先出栈;后进先出。 

3. 8086CPU提供入栈和出栈的指令,最基本的两个是 PUSH(入栈) 和 POP(出栈)

    push ax 表示将AX寄存器的内容送入栈中, pop ax 表示从栈顶取出数据送入AX寄存器中。

    8086CPU的入栈和出栈操作都是以字(word)为单位的。

4. 8086CPU中,段寄存器SS:存放栈顶段地址,段寄存器SP: 存放栈顶的偏移地址。 

5. 任意时刻:SS:SP 指向栈顶元素。

6. 8086CPU不保证我们对栈的操作是否会越界。

7. 栈顶是低地址单元, 栈底是高地址单元。 

8.  push 指令的执行步骤:

    (1) SP = SP - 2 (偏移地址减少,即往低地址处偏移[栈顶方向])

    (2) 向SS:SP指向的字单元中送入数据 

9. pop 指令的执行步骤:

    (1) 从SS:SP指向的字单元中读取数据

    (2) SP = SP + 2       (偏移地址增加,即往高地址处偏移[栈低方向]) 

10. 8086CPU只记录栈顶,栈空间的大小要我们自己管理。

11. 例子:

      如果将10000H ~ 1000FH 这段空间作为栈,初始状态栈是空的,此时SS=1000H,SP = ?

     解答:

     首先,低地址单元在栈顶方向,高地址单元在栈低方向 。

     低地址

     10000H

      。

      。

      。

     1000DH

     1000EH

     1000FH

     -------------------

     10010H                          <-------------SS:SP指向栈空间最高地址单元的下一个单元。

     假设 AX = 2266H, 因为8086CPU的入栈和出栈操作都是以字为单位的 。所以,结果看下图示。

     10000H

      。

      。

      。

     1000DH

     1000EH    66H   (AL)      <-------------SS:SP

     1000FH    22H   (AH)

     --------------------------------------------

     10010H

     以10000H ~ 1000FH这段空间为栈空间,SS=1000H,栈空间大小为16个字节。

     当初始状态栈为空时,SP = 0010H。

12. 编程

      (1) 将10000H~1000FH这段空间当作栈,初始状态栈是空的。

      (2) 设置AX寄存器 = 001AH, BX寄存器 = 001BH。

      (3) 利用栈,交换AX、BX寄存器中的数据。    

[cpp] view plaincopy
 
  1. mov ax, 1000H  
  2. mov ss, ax  
  3. mov sp, 0010H  
  4. mov ax, 001AH  
  5. mov bx, 001BH  
  6. push ax  
  7. push bx  
  8. pop ax  
  9. pop bx  

 13. 编程

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

[cpp] view plaincopy
 
  1. mov ax, 1000H  
  2. mov ds, ax  
  3. mov ax, 2266H  
  4. mov [0], ax  

      要求:不能使用“ mov 内存单元, 寄存器"这类指令,完成上面的功能。    

[cpp] view plaincopy
 
  1. mov ax, 1000H  
  2. mov ss, ax  
  3. mov sp, 2  
  4. mov ax, 2266H