bochs hlp 中的 FASM 引导程序
FASM bootloader in bochs hlp
我试图在 fasm 汇编上编写自己的引导加载程序,但没有成功。
结果:
预取:EIP 00010000 > CS.limit 0000ffff
代码:
org 0x7C00
mov ax, 0x02
int 0x10
mov si, boot_msg
call printf
mov al, 0x01 ; secror to read
mov bx, 0x7E00 ; dest
mov cx, 0x0002 ; cylinder:sector
mov dl, 0x01 ; floppy
call disk_read
mov ax, 0x7E00
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
jmp 0x7E00:0x0000
include 'disk.asm'
include 'printh.asm'
boot_msg db 'R-OS BOOTLOADER
',\
'KERNEL CHS 0 0 1', 0x00
times 510-$+$$ db 0x00
dw 0xAA55
;;;;;;;;; kernel! ;;;;;;;;;;
org 0x7E00
mov ah, 0x0E
mov al, 'X'
int 0x10
cli hlt
times 4096-512-$+$$ db 0x00
disk.asm:
disk_read:
pusha
mov si, 0x02
.top:
mov ah, 0x02
int 0x13
jnc .end
xor ah, ah
int 0x13
jnc .top
jc .err
.end:
popa
ret
.msg db 'disk rw err', 0x00
.err:
popa
pusha
mov ah, 0x0E
mov si, .msg
jmp .l
.l:
lodsb
cmp al, 0x00
je .end
int 0x10
printh.asm只有打印功能。
我不明白,为什么它不起作用。我尝试了很多解决方案的变体,但没有一个在这个列表中起作用。
求求你帮忙
要成功使用BIOS.ReadSectors函数02h,您需要设置它的所有参数!你没有初始化ES
段寄存器,也没有在DH
寄存器中指定头号。大概你认为所有的寄存器都是从零开始的,但事实并非如此!您的引导加载程序接收的唯一寄存器是 DL
寄存器,其中包含引导驱动器的编号。这将是您需要提供给此功能的号码。
您正在加载偏移地址 0x7E00 处的附加扇区。因为ES=0
(假设),这是分段地址0x0000:0x7E00。您可以通过多种方式 jmp
到此地址,但如果您想使用零偏移量来完成此操作,则段部分必须是 0x07E0。这就是分段的工作原理。
您可以在 () and in Michael Petch's answer at () 的回答中阅读有关引导加载程序的更多信息。
这是一个改进版本:
ORG 0x7C00
xor ax, ax ; Setup segment registers in accordance with the `ORG 0x7C00`
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0x7C00
cld ; Once at the top of every program
mov ax, 0x0003
int 0x10
mov si, boot_msg
call printf
mov al, 1 ; Number of sectors to read
mov bx, 0x7E00 ; ES:BX
mov cx, 0x0002 ; Cylinder, Sector
mov dh, 0 ; Head, DL is bootdrive
call disk_read
mov ax, 0x07E0 ; How segmentation works!
mov ds, ax
mov es, ax
jmp 0x07E0:0x0000
include 'disk.asm'
include 'printh.asm'
boot_msg db 'R-OS BOOTLOADER
',\
'KERNEL CHS 0 0 1', 0
times 510-($-$$) db 0
dw 0xAA55
;;;;;;;;; kernel! ;;;;;;;;;;
ORG 0x7E00
mov bh, 0 ; Don't forget to mention the DisplayPage
mov ah, 0x0E
mov al, 'X'
int 0x10
cli
hlt
jmp $-2
times 4096-512-($-$$) db 0
在 disk.asm 文件中,您试图实现重试计数,但您忘记在发生错误时实际减少计数器。
此外,如果您在此处显示错误消息,那将是致命的,因此请暂停代码。
再次改进版本:
disk_read:
pusha
mov si, 5 ; Retry count
.top:
mov ah, 0x02
int 0x13
jnc .OK
mov ah, 0x00
int 0x13
dec si
jnz .top ; More tries
jmp .fatal
.OK:
popa
ret
.msg db 'disk rw err', 0
.fatal:
mov bh, 0 ; Don't forget to mention the DisplayPage
mov ah, 0x0E
mov si, .msg
lodsb
.next:
int 0x10
lodsb
cmp al, 0
jne .next
cli
hlt
jmp $-2
printh.asm just have print functions.
包含尽可能多的信息很重要!在我上面改进的代码中,我假设 printf 不会破坏 DL
寄存器。
请确保它至少保留 DX
.
如果您将代码包含在 printh.asm 文件中,我已经为您验证过了...
我试图在 fasm 汇编上编写自己的引导加载程序,但没有成功。
结果: 预取:EIP 00010000 > CS.limit 0000ffff
代码:
org 0x7C00
mov ax, 0x02
int 0x10
mov si, boot_msg
call printf
mov al, 0x01 ; secror to read
mov bx, 0x7E00 ; dest
mov cx, 0x0002 ; cylinder:sector
mov dl, 0x01 ; floppy
call disk_read
mov ax, 0x7E00
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
jmp 0x7E00:0x0000
include 'disk.asm'
include 'printh.asm'
boot_msg db 'R-OS BOOTLOADER
',\
'KERNEL CHS 0 0 1', 0x00
times 510-$+$$ db 0x00
dw 0xAA55
;;;;;;;;; kernel! ;;;;;;;;;;
org 0x7E00
mov ah, 0x0E
mov al, 'X'
int 0x10
cli hlt
times 4096-512-$+$$ db 0x00
disk.asm:
disk_read:
pusha
mov si, 0x02
.top:
mov ah, 0x02
int 0x13
jnc .end
xor ah, ah
int 0x13
jnc .top
jc .err
.end:
popa
ret
.msg db 'disk rw err', 0x00
.err:
popa
pusha
mov ah, 0x0E
mov si, .msg
jmp .l
.l:
lodsb
cmp al, 0x00
je .end
int 0x10
printh.asm只有打印功能。
我不明白,为什么它不起作用。我尝试了很多解决方案的变体,但没有一个在这个列表中起作用。
求求你帮忙
要成功使用BIOS.ReadSectors函数02h,您需要设置它的所有参数!你没有初始化ES
段寄存器,也没有在DH
寄存器中指定头号。大概你认为所有的寄存器都是从零开始的,但事实并非如此!您的引导加载程序接收的唯一寄存器是 DL
寄存器,其中包含引导驱动器的编号。这将是您需要提供给此功能的号码。
您正在加载偏移地址 0x7E00 处的附加扇区。因为ES=0
(假设),这是分段地址0x0000:0x7E00。您可以通过多种方式 jmp
到此地址,但如果您想使用零偏移量来完成此操作,则段部分必须是 0x07E0。这就是分段的工作原理。
您可以在 (
这是一个改进版本:
ORG 0x7C00
xor ax, ax ; Setup segment registers in accordance with the `ORG 0x7C00`
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0x7C00
cld ; Once at the top of every program
mov ax, 0x0003
int 0x10
mov si, boot_msg
call printf
mov al, 1 ; Number of sectors to read
mov bx, 0x7E00 ; ES:BX
mov cx, 0x0002 ; Cylinder, Sector
mov dh, 0 ; Head, DL is bootdrive
call disk_read
mov ax, 0x07E0 ; How segmentation works!
mov ds, ax
mov es, ax
jmp 0x07E0:0x0000
include 'disk.asm'
include 'printh.asm'
boot_msg db 'R-OS BOOTLOADER
',\
'KERNEL CHS 0 0 1', 0
times 510-($-$$) db 0
dw 0xAA55
;;;;;;;;; kernel! ;;;;;;;;;;
ORG 0x7E00
mov bh, 0 ; Don't forget to mention the DisplayPage
mov ah, 0x0E
mov al, 'X'
int 0x10
cli
hlt
jmp $-2
times 4096-512-($-$$) db 0
在 disk.asm 文件中,您试图实现重试计数,但您忘记在发生错误时实际减少计数器。
此外,如果您在此处显示错误消息,那将是致命的,因此请暂停代码。
再次改进版本:
disk_read:
pusha
mov si, 5 ; Retry count
.top:
mov ah, 0x02
int 0x13
jnc .OK
mov ah, 0x00
int 0x13
dec si
jnz .top ; More tries
jmp .fatal
.OK:
popa
ret
.msg db 'disk rw err', 0
.fatal:
mov bh, 0 ; Don't forget to mention the DisplayPage
mov ah, 0x0E
mov si, .msg
lodsb
.next:
int 0x10
lodsb
cmp al, 0
jne .next
cli
hlt
jmp $-2
printh.asm just have print functions.
包含尽可能多的信息很重要!在我上面改进的代码中,我假设 printf 不会破坏 DL
寄存器。
请确保它至少保留 DX
.
如果您将代码包含在 printh.asm 文件中,我已经为您验证过了...