@XCemaXX

Как задать регистры стека ss, sp на x86 (загрузчик 16бит)?

Осталось недопонимание в задании сегментов стека и данных при написании загрузчика x86 в 16 битном режиме.
Хочу, чтобы стек размером 1кбайт создавался после кода загрузчика в 512 байт.
Есть два варианта:
[bits 16]
[org 0x7c00]
mov ax, 0x060 ;(1024+512)/16=96=60h адрес стека после загрузчика в сегментах
mov ss, ax ;установка адреса сегмента стека
mov sp, 1024 ;установка указателя стека
mov ax, 0x0000
mov ds, ax ;указатель равен 0, потому что смещение не нужно для меток. Все метки благодаря org 0x7c00 будут иметь правильный адрес


Либо:
[bits 16]
[org 0x0000]
mov ax, 0x07C0 ;0x7c00/0x10=0x07c0
mov ds, ax ;указатель сегмента данных равен 0x07c0. Все адреса меток в коде идут с 0, а код на самом деле перемещается на 0x7c00, поэтому нужно смещение
add ax, 0x060 ;адрес стека после загрузчика в сегментах 0x07C0+0x060
mov ss, ax ;установка адреса сегмента стека
mov sp, 1024 ;установка указателя стека


Насколько я понимаю, то адреса сегментов данных установлены правильно. Код без стека работает, как на виртуальной машине, так и на реальном ПК. В коде осуществляется правильный переход по меткам. Но вот со стеком возникают проблемы, вероятно, в варианте org 0x7c00, что то не так. Объясните, пожалуйста, где я совершаю ошибку.
  • Вопрос задан
  • 127 просмотров
Решения вопроса 1
jcmvbkbc
@jcmvbkbc
"I'm here to consult you" © Dogbert
Обычно удобно пользоваться моделью памяти, в которой все сегментные регистры указывают в одно место. И если пишешь загрузчик, рекомендуют сегментные регистры инициализировать в самом начале. Какое именно значение сегмента выбрать -- 0 или 0x7c0 не имеет большой разницы. sp можно инициализировать так:
start:
....
mov sp, start + 512 + 1024

это будет работать правильно для любого выбранного org и соответствующим образом инициализированного ss.
Например:
org 0x7c00
start:
mov ax, 0
mov ss, ax
mov sp, start + 512 + 1024


mov ax, 0x060 ;(1024+512)/16=96=60h адрес стека после загрузчика в сегментах
mov ss, ax ;установка адреса сегмента стека
mov sp, 1024 ;установка указателя стека

непонятно, почему ты решил записать в ss 0x60 а в sp -- 1024. Если ты хотел чтобы сегмент стека указывал на его дно, то должно было получиться (0x7c00 + 512) / 16 = 0x7e0.

add ax, 0x060 ;адрес стека после загрузчика в сегментах 0x07C0+0x060

и опять логика непонятна.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

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