КОНЦЕПЦИЯ MOV AX, CS и MOV DS, AX - PullRequest
4 голосов
/ 19 марта 2011

Может кто-нибудь объяснить, пожалуйста, функции трех инструкций .....

>      ORG 1000H 
>      MOV AX,CS
>      MOV DS,AX

Я знаю, что такое код, данные, дополнительные сегменты в теории.

Но

1. Как они реализуются в этой программе?

2. Почему они перемещают весь сегмент в другой? (MOV AX, CS; MOV DS, AX; )

(извините, если вопрос абсурдный), какова реальная концепция этих двух инструкций ...

/ * Приведенная ниже программа сборки 8086 хорошо работает.

Я могу понять значение каждого инструкция в этом коде,

за исключением выделенных 3 инструкций. * /

Код принимает ввод до тех пор, пока не будет нажата 0!

Code:
    ASSUME CS:CODE        
    CODE SEGMENT 
    ORG 1000H
    MOV AX,CS
    MOV DS,AX
BACK:
   MOV AH,01H
   INT 21H
   CMP AL,'0'
   JZ LAST
   JMP BACK
LAST:
   MOV AX,4C00H
   INT 21H
   CODE ENDS

   END

Ответы [ 3 ]

9 голосов
/ 19 марта 2011

Чтобы действительно объяснить концепцию, мы должны вернуться к основной идее сегментов и тому, как 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
8 голосов
/ 19 марта 2011

ORG 1000H сообщает ассемблеру, что следующий код должен быть помещен со смещением 1000H в образе кода.

Две другие инструкции копируют CS в DS.Это не копирование самого сегмента, просто обновление указателя на сегмент данных.Для небольшой программы (<64 КБ) статические данные (строковые литералы в источнике, таблицы косвенных переходов) могут быть размещены вместе в одном сегменте с кодом.Базовый указатель сегмента должен быть загружен в DS перед доступом к статическим данным.Загрузчик (часть ОС, которая считывает программу с диска в память и запускает ее), должна установить CS, чтобы она могла запускать программу, но не может установить DS, поэтому программа копирует CS в DS при запуске.</p>

Необходима последовательность двух команд, поскольку «MOV DS, CS» не является допустимой инструкцией 8086.

1 голос
/ 19 марта 2011

вы не можете сделать

MOV DS, CS

это недопустимая операция (masm 32: error A2070: invalid instruction operands).

MOV AX, CS
MOV DS, AX

Эти 2 инструкции выполняют так же, как mov ds, cs (что недействительно).Таким образом, ассемблер счастлив и не жалуется.Но я не могу сказать вам, почему программист хочет, чтобы сегмент данных был таким же, как сегмент кода

...