实模式下BootLoader栈初始化异常:为何添加栈代码后中断失效?
x86汇编引导加载器栈初始化导致BIOS中断失效问题分析
你的引导加载器代码
org 0x7C00 section boot start=0x7C00 ; initializing the stack mov ax,0xF000 mov ss,ax mov sp,0xFFFF mov bp,0xFFFF ; loading the additional sectors mov ah,0x02 mov al,0x02 ; number of sectors mov ch,0x00 ; cylinder mov cl,0x02 ; sector 2 mov dh,0x00 ; head ; address = es*0x10 + bx xor bx,bx ; moving 0 to es mov ds,bx mov es,bx mov bx,0x8000 int 0x13 jmp 0x8000 times 510-($-$$) db 0 db 0x55, 0xaa ; Ending the boot sector
问题描述
移除栈初始化代码时,引导加载器可正常工作,BIOS中断能执行;但添加回该代码后,程序无任何反应,中断也无法工作。
问题原因
你把栈设置到了BIOS只读ROM区域,这是核心错误:
- 实模式下,
0xF000段对应的物理地址范围是0xF0000到0xFFFFF,这片区域是BIOS的只读ROM存储空间,不允许写入操作。 - 栈的增长方向是从高地址向低地址(执行
push指令时SP会递减),当你执行int 0x13中断时,BIOS会自动把标志寄存器、CS、IP依次压入栈中,这会触发对只读ROM的写入操作,直接引发硬件错误,导致程序崩溃无响应。
而移除栈初始化代码时能正常工作,是因为BIOS在加载引导加载器前,已经默认设置了一个位于可写RAM区域的栈,此时所有栈操作都是合法的,中断自然能正常执行。
修复方案
把栈初始化到可写的常规RAM区域,比如选择引导加载器代码(0x7C00)以下的安全区域,或者常规内存的高端:
示例修复代码
; 初始化栈到常规RAM的高端区域(物理地址0x0FFFF) mov ax, 0x0000 mov ss, ax mov sp, 0xFFFF mov bp, 0xFFFF
或者更稳妥的,避免栈覆盖引导加载器本身:
; 栈设置在0x0000:0x7000,物理地址0x7000,低于引导加载器的0x7C00 mov ax, 0x0000 mov ss, ax mov sp, 0x7000 mov bp, 0x7000
内容的提问来源于stack exchange,提问作者Djebbar Abderrahmene
相关产品推荐
相关产品推荐

