从0创建一个OS (五) boot sector中的栈

本节将学习16bit模式下,汇编语言中的栈的基本操作

关键字:stack

目标:学习如何使用栈

理论基础

在我们学习其它高级语言,如C++,Java时,肯定会接触到栈这个概念,在汇编中栈的基础操作只有2种,入栈和出栈.

  1. 在16bit模式下
  2. 栈底由16bit寄存器BP负责记录
  3. 栈顶由16bit寄存器SP负责记录
  4. 栈中的一个单元占2个字节
  5. 栈底的2字节空间不参与存储任务
  6. 入栈操作: 先使SP = SP - 2,再向新的SP指向的地址写入2个字节
  7. 出栈操作: 先将SP指向的地址中的内容赋值到目标寄存器,然后SP = SP + 2
  8. 注意入栈操作会导致SP向低地址方向移动,出栈反之,这就是所谓的栈的反向增长
  9. 栈先入的数据后出栈,即先入后出原则

这里画一张图供大家理解.
在这里插入图片描述

源码实践

; ==============================================================
; 文件名: boot_sect_stack.asm
; 本程序展示入栈和出栈过程中,栈内的内容如何变化
; sp(stack pointer) 栈指针
; bp(base pointer) 栈底指针
; ==============================================================

mov ah, 0x0E ; 为使用0x10号中断的显示到屏幕子功能做准备

mov bp, 0x8000 ; 0x8000离0x7C00比较远,可以防止覆盖0x7C00附近的区域
mov sp, bp ; 栈空时sp指向bp

; 依次入栈'A'、'B'、'C',但其每个字符都占1个字节,同时16bit模式下栈的操作
; 基础大小为2个字节,因此在这里,每次入栈的高8bit会以0填充
push 'A'
push 'B'
push 'C'

; 展示栈从空增长的过程中,栈指针指向的地址如何从高到低
mov al, [0x7ffe] ; 0x8000 - 2 (16bit模式下,栈中一个单元为2个字节,也叫一个字)
int 0x10

mov al, [0x7ffc] ; 0x7ffe - 2
int 0x10

mov al, [0x7ffa] ; 0x7ffc - 2
int 0x10

; 利用出栈指令pop,将我们存储到栈中的“ABC”拿出来
; 由于pop指令每次要出栈一个完整的word(2个字节),所以我们需要一个16bit的寄存器放置
pop bx
mov al, bl
int 0x10 ; 这里会打印出’C‘

pop bx
mov al, bl
int 0x10 ; 这里会打印出’B‘

pop bx
mov al, bl
int 0x10 ; 这里会打印出'A'

; 目前栈又变为空栈,显示为空字符(也有可能是乱码)
mov al, [0x8000]
int 0x10


jmp $
times 510 - ($ - $$) db 0
dw 0xAA55

 

编译并Boot

具体编译并Boot方法参见从0创建一个OS (二) boot_sector的"裸骨架"的编译、Boot部分

结果

在这里插入图片描述

posted @ 2020-11-18 17:01  EwanHai  阅读(93)  评论(0编辑  收藏  举报