当我修改代码时,磁盘映像变得无法启动
When I modify code the disk image becomes unbootable
我正在用汇编语言开发一个操作系统。更改代码时,输出文件不被视为可引导文件。
这是我的代码:
BITS 16
start:
mov ax, 07C0h ; Set up 4K stack space after this bootloader
add ax, 288 ; (4096 + 512) / 16 bytes per paragraph
mov ss, ax
mov sp, 4096
mov ax, 07C0h ; Set data segment to where we're loaded
mov ds, ax
call cls
MOV AH, 06h ; Scroll up function
XOR AL, AL ; Clear entire screen
XOR CX, CX ; Upper left corner CH=row, CL=column
MOV DX, 184FH ; lower right corner DH=row, DL=column
MOV BH, 1Eh ; YellowOnBlue
INT 10H
mov si, text_string ; Put string position into SI
call print_string ; Call our string-printing routine
push bx ;push registers
push cx
push dx
mov ah,0h
int 16h
cmp al, '1'
je reboot
cmp al, '2'
je shutdown
cmp al, '3'
je about
cmp al, '4'
je message
cmp al, '5'
je shutdown
jmp $ ; Jump here - infinite loop!
text_string db '|Main Menu| |Smile OS V1.2|',13,10,'1) Reboot',13,10,'2) Shutdown',13,10,'3) About',13,10,'4) Message',13,10,'5) System Halt',0
about_string db '|About|',13,10,'Smile OS is a console based operating system in assembly.',13,10,'Press any key to go back!',0
message_str db '|Message|',10,13,'Hello, World!',13,10,'Press any key to go back!',0
reboot:
mov ax, 0
int 19h
shutdown:
mov ax, 0x1000
mov ax, ss
mov sp, 0xf000
mov ax, 0x5307
mov bx, 0x0001
mov cx, 0x0003
int 0x15
message:
call cls
mov si, message_str ; Put string position into SI
call print_string ; Call our string-printing routine
push bx ;push registers
push cx
push dx
mov ah,0h
int 16h
je start
cls:
pusha
mov ah, 0x00
mov al, 0x03 ; text mode 80x25 16 colours
int 0x10
popa
ret
about:
call cls
mov si, about_string ; Put string position into SI
call print_string ; Call our string-printing routine
push bx ;push registers
push cx
push dx
mov ah,0h
int 16h
je start
print_string: ; Routine: output string in SI to screen
mov ah, 0Eh ; int 10h 'print char' function
.repeat:
lodsb ; Get character from string
cmp al, 0
je .done ; If char is zero, end of string
int 10h ; Otherwise, print it
jmp .repeat
.done:
ret
times 512-($-$$) db 0 ; Pad remainder of boot sector with 0s
dw 0xAA55 ; The standard PC boot signature
当我尝试还原更改时,代码损坏了。
- 我正在使用 Oracle VM VirtualBox 和最新版本的 NASM。
- 我试了几次重启电脑都没有变化
- 我尝试安装旧版本 NASM 但什么也没安装。
我需要做什么来修复这个引导加载程序?
您需要更改:
times 512-($-$$) db 0
至:
times 510-($-$$) db 0
您需要填充 510 个字节,因此引导签名 0xaa55 是 512 字节引导扇区的最后 2 个字节。如果不这样做,映像将不会被视为有效的引导扇区。您之前的问题提到使用命令:
nasm -f bin os.asm -o os.iso
您没有使用此命令生成 ISO(CD-ROM 映像)。要在 VirtualBox 中启动,我建议用您的引导扇区创建一个 1.44MB 的软盘映像:
Assemble 文件到 os.bin
.
nasm -f bin os.asm -o os.bin
完成此步骤后,检查文件 os.bin
是否正好 512 字节1。如果不是您在引导扇区中放置了太多代码和数据,引导签名将位于错误的位置并且 VirtualBox 将拒绝将其识别为可引导设备。
创建一个名为 os.img
:
的空白 1.44MB 软盘映像
dd if=/dev/zero of=os.img bs=1024 count=1440
将 os.bin
复制到 os.img
的开头,而不 运行 复制磁盘映像:
dd if=os.bin of=os.img conv=notrunc
在 VirtualBox 中将其设置为从 FLOPPY(不是 CD-ROM)启动,并且 select os.img
文件作为启动映像。 VirtualBox 需要大小合适的软盘映像。
当运行出现在我的VirtualBox中时,你在这个问题中显示的代码是这样的:
将捕获重叠部分的 TIMES 的替代方法
如果替换:
times 510-($-$$) db 0 ; Pad remainder of boot sector with 0s
dw 0xAA55 ; The standard PC boot signature
有:
section bootsig start=510
dw 0xAA55 ; The standard PC boot signature
然后会提示你的bootloader太大的错误:
nasm: fatal: sections .text and bootsig overlap!
这意味着 bootsig
之前的部分中的代码与引导签名部分重叠。如果发生这种情况,那么您将知道是时候自己读取磁盘扇区以将您的代码扩展到 512 字节引导扇区之外了。
如果使用 ORG 0x7c00
,则 start=510
必须是 start=0x7c00+510
。
如果您依靠 TIMES
来告诉您有问题,它看起来像:
os.asm:###: error: TIMES value -### is negative
1 如果文件 os.bin
超过 512 字节,那么您将需要使用 BIOS 手动将更多磁盘扇区读入内存。从软盘读取磁盘可以用 INT 13h/AH=2h.
我正在用汇编语言开发一个操作系统。更改代码时,输出文件不被视为可引导文件。
这是我的代码:
BITS 16
start:
mov ax, 07C0h ; Set up 4K stack space after this bootloader
add ax, 288 ; (4096 + 512) / 16 bytes per paragraph
mov ss, ax
mov sp, 4096
mov ax, 07C0h ; Set data segment to where we're loaded
mov ds, ax
call cls
MOV AH, 06h ; Scroll up function
XOR AL, AL ; Clear entire screen
XOR CX, CX ; Upper left corner CH=row, CL=column
MOV DX, 184FH ; lower right corner DH=row, DL=column
MOV BH, 1Eh ; YellowOnBlue
INT 10H
mov si, text_string ; Put string position into SI
call print_string ; Call our string-printing routine
push bx ;push registers
push cx
push dx
mov ah,0h
int 16h
cmp al, '1'
je reboot
cmp al, '2'
je shutdown
cmp al, '3'
je about
cmp al, '4'
je message
cmp al, '5'
je shutdown
jmp $ ; Jump here - infinite loop!
text_string db '|Main Menu| |Smile OS V1.2|',13,10,'1) Reboot',13,10,'2) Shutdown',13,10,'3) About',13,10,'4) Message',13,10,'5) System Halt',0
about_string db '|About|',13,10,'Smile OS is a console based operating system in assembly.',13,10,'Press any key to go back!',0
message_str db '|Message|',10,13,'Hello, World!',13,10,'Press any key to go back!',0
reboot:
mov ax, 0
int 19h
shutdown:
mov ax, 0x1000
mov ax, ss
mov sp, 0xf000
mov ax, 0x5307
mov bx, 0x0001
mov cx, 0x0003
int 0x15
message:
call cls
mov si, message_str ; Put string position into SI
call print_string ; Call our string-printing routine
push bx ;push registers
push cx
push dx
mov ah,0h
int 16h
je start
cls:
pusha
mov ah, 0x00
mov al, 0x03 ; text mode 80x25 16 colours
int 0x10
popa
ret
about:
call cls
mov si, about_string ; Put string position into SI
call print_string ; Call our string-printing routine
push bx ;push registers
push cx
push dx
mov ah,0h
int 16h
je start
print_string: ; Routine: output string in SI to screen
mov ah, 0Eh ; int 10h 'print char' function
.repeat:
lodsb ; Get character from string
cmp al, 0
je .done ; If char is zero, end of string
int 10h ; Otherwise, print it
jmp .repeat
.done:
ret
times 512-($-$$) db 0 ; Pad remainder of boot sector with 0s
dw 0xAA55 ; The standard PC boot signature
当我尝试还原更改时,代码损坏了。
- 我正在使用 Oracle VM VirtualBox 和最新版本的 NASM。
- 我试了几次重启电脑都没有变化
- 我尝试安装旧版本 NASM 但什么也没安装。
我需要做什么来修复这个引导加载程序?
您需要更改:
times 512-($-$$) db 0
至:
times 510-($-$$) db 0
您需要填充 510 个字节,因此引导签名 0xaa55 是 512 字节引导扇区的最后 2 个字节。如果不这样做,映像将不会被视为有效的引导扇区。您之前的问题提到使用命令:
nasm -f bin os.asm -o os.iso
您没有使用此命令生成 ISO(CD-ROM 映像)。要在 VirtualBox 中启动,我建议用您的引导扇区创建一个 1.44MB 的软盘映像:
Assemble 文件到 os.bin
.
nasm -f bin os.asm -o os.bin
完成此步骤后,检查文件 os.bin
是否正好 512 字节1。如果不是您在引导扇区中放置了太多代码和数据,引导签名将位于错误的位置并且 VirtualBox 将拒绝将其识别为可引导设备。
创建一个名为 os.img
:
dd if=/dev/zero of=os.img bs=1024 count=1440
将 os.bin
复制到 os.img
的开头,而不 运行 复制磁盘映像:
dd if=os.bin of=os.img conv=notrunc
在 VirtualBox 中将其设置为从 FLOPPY(不是 CD-ROM)启动,并且 select os.img
文件作为启动映像。 VirtualBox 需要大小合适的软盘映像。
当运行出现在我的VirtualBox中时,你在这个问题中显示的代码是这样的:
将捕获重叠部分的 TIMES 的替代方法
如果替换:
times 510-($-$$) db 0 ; Pad remainder of boot sector with 0s
dw 0xAA55 ; The standard PC boot signature
有:
section bootsig start=510
dw 0xAA55 ; The standard PC boot signature
然后会提示你的bootloader太大的错误:
nasm: fatal: sections .text and bootsig overlap!
这意味着 bootsig
之前的部分中的代码与引导签名部分重叠。如果发生这种情况,那么您将知道是时候自己读取磁盘扇区以将您的代码扩展到 512 字节引导扇区之外了。
如果使用 ORG 0x7c00
,则 start=510
必须是 start=0x7c00+510
。
如果您依靠 TIMES
来告诉您有问题,它看起来像:
os.asm:###: error: TIMES value -### is negative
1 如果文件 os.bin
超过 512 字节,那么您将需要使用 BIOS 手动将更多磁盘扇区读入内存。从软盘读取磁盘可以用 INT 13h/AH=2h.