[英]Trouble with Assembly: Creating a Bootloader
我刚刚启动了一个操作系统类,并在臭名昭着的bootloader实验室中遇到了障碍。 分配的一部分是在Assembly中创建一个512字节的引导加载程序,能够从头开始或多或少地加载给定的内核。 这是我到目前为止所做的代码:
# bootblock.s
# .equ symbol, expression
# These directives set the value of the symbol to the expression
.equ BOOT_SEGMENT,0x07c0
.equ DISPLAY_SEGMENT,0xb800
.text # Code segment
.globl _start # The entry point must be global
.code16 # Real mode
# Start
_start:
jmp over
# OS Size
os_size:
# Area reserved for createimage to write the OS size
.word 0
.word 0
# Routines to print a zero terminated string pointed to by esi
# Overwrites: AX, DS, BX
print:
movw $BOOT_SEGMENT,%ax
movw %ax,%ds
print_loop:
lodsb
cmpb $0,%al
je print_done
movb $14,%ah
movl $0x0002,%ebx
int $0x10
jmp print_loop
print_done:
retw
# Over is where the magic happens
over:
movl $messagetest, %esi
call print
movl $hellostring, %esi
call print
# Allocating the stack
movw $0x0, %ax
movw %ax, %ss
movw $0xffff, %sp
# Booting up at 0x07c0
movw $BOOT_SEGMENT, %ax
movw %ax, %ds
movl $messageboot, %esi
call print
# Resetting the disk drive, setting %dl and calling int 0x13
movb $0x0, %ah
movb $0x80, %dl
int $0x13
# Make says my .os_size = 9 sectors. Setting %al = 9
movb $0x09, %al
# %cl controls which sector to read from. Setting %cl = 2
movb $0x02, %cl
# %dh/%ch control head numbers. I'm not sure how they work; setting them to zero
movb $0x0, %dh
movb $0x0, %ch
# Setting the drive number to 0x80 (Hard drive)
movb $0x80, %dl
# Time to set es:bx to read from the correct place (0:1000)
movw $0x0, %bx
movw %bx, %es
movw $0x1000, %bx
# Setting %ah = 2 and calling int 0x13 again (Read Sectors)
movb $0x02, %ah
int $0x13
# Setting %ds = 0. I don't think it can be done directly.
movw $0x0, %ax
movw %ax, %ds
# Kernel jump
movl $messageready, %esi
call print
ljmp $0x1000, $0x0
# Displaying error message, if any
movl $messageerror, %esi
call print
# Rebooting the OS
reboot:
movl $messagereboot, %esi
call print
movb $0, %ah
int $0x16
movb $0, %ah
int $0x19
# Infinite loop
forever:
hlt
jmp forever
# Error handling
error:
movl $messageerror, %esi
call print
# Test messages
hellostring:
.asciz "Hi Professor.\n\n\r"
messagetest:
.asciz "\nTesting Bootblock!\n\r"
messageboot:
.asciz "Booting up... \n\r "
messageready:
.asciz "\b>> Jumping into the Kernel... \n\r"
messagereboot:
.asciz "Press any key to reboot the OS!\n\r"
messageerror:
.asciz "Unknown error!\n\r"
现在,我的代码打印了它应该的所有消息,但是当它是时候跳进内核时,它显然没有正确地执行它(内核不显示确认消息)。
我的代码编译,但我觉得必须在某处出现错误:
谁能告诉我什么是错的,可以帮助我吗?
您显然在地址0:0x1000
处加载代码0:0x1000
( es=0
, bx=0x1000
)但跳转到0x1000:0
( ljmp $0x1000, $0x0
)。 这不起作用,因为第一个是物理地址0x1000但第二个是0x10000(因为在实模式中你必须将段乘以16)。 让它们匹配。
可能存在其他错误,学习使用调试器或者您每分钟都会寻求帮助。
另外,请保留格式,以便我们可以轻松地复制粘贴整个代码以进行自我测试(或者也提供一个pastebin链接)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.