Сборка Почему, когда я изменяю код, результат не загружается
Я разрабатываю операционную систему на ассемблере. Во время разработки я изменяю небольшую часть кода, и выходной файл не является загрузочным.
Есть код:
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 и ничего. Что делать?
1 ответ
Вам нужно изменить:
times 512-($-$$) db 0
чтобы:
times 510-($-$$) db 0
Вам нужно заполнить 510 байт, чтобы загрузочная подпись 0xaa55 была последними 2 байтами 512-байтового загрузочного сектора. Если вы этого не сделаете, образ не будет считаться допустимым загрузочным сектором. Ваш предыдущий вопрос упоминается с помощью команды:
nasm -f bin os.asm -o os.iso
Вы не генерируете ISO (образ компакт-диска) с этой командой. Для загрузки в VirtualBox я рекомендую создать образ дискеты 1,44 МБ с загрузочным сектором следующим образом:
Соберите файл в os.bin
,
nasm -f bin os.asm -o os.bin
После этого шага проверьте, что файл os.bin
ровно 512 байт 1. Если вы не поместили слишком много кода и данных в загрузочный сектор, загрузочная подпись окажется в неправильном месте, и VirtualBox откажется идентифицировать ее как загрузочное устройство.
Создайте пустой образ дискеты 1.44MB под названием 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) и выберите 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: fatal: разделы.text и bootsig перекрываются!
Это означает код в разделе перед bootsig
перекрывается с разделом подписи загрузки. Если это произойдет, вы узнаете, что пришло время самостоятельно прочитать секторы диска, чтобы расширить свой код за пределы 512-байтового загрузочного сектора.
При использовании ORG 0x7c00
затем start=510
должно быть start=0x7c00+510
,
Если вы полагаетесь на TIMES
Сказать, что есть проблема, будет выглядеть примерно так:
os.asm: ###: error: значение TIMES -### отрицательно
1 Если файл os.bin
больше 512 байт, тогда вам нужно будет использовать BIOS для чтения большего количества секторов диска в память вручную. Чтение диска с дискеты можно выполнить с INT 13h / AH = 2h.