BY eHWRITTEN ON HALO2 MIN READ

stack补习

栈指针(sp)与call / ret、push / pop、中断 很好,这是一个核心问题,理解了你就真的掌握了 BIOS 编程的关键点之一。 ⸻   栈指针(SP, Stack Pointer) 是一个非常基础但非常重要的东西,它决定了你程序里 call / ret、push / pop、中断等功能

栈指针(sp)与call / ret、push / pop、中断 很好,这是一个核心问题,理解了你就真的掌握了 BIOS 编程的关键点之一。

  栈指针(SP, Stack Pointer) 是一个非常基础但非常重要的东西,它决定了你程序里 call / ret、push / pop、中断等功能能否正常执行。

✅ 什么是栈(Stack)? • 栈就是一块“倒着长”的内存区域,用来保存: • call 语句保存的返回地址 • push 压入的变量 • 中断自动压入的寄存器等 • 栈通过 SP(低地址) 和 SS(段地址) 来管理,从高地址往低地址增长:

内存高地址 ↓ [返回地址] [变量] [旧寄存器] … ↑ 栈顶(SP)

✅ 为什么不能设置 SP=0x7c00?

因为: 1. 你的程序本身就是从 0x7c00 开始执行的 2. 如果你把 SP 也设置成 0x7c00,接下来执行 call delay,就会把返回地址压入 0x7bfe、0x7bfd 等地方(往下增长),直接把你的代码给覆盖了 3. 然后你 ret 回来时跳到垃圾代码,程序就死了(你看到的就是“彩虹不执行”)

✅ 什么时候必须设置 SP?

你只要用了以下任何一个功能,就必须确保栈设置得安全: • call / ret • push / pop • BIOS / DOS 中断(它们会用 stack) • 中断处理程序 • 使用宏、函数嵌套等

✅ 那我该怎么设置 SP?

你只要记住:

mov ax, 0 ; 栈段和代码段一致 mov ss, ax mov sp, 0x7e00 ; 设置栈顶到代码段高地址(避开你主程序)

为什么 0x7e00 合适? • 你的代码从 0x7c00 开始,最多不到 512 字节 • 0x7e00 比 0x7c00 + 0x0200 = 0x7e00 高出两个扇区,很安全

✅ 图示理解:

内存布局:

0000:7c00 ——————> 你的 BIOS 程序开始(比如清屏/打印) … 0000:7dff ——————> 程序结尾 0000:7e00 ——————> 👈 栈顶从这里开始,往下增长

✅ 小结一句话:

设置栈指针,就是告诉 CPU:你需要用临时空间(保存返回地址、参数等),这块区域放在哪才不会破坏程序。

如果你愿意,我可以带你做一个实验:把 sp 改回 0x7c00,你会看到彩虹循环无法进行,甚至清屏都变花。这就是栈覆盖的结果。你想做一下试验吗?