本节将学习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部分