Чтобы действительно объяснить концепцию, мы должны вернуться к основной идее сегментов и тому, как x86 использует их (в реальном режиме).
8086 имеет 20-битную адресацию, но только 16регистры.Для генерации 20-битных адресов он объединяет сегмент со смещением.Сегмент должен быть в регистре сегмента (CS, DS, ES или SS).Затем вы генерируете смещение (как непосредственное значение или содержимое другого регистра или двух.
Итак, для генерации адреса 16-разрядный регистр сегмента сдвигается влево на четыре бита, а затем 16-разрядныйк этому добавляется битовое смещение в каком-то другом регистре, и объединенный итог фактически используется в качестве адреса. Большинство инструкций имеют присоединенный к ним сегмент по умолчанию - push
, pop
и все, что относится к bp
, будет использовать ss
. Переходы и т. П. cs
. Некоторые строковые инструкции es
(например, scans
), а некоторые используют два сегмента - например, movsd
копирует данные из [ds:si]
в [es:di]
В большинстве других инструкций используется ds
. Вы также можете использовать переопределения сегментов, чтобы явно указать адрес, такой как es:bx
.
В любом случае, прежде чем вы сможете осмысленно использовать регистр сегментов, вы должны сначалазагрузить его с (верхние 16 бит) адресом данных, которые вас интересуют. Типичная программа для «маленькой модели» будет начинаться с чего-то вроде:
mov ax, @Data
mov ds, ax
В крошечной модели выиспользуйте тот же сегмент для данных и кода.Чтобы убедиться, что он ссылается на правильный сегмент, вы хотите получить 16 бит из CS и скопировать его в DS.Как уже упоминалось рядом других, нет инструкции по перемещению CS непосредственно в DS.Вопрос упоминает одну возможность;Еще один распространенный:
push cs
pop ds