#assembly #x86-16
Вопрос:
я написал небольшую программу на 16-разрядной сборке NASM для загрузочного сектора (512 байт). Он использует видеорежим BIOS 13h, чтобы нарисовать маленькую белую полоску на экране. Это и есть код:
bits 16
org 0x7C00
VIDEO_INT: equ 0x10
VGA_BASE: equ 0xA000
mov ax, 13
int VIDEO_INT
push VGA_BASE
pop es
xor di,di
mov ax, 255
mov [es:di], ax
mov [es:di 1], ax
mov [es:di 2], ax
start:
;--------------------------------------
; make file 512 bytes, just enough to fit in boot sector
times 510-($-$) db 0
dw 0xaa55 ; boot sector magic number
Однако, когда программа была скомпилирована и протестирована на реальном оборудовании, на экране появилась приятная белая полоса, но BIOS по какой-то причине издал непрерывный звуковой сигнал динамика ПК. Может ли кто-нибудь объяснить, почему это так, что я делаю неправильно и что я должен делать вместо этого?
Комментарии:
1. Как вы думаете, что произойдет после выполнения последней инструкции в вашем коде?
2. Почему? Я не знаю.
3. Процессор не знает, что на этом ваша программа заканчивается. Он просто продолжает выполнять весь мусор, который есть в памяти после вашей программы. Но такая инструкция, как
jmp $
в, позволяет заставить код идти по бесконечному циклу и предотвратить это.4. Ну, а с другой стороны, вы перепутали x и y . Также это в сегменте
A000
. Поэтому вам нужно загрузить сегментный регистрA000
и получить доступ к памяти, используя этот сегментный регистр с правильным смещением. Режим 13h-это режим палитры с 256 цветами (вы можете найти палитру онлайн). Также можно установить свою собственную палитру, но проще всего просто использовать предопределенные цвета.5. Поскольку вы пишете слова (
ax
), вы устанавливаете два пикселя (один на 255, который белый, другой на 0, который черный, и значение по умолчанию для всех пикселей, когда установлен режим видео).
Ответ №1:
Причина, по которой это происходит, заключается в том, что процессор [процессор] не знает, когда прекратить выполнение кода, и поэтому он просто выполняет все, что находится в памяти. Чтобы остановить это, вы просто помещаете простой цикл (например: jmp $
) в конец своей программы, чтобы процессор просто непрерывно повторял цикл снова и снова и больше ничего не выполнял.
Комментарии:
1. Лучше: поставьте ярлык, как
halting:
«затемsti
«, а затемhlt
«потомjmp halting
«. Это экономит процессорное время и мощность при бесконечном цикле.2. Да… ты тоже можешь это сделать.