Если внешняя память (1 МБ) в системе на базе 8086 разделена на код, данные, стек и дополнительные части, которые составляют 64 КБ, что мы делаем с остальной памятью? Это идет впустую?
В 8086 каждый сегмент, да, 64 КБ. Однако эти сегменты могут двигаться.
Вы устанавливаете «указатель сегмента», который определяет, где начинается сегмент. Он действует как смещение адреса, которое добавляется к внутреннему 16-битному адресу счетчика команд (или другого индексного регистра).
Изменение указателей сегментов является тривиальной задачей, поэтому, хотя вы можете получить доступ только к 64 КБ за раз, вы можете перемещать это окно размером 64 КБ по желанию, чтобы получить доступ ко всему 1 МБ пространства памяти.
Также обратите внимание, что, поскольку 8086 имел 20-битную схему адресации, эти смещения сегментов перекрывались через каждые 16 байтов.
Например, если у вас есть CS по адресу 0x0010 и SS по адресу 0x0011, [CS]:[0x0010] = [SS]:[0x0000]
Номер сегмента определяет место в памяти. Сегмент 0 начинается с физического адреса 0 памяти. Сегмент 1 начинается с 0x10 байт от начала, сегмент 2 с 0x20 и т. д.
Да, сегменты начинаются с 0x10 байт, но имеют длину 64 КБ, что означает, что они сильно перекрываются.
Существуют сегментные регистры: CS (сегмент кода), DS (сегмент данных), SS (сегмент стека) и ES (дополнительный сегмент). Побайтовые адреса получаются с помощью регистров указателей: IP (указатель инструкций), SP (указатель стека) и BP (базовый указатель).
Текущая выполняемая инструкция находится в CS:IP (номер сегмента от смещения байтов CS + IP).
Если вы работаете с данными без явного указания сегмента, по умолчанию используется DS (по крайней мере, в нотации Турбо Ассемблера). Например:
mov cx, [bp]
такой же как:
mov cx, ds:[bp]
Я не уверен в точном синтаксисе (это было около 15 лет назад с тех пор, как я его использовал).
Вы не можете напрямую присвоить значение сегментному регистру. Вы должны сделать это через общие регистры, например:
mov ax, 100h
mov ds, ax
Итак, чтобы загрузить слово с физического адреса 0x105 в BX, вы можете сделать это следующим образом:
xor ax, ax ; equal to mov ax, 0 but faster
mov ds, ax
mov ax, 105h
mov bx, [ax]
или, используя другой сегмент:
mov ax, 10h
mov ds, ax
mov ax, 5
mov bx, [ax]
ds
по умолчанию — это то, как работает набор инструкций. А именно, если вы переопределяете сегмент, ассемблер сгенерирует соответствующий префикс переопределения сегмента, в противном случае он генерирует инструкцию без префикса, и это фактически делает ds
значение по умолчанию (для инструкций, которые подчиняются этому принципу).ax
ошибочно. Нет такого режима адресации, как [ax]
. Вы можете либо использовать [eax]
начиная с i386, либо ограничиться [bx+si]
, [bx+di]
, [bp+si]
, [bp+di]
, [si]
, [di]
, [bp]
, [bx]
.
Крис Стрэттон
Маженко
Мистер Листер