Последовательность push cs
, pop ds
- это просто способ установить для вашего сегмента данных то же значение, что и для вашего сегмента кода.
Это похоже на использование push ax
, pop bx
вместо mov bx, ax
, кроме того факта, что он использует память и может иметь различное влияние на определенные флаги, что я не смог потрудиться проверить, когда мое намерение состоит только в том, чтобы предоставить пример: -)
Одна из причин, по которой вы бы это сделали, восходит к старым временам сегментированной архитектуры x86 (в отличие от более современных селекторов), которая в настоящее время редко используется.У x86 были различные модели памяти, такие как крошечная, маленькая, компактная, средняя, большая и огромная.
В основном это были различия в размерах и количестве сегментов кода и данных, которые вы могли использовать, и, из памяти, крошечныеозначало, что у вас был один сегмент, который содержал и код, и данные.
Следовательно, cs
и ds
должны быть установлены в одно и то же значение, чтобы все инструкции работали в этом сегменте по умолчанию.
В вашем конкретном случае вы сохраняете ds
, устанавливая для него то же значение, что и cs
, а затем восстанавливаете его.Ниже приведено более вероятное объяснение причины.
Что касается работы movsw
, он просто копирует значение одного слова из памяти по адресу ds:si
по адресу es:di
, обновляяуказатели после (увеличение или уменьшение, в зависимости от установки флага направления).
Префикс rep
делает это в цикле, уменьшая cx
, пока не достигнет нуля.
Следовательноэто просто объемная копия памяти.
Теперь, поскольку источник repsw
указан в сегменте ds
, реальная причина, по которой вы видите, что push/pop
устанавливаетсяds
временно становится понятным - это потому, что источник данных явно лежит в сегменте кода.