Вопрос по assembly, x86 – Какое значение следует использовать для SP для процесса загрузки?

3

Последовательность загрузки в BIOS загружает первую действительную MBR, которую он находит, в физическую память компьютера по адресу 0x7C00.

Какое значение следует использовать для SP для процесса загрузки?

org 7c00h      ; set location counter.
mov ax, XXX    ; What is XXX?
mov sp, ax
; Now PUSH an POP are safe

Ваш Ответ

2   ответа
2

SS:SP такой, что для вашего кода достаточно стекового пространстваAND Служба обработки прерываний в порядке.

И, разумеется, ваш стек не должен вступать в конфликт с каким-либо кодом или другими данными или работать в ПЗУ или в диапазоне адресов отображаемого в памяти устройства.

BIOS не гарантирует, чтоSS:SP ваш загрузочный сектор получит. Так что, изменяя толькоSP не так.

Например, вы можете сделать это (если в этом месте нет вашего кода или данных):

...
mov ax, 0
mov ss, ax
mov sp, ax
...

Это установитSS:SP до 0: 0. Пока не паникуйте. Следующий толчок будет первым уменьшениемSP от 0 до 0xFFFE и записать в 0: 0xFFFE, а не в 0: 0.

Это даст вам 0x10000 - (0x7c00 + 0x200) = 33280 байт пространства между концом загрузочного сектора и адресом указателя максимального стека. Это достаточно места в стеке.

Также обратите внимание, что при изменении обоихSS а такжеSPВы должны сделать это с отключенными прерываниями или сначала изменитьSS а затем изменитьSP в сразу же следующей инструкции (как показано выше).

В качестве альтернативы вы можете использоватьLSS SP, ... инструкции, но он принимает в качестве аргумента адрес дальнего адреса, то есть ваш новыйSS:SP Значение сначала должно быть где-то в памяти.

Еще один способ изменитьSS а такжеSP это использоватьPUSH а такжеRETF.

3

0000: 0500 до 0007: FFFF гарантированно бесплатен для использования. Правильная инициализация выглядит так:

org 0x0600
...

cli
xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0x7C00

; relocate itself
mov si, sp
mov di, 0x0600
mov cx, 256
rep movsw

; make sure we'are at 0000:0600+x
jmp 0:.reloc
.reloc:
push 2
popf    ; flags with all off

Я использую 7C00, стек идет вниз, а код идет вверх. Вы можете заменить 7C00 любым допустимым диапазоном, как упомянуто, только убедитесь, что не перезаписываете свой собственный код / данные.

Кстати, большинство MBR по традиции переместится в 0000: 0600, а VBR с цепной загрузкой - в 7C00.

Также обратите внимание на jmp .reloc, некоторые ошибочные BIOS запускают MBR с 07C0: 0000, поэтому в jmp убедитесь, что CS = 0

+1 для глючных BIOS.
С 80-х годов это было довольно легкое правило. Если вы хотите работать на самых разных аппаратных средствах, не делайте предположений - за исключением содержимого_DL_, хотя некоторые производители BIOS испортили значение вDL также.
Я бы не сказал, что это были глючные BIOS. Еще в тот день, когда IBM не указала, какая именно пара сегментов: смещение будет использоваться BIOS для перехода к вашему коду, он будет загружен в 0x7c00. Даже к середине 80-х MS-DOS не делала предположений. В одной из спецификаций El Torito несколько лет спустя упоминалось 0x07c0: 0x0000. В некоторых средах при загрузке с компакт-диска он использовал 0x07c0: 0x0000, а если это был дискета / жесткий диск, то он использовал 0x0000: 0x7c00.
@MichaelPetch Загрузочный сектор на моем диске MS-DOS 2.11 середины 80-х годов требует CS = 0. Так что да, я бы назвал это ошибкой BIOS. Также в спецификации El Torito не совсем сказано, что CS: IP должен быть 07c0: 0000. Это просто говорит о том, что сегмент загрузки по умолчанию - 07c0.
@RossRidge: Я не помню точную версию, будь то PC-DOS или MS-DOS, но в конечном итоге загрузчики были перемещены из 0x7c00 и помещены в более низкую память, а затем было выполнено FAR JMP до 0: смещение (где DS / ES были установлены соответственно). Я знаю, что в начале 80-х загрузчики делали предположения. Что касается спецификации El Torito, я говорю не о том, как я ее интерпретировал, а о том, как многие другие это сделали. Интересно, что Bochs (я не могу вспомнить, был ли это 2.6.4 или более ранний), фактически использовал 0x0: 0x7c00 для дискет / HD и 0x7c0: 0 для компакт-дисков. И в то время они тоже воспитывали Эль Торито

Похожие вопросы