我这台32位 DOS的远跳指令不起作用,为什么?
我在用32位创建一个DOS,并且在远跳上遇到了一些问题。
下面是我将数据加载到内存地址0x0000:0x8000的方式:
load_next_boot:
mov ah, 0x02
mov al, 1
mov ch, 0
mov cl, 2
mov dh, 0
mov dl, 0x00
mov bx, 0x8000
int 0x13
jmp 0x0000:0x8000
其次,我核对了第二个扇区是否处于正确的内存地址,这里是第二扇区的主体代码:
[BITS 16]
[ORG 0x8000]
start:
mov ah, 0x0E
mov al, 'A'
int 0x10
cli
mov eax, cr0
or eax, 1
mov cr0, eax
jmp 0x08:protected_mode_start_32
[BITS 32]
protected_mode_start_32:
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
mov esp, 0x90000
mov esi, msg2
mov edi, 0xB8000
call print_string_32
hang:
jmp hang
(我已经用gdt_null、gdt_code和 gdt_data设置了一个全局描述符表(GDT)。问题中我就不展示GDT。)
有人知道为什么远跳不起作用吗?
解决方案
BIOS中断13h ax=0x02(用于在内存中读取并加载磁盘扇区的中断。)使用ES:BX将寄存器转换为一个地址。在这段代码中:
load_next_boot:
mov ah, 0x02
mov al, 1
mov ch, 0
mov cl, 2
mov dh, 0
mov dl, 0x00
mov bx, 0x8000
int 0x13
jmp 0x0000:0x8000
ES寄存器未被赋值,因此其值往往是随机的。
代码应该是这样的:
load_next_boot: ; Label
mov bx, 0x8000 ; Offset
xor ax, ax ; Set ax at 0
mov es, ax ; Set es at ax(0)
mov ah, 0x02 ;
mov al, 16 ; Numbers of segment(Should be greater than 1.)
mov ch, 0 ; Cylinder
mov cl, 2 ; Read sectors starting with sector 2
mov dh, 0 ; Head
mov dl, 0x00 ; Drive
int 0x13
jmp 0x0000:0x8000
此外,我们不能直接给ES赋值,需要使用一个中间寄存器。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。