我正在用汇编语言开发操作系统。 在开发时,我更改了一小部分代码,并且输出文件不可启动。
有代码:
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,但一无所获。 该怎么办?
答案 0 :(得分:2)
您需要更改:
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的软盘映像:
将文件组装到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)启动,然后选择os.img
文件作为启动映像。 VirtualBox需要适当大小的软盘映像。
运行时在此问题中显示的代码在我的VirtualBox中显示如下:
如果您替换:
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
然后,您会收到一条错误消息,提示您引导加载程序太大:
nasm:致命:.text和bootsig部分重叠!
这意味着bootsig
之前的部分中的代码与引导签名部分重叠。如果发生这种情况,那么您将知道该是您自己读取磁盘扇区以将代码扩展到512字节引导扇区之外的时候了。
如果使用ORG 0x7c00
,则start=510
必须为start=0x7c00+510
。
如果您依靠TIMES
来告诉您有问题,它将看起来像这样:
os.asm:###:错误:TIMES值-###为负
1 如果文件os.bin
大于512字节,则需要使用BIOS手动将更多磁盘扇区读入内存。可以使用INT 13h/AH=2h从软盘读取磁盘。