В качестве учебного опыта я пишу загрузчик для BIOS в NASM в 16-битном реальном режиме в моем эмуляторе x86 Qemu.
BIOS загружает ваш загрузочный сектор по адресу 0x7C00
. NASM предполагает, что вы начинаете с 0x0
, поэтому ваши ярлыки бесполезны, если вы не укажете источник с помощью [org 0x7C00]
(или, предположительно, других методов) . Но когда вы загружаете загрузчик 2-го уровня, его ОЗУ отличается, что до чертиков усложняет использование меток в этом недавно загруженном коде.
Какой рекомендуемый способ справиться с этим? Это территория компоновщика? Должен ли я использовать сегментные регистры вместо org
?
Заранее спасибо!
P.s. Вот код, который работает прямо сейчас:
[bits 16]
[org 0x7c00]
LOAD_ADDR: equ 0x9000 ; This is where I'm loading the 2nd stage in RAM.
start:
mov bp, 0x8000 ; set up the stack
mov sp, bp ; relatively out of the way
call disk_load ; load the new instructions
; at 0x9000
jmp LOAD_ADDR
%include "disk_load.asm"
times 510 - ($ - $$) db 0
dw 0xaa55 ;; end of bootsector
seg_two:
;; this is ridiculous. Better way?
mov cx, LOAD_ADDR + print_j - seg_two
jmp cx
jmp $
print_j:
mov ah, 0x0E
mov al, 'k'
int 0x10
jmp $
times 2048 db 0xf
1 ответ
Возможно, вы усложняете это дело (не то чтобы это было тривиально!)
Ваши ярлыки работают нормально и будут продолжать работать нормально. Помните, что если вы посмотрите под капот на сгенерированный машинный код, ваши короткие прыжки (все после seg_two
в том, что вы опубликовали) являются относительными прыжками. Это означает, что ассемблеру фактически не нужно вычислять реальный адрес, ему просто нужно вычислить смещение от текущего кода операции. Однако, когда вы загружаете свой код в ОЗУ по адресу 0x9000, это совсем другая история.
Лично, когда вы пишете именно такой код, я бы разделил его. Загрузочный сектор останавливается на dw 0xaa55
, а второй этап получает свой собственный файл с ORG 0x9000
наверху.
Когда вы компилируете их в объектный код, вам просто нужно объединить их вместе. По сути, это то, что вы сейчас делаете, за исключением того, что вы заставляете ассемблер делать это за вас.
Надеюсь, это имеет смысл. :)
Похожие вопросы
Новые вопросы
nasm
Nasm - это Netwide Assembler, ассемблер с открытым исходным кодом для x86 / x64. Он стремится быть переносимым, модульным и иметь простой синтаксис.
org
, и объединить полученные двоичные файлы? Я попробую это ....