Загрузчик ссылается на данные и переходы
Привет сообществу,
Я пытаюсь разработать очень простой загрузчик, и для этого я следую учебному пособию: http://www.cs.bham.ac.uk/~exr/lectures/opsys/10_11/lectures/os-dev.pdf
Я новичок в ассемблере и надеюсь найти свой ответ здесь. Мой вопрос касается адресации и org
команда.
Я понимаю почему org
Команда необходима для получения данных по заданному адресу. Поскольку загрузочный сектор будет загружен по адресу 0x7c00, необходимо сообщить компилятору, что этот адрес должен быть добавлен к любой ссылке. Например, приведенный ниже код не будет работать без [org 0x7c00]
команда, потому что она будет получать данные по адресу 0x0012 вместо 0x7c12.
[org 0x7c00]
; print String
mov ah, 0x0e
mov bx, text
printLoop:
mov al,[bx]
cmp al,0
je loop
int 0x10
inc bx
jmp printLoop
loop:
jmp loop
text: ; at adress 0x0012 in the file but will be loaded at 0x7c12
db 'Loading OSiris operating system...',10,13,0
times 510-($-$$) db 0
dw 0xaa55
Теперь то, что я не понимаю, почему это не то же самое для jmp
команда? Короче я не понимаю, почему код ниже работает (бесконечно печатает?, org
Команда прокомментировала).
;[org 0x7c00]
mov ah, 0x0e
mov al, '?'
loop: ; as I understood 0x0004 in the file but 0x7c04 in the memory
int 0x10
jmp loop ; hence this should jump at 0x0004 and the code should not work (but it actually works)
times 510-($-$$) db 0
dw 0xaa55
Насколько я понимаю, прыжок должен быть сделан по адресу 0x0004 . Следовательно, компьютер должен загружаться бесконечно, а не просто печатать? Это что-то делать с локальными переходами и сегментами кода?
1 ответ
Эта форма короткого jmp
кодируется с использованием относительного смещения. Это в основном говорит "отскок назад 4 байта". Таким образом, он не зависит от позиции и работает независимо. Фактический машинный код EB FC
где EB
это код операции для быстрого перехода, и FC
является -4
, смещение отсчитывается от адреса следующей инструкции, где выполнение обычно продолжается.
Также обратите внимание, что точка входа гарантированно находится только по физическому адресу 0x7c00, вы не должны полагаться на это 0:0x7c00
, Некоторые BIOS могут использовать 0x7c0:0
, Чтобы быть в безопасности, вы должны инициализировать свои регистры сегментов, в том числе CS
(используйте дальний прыжок для этого).