从0创建一个OS (五) boot sector中的栈
本节将学习16bit模式下,汇编语言中的栈的基本操作
关键字:stack
目标:学习如何使用栈
理论基础
在我们学习其它高级语言,如C++,Java时,肯定会接触到栈这个概念,在汇编中栈的基础操作只有2种,入栈和出栈.
- 在16bit模式下
- 栈底由16bit寄存器BP负责记录
- 栈顶由16bit寄存器SP负责记录
- 栈中的一个单元占2个字节
- 栈底的2字节空间不参与存储任务
- 入栈操作: 先使SP = SP - 2,再向新的SP指向的地址写入2个字节
- 出栈操作: 先将SP指向的地址中的内容赋值到目标寄存器,然后SP = SP + 2
- 注意入栈操作会导致SP向低地址方向移动,出栈反之,这就是所谓的栈的反向增长
- 栈先入的数据后出栈,即先入后出原则
这里画一张图供大家理解.
源码实践
; ============================================================== ; 文件名: 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部分