У меня есть следующая программа x86:
mov ah, 0x0e ; Set up call to BIOS routine to print character
mov al, [character] ; Stick the byte at label "character"
int 0x10 ; Display character in al
jmp $ ; Loop forever
character:
db 0x41 ; Put the byte "A" at this position
times 510-($-$$) db 0 ; Pad with zeros and end with the magic number for a bootloader
db 0x55
db 0xaa
Я запускаю его двумя разными способами:
- В чему
- Запись на USB-накопитель с помощью
dd
и загрузка на старом 64-битном ноутбуке.
Я использую следующие команды для запуска этого кода:
$ nasm -f bin -o boot.bin main.s
$ qemu-system-x86_64 boot.bin # to test
$ dd if=boot.bin of=/dev/sda # to put it on a USB stick
Код, как написано выше, не работает ни в том, ни в другом случае. На железе показывает мигающий курсор, а на qemu печатает кириллическую букву, а не А. Поэтому вторую (непустую) строку я меняю на
mov al, [0x7c00 + character]
добавление смещения 0x7c00
к метке, так как согласно некоторым источникам x86 помещает ваш загрузчик в 0x7c00
в памяти. Это работает, как и ожидалось, в qemu, но продолжает давать мне мигающий курсор на оборудовании. Обратите внимание, что это имеет тот же эффект, что и размещение [org 0x7c00]
вверху, под которым я подразумеваю, что бинарные файлы, созданные с использованием указанной выше строки или путем добавления директивы org
, идентичны (я сравнил их md5).
Чтобы убедиться, что на моем оборудовании нет странного набора символов, где 0x41
не является буквой A, я попробовал
mov al, 0x41
и это работает как на qemu, так и на оборудовании.
Как я могу правильно сослаться на данные, хранящиеся в символе, чтобы мой ноутбук нашел значение, которое должно быть там? Обратите внимание, что поскольку это загрузчик, процессор (если я правильно понимаю) находится в 16-битном реальном режиме.
org
и установилиds
, поэтому ваш ассемблер не знает правильных смещений для абсолютных операндов памяти, и нет гарантированного правильного смещения. - person Peter Cordes   schedule 25.07.20200x7c00
, был своего рода стандартом x86. - person Jack M   schedule 25.07.2020org
, из-за чего ваши операнды памяти отправляются по неправильным адресам. Публикация команд, используемых для сборки и запуска кода, также не помешает. - person fuz   schedule 25.07.2020org
раньше, и она дала те же результаты, что и моя попытка с явным добавлением0x7c00
. На самом деле, поскольку я только что отредактировал вопрос, использованиеorg
создает двоичный файл, идентичный байту за байтом, с моим явным добавлением безorg
. - person Jack M   schedule 25.07.2020org 0x7c00
. Каждая ссылка на память, которая не включает регистрBP
, по умолчанию имеет значение DS:. Если вы не установите DS, вы можете ссылаться не на нужную память. См. мои советы по загрузчику. Это может быть реальной проблемой на реальном оборудовании. Если вы используете USB с эмуляцией флоппи-дисковода (USB FDD), вам может понадобиться Блок параметров BIOS. - person Michael Petch   schedule 25.07.2020org
вместо добавления смещений вручную. Тем не менее, да, вам может потребоваться настроить регистры сегментов в вашем загрузчике. - person fuz   schedule 25.07.2020ds:
в дизассемблированном двоичном файле, но NASM отказался собирать строкуmov ds, 0
, поэтому я подумал, что, должно быть, просто что-то неправильно понял. Благодаря некоторому коду, размещенному в одной из ваших ссылок, я понял, что вам нужно сделатьmov ax, 0
иmov ds, ax
. Вы можете опубликовать это как ответ, если хотите - если вы хотите немного дополнить его, я также хотел бы объяснить, почему вы не можете просто написать константу в DS. - person Jack M   schedule 25.07.2020bh
? И сегмент данных выглядит таким же, как сегмент кода, поэтомуmov ax, cs
иmov ds, ax
. - person Weather Vane   schedule 25.07.2020cs
оказывается0
, и нет никакой гарантии, что в противном случае не было бы смысла иметь регистры сегментов. И то, что иногдаbh
случайно оказывается равным0
, не означает, что вам не нужно его устанавливать. С такими предположениями ваш код будет очень хрупким. - person Weather Vane   schedule 25.07.2020