Описание некоторых команд Ассемблера

Команда пересылки данных - MOV

Основная команда общего назначения MOV (move – переслать) может пересылать байт или слово между регистром и ячейкой памяти или между двумя регистрами. Она может также пересылать непосредственно адресуемое значение в регистр или в ячейку памяти. При пересылке она замещает первый операнд (приемник) вторым (источником), соответственно исходное значение первого операнда теряется. Тип пересылаемых операндов должен быть одинаков.

Команда имеет следующий формат: MOV приемник, источник

В этой команде допустимо большинство из возможных сочетаний операндов. Приведем несколько примеров:

MOV AX,TABLE; Пересылка из памяти в регистр.

MOV TABLE,АХ; Пересылка из регистра в память.

MOV ES:[BX],AX; Можно заменить используемый регистр сегмента.

MOV DS,AX; Пересылка между 16-битовыми регистрами.

MOV BL,AL; Пересылка между 8- битовыми регистрами.

MOV CL,-ЗО; Пересылка константы в регистр.

MOV DEST,25H; Пересылка константы в ячейку памяти по адресу DEST.

В команде МОV исключаются следующие сочетания операндов:

1) память, память – запрещается непосредственная пересылка данных из одной ячейки памяти в другую. Чтобы выполнить такую операцию, необходимо использовать промежуточное звено, которым может быть регистр общего назначения. Например, если per1 и per2 – переменные, находящиеся в памяти, то для пересылки значения из одной переменной в другую можно воспользоваться следующими командами:

MOV AX, per1; Копировать содержимое ячейки по адресу per1 в АХ.

MOV per2,AX; Копировать содержимое АХ в ячейку по адресу per2.

2) регистр сегмента, непосредственный операнд – нельзя пересылать непосредственно адресуемый операнд в регистр сегмента. Как и в случае 1, сначала надо загрузить его в регистр общего назначения. Например, для загрузки адреса сегмента данных (DATA_SEG) в регистр DS используют следующие команды:

MOV AX,@DATA; Копировать адрес сегмента данных в АХ.

MOV DS,AX; Копировать адрес сегмента данных из АХ в DS.

Эти команды инициализируют сегментный регистр DS;

3) регистр сегмента, регистр сегмента – нельзя непосредственно пересылать значение одного регистра сегмента в другой. Делайте подобные пересылки через регистр общего назначения. Например, чтобы регистр DS указывал на тот же сегмент, что и регистр ES, воспользуйтесь командами:

MOV AX,@DATA; Копировать адрес сегмента данных в АХ.

MOV DS,AX; Копировать адрес сегмента данных из АХ в DS.

MOV ЕS, АХ; Копировать адрес сегмента данных из АХ в ES.

4) запрещено использовать регистр CS в качестве приемника в команде пересылки непосредственных данных.

Команды обращения в стэк – PUSH и POP

Как уже упоминалось, во время исполнения процедуры стек содержит адрес возврата. Команда вызова процедуры CALL (call - вызвать) помещает адрес следующей команды в стек, а команда возврата RET (return - возвратить) извлекает его по окончании исполнения процедуры. Это один из случаев, когда микропроцессор 8086 использует стек автоматически, без указания.

Таким образом, стек удобен для временного сохранения данных (содержимого регистров и ячеек памяти) при работе программы. Например, сохранить содержимое регистра СХ на то время, пока он требуется для выполнения каких-либо действий. Для этого имеются две команды для работы со стеком – PUSH (поместить слово в стек) и POP (извлечь слово из стека). Команда PUSH помещает содержимое регистра или ячейки памяти размером в 16-битовое слово на вершину стека. А команда POP, наоборот, снимает слово с вершины стека и помещает его в ячейку памяти или регистр.

Команды PUSH и POP имеют следующие форматы:

PUSH источник

POP приемник

Приведем несколько примеров:

PUSH SI; В стэк копируется содержимое регистра SI.

PUSH DS; В стэк копируется содержимое регистра DS.

PUSH CS; В стэк копируется содержимое регистра CS.

PUSH COUNTER; В стэк копируетсяc одержимое константы,

PUSH TABLE [BX][DI]; или ячейки памяти из указанного адреса.

Будучи взаимно обратными командами, PUSH и POP обычно используются парами, т.е. каждой команде PUSH в программе должна соответствовать своя команда POP. Например, при сохранении содержимого регистра АХ в стеке и последующем его восстановлении программа будет иметь вид:

PUSH AX; Сохранить АХ на вершине стека.

. . . ; Другие команды программы,

. . . ; изменяющие содержимое АХ.

. . . ;

POP AX; Восстановить значение АХ, сняв его с вершины стека.

Под вершиной стека понимается ячейка в сегменте стека, адрес которой содержится в указателе стека SP. Так как стек "растет" по направлению к младшим адресам памяти (к ячейке 0), то первое помещаемое в стек слово запоминается в ячейке стека с наибольшим адресом, следующее на два байта ниже, и т.д.

Регистр SP всегда указывает на адрес последнего слова, помещенного в стек. Следовательно, команда PUSH вычитает 2 из значения указателя стека, а затем пересылает операнд-источник (слово) в стек. Действуя обратным образом, команда POP пересылает в операнд-приемник слово, адрес которого содержится в регистре SP, a затем добавляет 2 к содержимому этого регистра. Адреса ячеек стека вычисляются по следующему известному алгоритму:

SS × 10H + SP ± 2.

Значение SP в результате исполнения команды PUSH указатель стека передвинется на два байта памяти ниже, и в этих байтах (ранее не используемых) будет содержаться значение регистра АХ. В результате исполнения команды POP содержимое регистра SP вернется в исходное состояние. Слово, считанное из стека по команде РОР, может быть помещено в любой регистр, кроме сегментного регистра CS. С помощью серии команд PUSH в стеке можно сохранить 32768 слов, причем каждая команда PUSH помещает свой операнд на вершину стека, и поэтому с помощью команды POP слова извлекаются из стека в порядке, обратном их записи. В приведенном ниже примере последовательность команд помещает значения четырех регистров в стек, а затем восстанавливает их, но уже в обратном порядке.

Mov AX,33; Занесем в АХ десятичное число 33.

Mov BX,55; Занесем в ВХ десятичное число 55.

Mov CX,66; Занесем в СХ десятичное число 66.

Mov dx,77; Занесем в DХ десятичное число 77.

PUSH AX; Сохраним содержимое АХ в стеке.

PUSH ВХ; Сохраним содержимое ВХ в стеке.

PUSH СХ; Сохраним содержимое СХ в стеке.

PUSH DX; Сохраним содержимое DХ в стеке.

POP AX; Восстановить АХ. Теперь в АХ число 77.

POP BX; Восстановить ВХ. Теперь в ВХ число 66.

POP CX; Восстановить СХ. Теперь в СХ число 55.

POP DX; Восстановить DХ. Теперь в DХ число 33.

Команды PUSH и POP удобны также для копирования содержимого одного регистра сегмента в другой. Например, с помощью команд

PUSH ES

POP DS; Можно скопировать значение регистра ES в регистр DS.

Разновидность стековых команд дает возможность сохранять в стеке содержимое регистра флагов.

PUSHF; Запись регистра флагов в стек.

POPF; Чтение регистра флагов из стека.

По первой команде в стеке сохраняется содержимое регистра флагов, а по второй из стека считывается слово и заносится в Flags. При этом команда PUSHF не меняет флаги, а команда POPF, естественно, меняет все флаги. Эти команды можно также использовать для определения или изменения состояния любого флага.

Команда обмена операндами - XCHG

Команда обмена XCHG (exchange - обменять) меняет между собой значения двух регистров или регистра и ячейки памяти. Операнды должны иметь одинаковый тип данных (байт−байт, слово−слово и т.д.). Несколько примеров:

XCHG АХ,ВХ; Обменять значения двух словных регистров.

XCHG AL,BL; Обменять значения двух байтовых регистров.

XCHG WORD_MEM,DX; Поменять значения словной ячейки памяти и словного регистра.

XCHG DL,BYTE­_ MEM; Поменять значения байтового регистра и байтовой ячейки памяти.

Команда инвертирования операндов

Команда инвертирования NOT выполняет логическую функцию НЕ над операндом и оставляет результат в операнде. Операндом может служить регистр или ячейка памяти. Тип операндов – байт, слово, двойное слово.

Пример применения команды:

Mov АХ,579BH; Загрузим данные в регистр АХ.

Not АХ; Получим в АХ 0А864Н.

Mov WORD_MEM,1111H; Загрузим в ячейку памяти число 1111Н.

Not WORD_MEM; Инвертируем его и получим число ЕЕЕЕН.

Mov BYTE­_ MEM, 0000H; Загрузим в ячейку памяти число 0000Н.

Not BYTE­_ MEM; Инвертируем его и получим число FFFFH.

Команда программного прерывания – INT

Команда INT инициирует в процессоре процедуру прерывания, в результате которой управление передается программе обработки прерывания с номером n. Этот номер указан в качестве операнда команды.

Прерывания подразделяются на аппаратные и программные, но процедуры обработки прерываний выполняются по одному алгоритму.

Команда INT (interrupt – прерывать) имеет следующий формат:

INT тип_прерывания,

где тип_прерывания −это номер, идентифицирующий один из 256 различных векто­ров, находящихся в памяти (вектор-это четырехбайтная область памяти).

Таким образом, каждому из 256 прерываний соответствует один вектор, где хранятся IP и CS программы обработки прерывания.

При исполнении команды INT микропроцессор выполняет следующие действия:

1) помещает в стек содержимое регистра флагов;

2) помещает в стек значение регистра CS;

3) помещает в стек значение регистра IP;

4) обнуляет флаг трассировки TF и флаг включения-выключения прерываний IF для исключения пошагового режима исполнения команд и блокировки других маскируемых прерываний;

5) умножая тип_ прерыванияна 4, вычисляя тем самым адрес вектора прерывания;

6) загружает из памяти второе слово вектора прерывания в регистр CS;

7) загружает из памяти первое слово вектора прерывания в регистр IP;

8) устанавливает флаги IF и TF.

Итак, после исполнения команды INT в стеке окажутся значения регистра флагов и регистров CS и IP, флаги TF и IF будут равны 0, а в регистрах CS:IP начальный адрес программы обработки прерывания. Адреса имеют длину 4 байта и они занимают первые 1К байтов.

Например, команда INT 21Н заставит микропроцессор 8086 вычислить адрес вектора 54Н (4×21Н). Следовательно, он получит 16-битовые значения регистров IP и CS, отвечающие программе обработки прерывания, из ячеек 54Н и 56Н соответственно.

Вызванная программа анализирует содержимое регистров Al, AH, DX, определяет вид вызываемой функции и осуществляет передачу управления этой функции.

Наши рекомендации