Материал: Системное программирование

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

Контрольные вопросы

  1. В чем заключается идея сегментирования адресов?

  2. Что представляет и как описывается программный сегмент?

  3. В чем состоит назначение сегментных регистров?

  4. Объясните назначение и применение директив SEGMENTиASSUME.

  5. Опишите структуру программы на языке ассемблера.

  6. Для чего используется модели памяти?

5. Основные группы команд

5.1. Соглашению по описанию команд

Базовой системой команд микропроцессоров архитектуры Intel является набор команд процессора 8086 (8080). Начиная с данного раздела, будут рассмотрены команды микропроцессора 8086, который насчитывает более 130 различных инструкций. Инструкции математического сопроцессора не рассматриваются, поскольку они не относятся к системе команд микропроцессора и реализуются сопроцессором 8087 (КР1810ВМ87).

Систему команд можно разделить на несколько функциональных групп:

  • команды пересылки данных, выполняющие обмен информацией между регистрами, памятью, портами ввода-вывода;

  • арифметические команды, выполняющие арифметические операции над двоичными и двоично-десятичными числами;

  • логические команды и команды сдвига;

  • команды управления последовательностью выполнения команд – команды переходов и циклов, вызова подпрограмм и выхода из них;

  • команды обработки строк, выполняющие перемещение, сравнение и сканирование строк;

  • стековые команды, предназначенные для работы со стеком;

  • команды управления работой микропроцессора.

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

  • NN+rb – код операции состоит из фиксированного кода NN (шестнадцатеричного), к которому прибавлен номер 8-разрядного регистра общего назначения;

  • NN+rw – код операции состоит из фиксированного кода NN (шестнадцатеричного), к которому прибавлен номер 16-разрядного регистра общего назначения;

  • /r – байт ModRegR/M, в котором поле Reg определяет номер регистра;

  • /rцифра – байт ModRegR/M, в котором поле Reg имеет значение, указанное цифрой (например, /r2 означает, что поле Reg содержит двоичную комбинацию 010);

  • cb – 8-разрядное отклонение;

  • cw – 16-разрядное отклонение;

  • cd – 32-разрядный абсолютный адрес дальнего перехода;

  • ib – 8-разрядный непосредственный операнд;

  • iw – 16-разрядный непосредственный операнд;

  • imm8 – 8-разрядное непосредственное значение (константа);

  • imm16 – 16-разрядное непосредственное значение (константа);

  • ow – 16-разрядное смещение операнда в сегменте данных;

  • r/m8 – 8-разрядный регистр общего назначения или байт памяти, определяемый полями Mod и R/M байта ModRegR/M. В коде команды может присутствовать 8- или 16-разрядное отклонение;

  • r/m16 – 16-разрядный регистр общего назначения или слово памяти, определяемое полями Mod и R/M байта ModRegR/M;

  • m8 – байт данных, заданный смещением (поле ow кода команды);

  • m16 – слово данных, заданное смещением (поле ow кода команды);

  • m16:16 – двойное слово памяти, содержащее сегмента и смещение, используемые в качестве абсолютного адреса дальнего перехода. Местоположение поля в памяти определяется полями Mod и R/M байта ModRegR/M;

  • r8 – 8-разрядный регистр общего назначения, определяемый полем Reg байта ModRegR/M;

  • r16 – 16-разрядный регистр общего назначения, определяемый полем Reg байта ModRegR/M;

  • Sreg – сегментный регистр, определяемый полем Reg байта ModRegR/M;

  • rel8 – 8-разрядный относительный адрес ближнего перехода (8-разрядное отклонение);

  • rel16 – 16-разрядный относительный адрес ближнего перехода (16-разрядное отклонение);

  • ptr16:16 – абсолютный адрес дальнего перехода (16-разрядные сегмент и смещение).

При описании команд будут указываться только обязательно присутствующие компоненты. Например, в арифметико-логических операциях, где один из операндов задаётся с помощью полей Mod и R/M байта ModRegR/M, не указывается поле отклонения, которое может присутствовать или отсутствовать в зависимости от содержимого байта ModRegR/M.

5.2. Команды пересылки данных

Команда MOV пересылает содержимое источника (второго операнда) на место приёмника (первого операнда) (табл. 5.10). Флаги команда не изменяет. Пересылаемая величина извлекается из команды, регистра или ячейки памяти, а записывается в регистр или ячейку памяти. Пересылать одной командой двойное слово запрещено.

Инструкции с кодами операций 8C и 8E обеспечивают загрузку и извлечение информации из сегментных регистров. Занесение информации в регистр CS запрещено, т.к. регистровая пара CS:IP определяет адрес команды, которая должна быть выполнена следующей. Поэтому для этой цели необходимо использовать любую инструкцию дальнего (межсегментного) перехода (см. раздел 5.5).

Табл. 10. КомандаMOV.

Код

Инструкция

Описание

88 /r

MOV r/m8, r8

Пересылка из r8 в r/m8.

89 /r

MOV r/m16, r16

Пересылка из r16 в r/m16.

8A /r

MOV r8, r/m8

Пересылка из r/m8 в r8.

8B /r

MOV r16, r/m16

Пересылка из r/m16 в r16.

8C /r

MOV r/m16, Sreg

Пересылка из Sreg в r/m16.

8E /r

MOV Sreg, r/m16

Пересылка из r/m16 в Sreg.

A0 ow

MOV AL, m8

Пересылка из m8 в AL.

A1 ow

MOV AX, m16

Пересылка из m16 в AX.

A2 ow

MOV m8, AL

Пересылка из AL в m8.

A3 ow

MOV m16, AX

Пересылка из AX в m16.

B0+rb

MOV r8, imm8

Пересылка imm8 в r8.

B8+rw

MOV r16, imm16

Пересылка imm16 в r16.

C6 /0

MOV r/m8, imm8

Пересылка imm8 в r/m8.

C7 /0

MOV r/m16, imm16

Пересылка imm16 в r/m16.

Командой MOV запрещена также пересылка из одной ячейки памяти в другую, из одного сегментного регистра в другой и запись непосредственного операнда в сегментный регистр. Если по алгоритму такое действие требуется выполнить, оно реализуется путем пересылки данных через несегментный регистр.

Например, записать число 100 в сегментный регистр DS можно так:

MOV АХ, 100

MOV DS, AX

Как правило, в команде MOV легко определить тип одного из операндов и размер пересылаемой величины, например:

MOV АХ, 300 ; пересылка слова

MOV AH, AL ; пересылка байта

В ряде случаев по операндам команды MOV нельзя определить размер пересылаемой величины. Пусть в регистре AX находится адрес некоторой ячейки памяти и требуется записать 0 в эту ячейку. Такое обнуление можно сделать с помощью команды:

MOV [AX], 0

Однако по этой команде нельзя определить, какого размера пересылаемый ноль, поскольку второй операнд может обозначать ноль размером в байт (00h) или размером в слово (0000h). Кроме того, адрес из регистра AX может быть также адресом ячейки как размером в байт, так и размером в слово (с одного и того же адреса могут начинаться ячейки разных размеров). Поэтому ассемблер зафиксирует ошибку, сообщая, что типы операндов неизвестны.

Для явного указания типов операндов команды используется оператор указания типаPTR:

<тип> PTR <выражение>

где <тип> – BYTE, WORD или DWORD, выражение может быть константным или адресным.

Если указано константное выражение, то оператор сообщает, что значение выражения (число) должно рассматриваться как величина указанного типа (размера); например, BYTE PTR 0 – ноль как байт, а WORD PTR 0 – ноль как слово.

Если в PTR указано адресное выражение, то оператор сообщает, что адрес, являющийся значением выражения, должен восприниматься ассемблером как адрес ячейки указанного типа, например: WORD PTR A – адрес A обозначает слово (байты с адресами A и A+1).

Вернемся к нашему примеру и запишем его корректно с использованием оператора PTR. При обнулении байта по адресу из регистра AX, то команда имеет вид:

MOV BYTE PTR [AX], 0 или MOV [AX], BYTE PTR 0

Если требуется переслать нулевое слово:

MOV WORD PTR [AX], 0 или MOV [AX], WORD PTR 0

Обычно принято уточнять тип операнда-адреса, а не тип непосредственного операнда.

Перестановку двух величин можно реализовать с помощью команды MOV, однако существует и специальная команда XCHG (табл. 11). Инструкция меняет местами содержимое своих операндов. Флаги команда не меняет.

Табл. 11. Команда XCHG.

Код

Инструкция

Описание

90+rw

XCHG AX, r16

AX ↔ r16

90+rw

XCHG r16, AX

r16 ↔ AX

86 /r

XCHG r/m8, r8

r/m8 ↔ r8

86 /r

XCHG r8, r/m8

r8 ↔ r/m8

87 /r

XCHG r/m16, r16

r/m16 ↔ r16

87 /r

XCHG r16, r/m16

r16 ↔ r/m16

Например, для обмена содержимого регистров AX и BX следует записать:

MOV АХ, 124

MOV BX, 43

ХСHG AX, BX ; АХ=43, BX=124

Перестановка содержимого двух ячеек памяти недопустима. Если требуется провести такую перестановку, она реализуется через регистр. Следующий пример меняет местами значения байтовых переменных X и Y:

MOV AL, X ; AL=X

XCHG AL, Y ; AL=Y, Y=X

MOV X, AL ; X=Y (исходное значение)

Рассмотрим еще несколько примеров команды MOV:

A DW 10 DUP(0) ; одномерный массив A из 10-ти элементов размером слово

B DW A ; в переменной B хранится адрес переменной A

...

MOV BX, B ; помещение в регистр BX адреса 1-ого элемента

MOV DX, [BX] ; помещение в регистр DX значения переменной A

MOV AX, BX ; помещение в регистр AX адреса 1-ого элемента A

...

MOV BX, 4 ; индекс второго элемента массива

MOV DX, A[BX] ; модификация адреса по регистру BX

Модификация адреса может быть выполнена и для двумерного массива. Например, для матрицы 10x10:

A DW 10 DUP(10 DUP (0))

запись элемента [i,j] в регистр AX будет следующей (регистры SI и DI содержат индексы):

MOV AX, A[SI][DI]

Следует заметить, что следующие записи эквиваленты (A и B – некоторые регистры-модификаторы):

[A][B] = [A]+[B] = [A+B]

В рассмотренном примере для получения адреса переменной A мы ввели дополнительную переменную B. Однако для загрузки исполнительного адреса операнда в памяти существует специальная команда LEA (табл. 12). Полученный результат заносится в регистр общего назначения. Флаги команда не изменяет. В качестве первого операнда команды должен быть указан регистр общего назначения, а в качестве второго – адресное выражение.

Табл. 12. Команда LEA.

Код

Инструкция

Описание

8D /r

LEA r16, m

Загрузка в r16 исполнительного адреса ячейки m.

Команда LEA может ссылаться на операнд источника с помощью любого типа адресации, который можно указать байтом ModRegR/M. Поля Mod и R/M байта ModRegR/M используются при вычислении адреса. Поле Reg этого байта определяет регистр общего назначения, в который должен быть занесён адрес.

Во многих случаях команда LEA идентична команде MOV с непосредственным операндом. Например, следующие две команды выполняют одинаковое действие:

MOV BX, OFFSET A

Источник: https://files.student-it.ru/previewfile/284711