Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
met.doc
Скачиваний:
15
Добавлен:
30.04.2019
Размер:
1.92 Mб
Скачать

Задачи к выполнению лабораторной работы

  1. В слове установить 0, 2 и 5 биты, сбросить 7, 11 и 13 биты, инвертировать 3, 8 и 15 биты. Остальные биты оставить без изменения.

  2. Двухразрядное двоично-десятичное число представить ASCII кодами его цифр.

  3. Двузначное десятичное число, представленное ASCII кодами своих цифр, представить двоично-десятичным кодом.

  4. Используя команды поразрядной обработки данных поместить в регистр AX значение 0F00h (непосредственные операнды не использовать).

  5. Обменять вторую и третью тетрады в слове.

  6. Без использования команды MUL организовать беззнаковое умножение слова на 5.

  7. Без использования команды DIV организовать беззнаковое деление слова на 8.

  8. Используя любые известные команды промоделировать выполнение команды AND dest,scr.

  9. Используя любые известные команды промоделировать выполнение команды OR dest,scr.

  10. Используя любые известные команды промоделировать выполнение команды XOR dest,scr.

Варианты заданий

Номер варианта

Номер задачи

Номер варианта

Номер задачи

1

1, 6

14

3, 9

2

1, 7

15

3, 10

3

1, 8

16

4, 6

4

1, 9

17

4, 7

5

1, 10

18

4, 8

6

2, 6

19

4, 9

7

2, 7

20

4, 10

8

2, 8

21

5, 6

9

2, 9

22

5, 7

10

2, 10

23

5, 8

11

3, 6

24

5, 9

12

3, 7

25

5, 10

13

3, 8

Лабораторная работа № 7

Команды передачи управления

Цель работы: изучить команды передачи управления и особенности их применения.

Основные понятия

Команды передачи управления можно подразделить на следующие группы:

– команды безусловной передачи управления;

– команды условного перехода;

– команды управления циклами.

В табл. 7.1 приведена мнемоника этих команд и описание выполняемых ими действий.

Таблица 7.1

Мнемоника команд передачи управления

Обозначение

Выполняемая функция

Команды безусловной передачи управления

CALL

Вызов подпрограммы

RET

Возврат из подпрограммы

INT

Вызов программного прерывания

INTO

Вызов прерывания переполнения

IRET

Возврат из прерывания

JMP

Безусловный переход

Команды условного перехода

Jxx

Группа команд условного перехода

JCXZ

Переход по счетчику

Команды управления циклами

LOOP

Цикл с заданным количеством повторений

LOOPE/LOOPZ

Цикл до тех пор, пока не нуль

LOOPNE/LOOPNZ

Цикл до тех пор, пока нуль

Команда CALL осуществляет передачу управления (вызов) подпрограммы и имеет следующий формат в мнемонике ассемблера:

CALL dest,

где dest – операнд, который прямо или косвенно определяет адрес подпрограммы.

Существуют четыре типа команды CALL:

– прямой внутрисегментный вызов;

– прямой межсегментный вызов;

– косвенный внутрисегментный вызов;

– косвенный межсегментный вызов.

При прямом вызове адрес подпрограммы находится непосредственно в коде команды, а при косвенном вызове – в регистре или в памяти. При внутрисегментном вызове используется только одна компонента адреса: смещение подпрограммы относительно начала текущего кодового сегмента, а при межсегментном вызове – обе компоненты адреса, т.е. сегмент, в котором располагается подпрограмма и ее смещение относительно начала этого сегмента.

В зависимости от типа вызова, команда CALL сохраняет в стеке адрес возврата из подпрограммы, т.е. адрес команды, располагаемой сразу же за командой CALL. При внутрисегментном вызове в стеке сохраняется только смещение адреса возврата, а при межсегментном – еще и текущее значение CS. Затем изменяется значение IP и, если вызов межсегментный, то и CS. Команда CALL не изменяет значение регистра флагов.

Команда CALL имеет следующие форматы машинного кода.

1. Прямой внутрисегментный вызов:

11101000

disp_low

disp_high

Поля disp_low и disp_high определяют смещение адреса подпрограммы относительно текущего значения IP.

2. Прямой межсегментный вызов:

10011010

offset_low

offset_high

seg_low

seg_high

Поля seg_low и seg_high определяют сегмент, в котором располагается подпрограмма, а поля offset_low и offset_high – смещение относительно начала этого сегмента.

3. Косвенный внутрисегментный вызов:

11111111

mod 010 r/m

disp_low

disp_high

Поля mod, r/m, disp_low и disp_high определяют 16-разрядный регистр или ячейку памяти, в которой располагается смещение подпрограммы относительно текущего кодового сегмента.

4. Косвенный межсегментный вызов:

11111111

mod 011 r/m

disp_low

disp_high

Поля mod, r/m, disp_low и disp_high определяют 32-разрядную ячейку памяти, в которой располагается сегмент и смещение подпрограммы. Смещение располагается в младших байтах этой ячейки памяти, а смещение – в старших байтах.

Если для передачи управления применяется команда CALL, то для возврата из подпрограммы требуется выполнение команды RET соответствующего типа (внутрисегментной или межсегментной). Формат команды CALL выбирается ассемблером на основании типа ее операнда, а формат RET – по контексту на основании типа подпрограммы, в которой текстуально находится RET.

Примеры использования команды CALL:

CALL 0BD4

; прямой внутрисегментный вызов

; подпрограммы, располагаемой

; по адресу CS:0BD4h

CALL 0234:0BD4

; прямой межсегментный вызов

; подпрограммы, располагаемой

; по адресу 0234:0BD4h

CALL AX

; косвенный внутрисегментный вызов

; подпрограммы, располагаемой

; по адресу CS:AX

CALL word ptr [BX + 12]

; косвенный внутрисегментный вызов

CALL dword ptr [BX + 12]

; косвенный межсегментный вызов

Команда RET осуществляет возврат из подпрограммы в вызвавшую ее программу и имеет следующий формат в мнемонике ассемблера:

RET [data],

где операнд data имеет непосредственную адресацию. Этот операнд необязателен.

Эта команда передает управление по адресу, выбираемому из стека. Допускаются внутрисегментные и межсегментные возвраты, а также возможность прибавления непосредственного значения data к содержимому SP. В случае межсегментного возврата из стека последовательно выбираются значения IP и CS, для внутрисегментного возврата – только IP. Если в команде RET указан операнд (который должен задаваться числовым выражением), то его значение затем прибавляется к содержимому указателя стека. Содержимое регистра флагов при выполнении команды RET не изменяется.

Команда RET имеет следующие форматы машинных кодов:

  1. внутрисегментный возврат

11000011

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

11000010

data_low

data_high

  1. межсегментный возврат

11001011

  1. межсегментный возврат с добавлением непосредственного значения к указателю стека

11001010

data_low

data_high

Как было отмечено выше, ассемблер выбирает тип возврата по контексту, в зависимости от типа подпрограммы, в которой текстуально находится RET. В режиме ассемблирования и дизассемблирования DEBUG для обозначения межсегментных возвратов применяется мнемоника RETF.

Примеры использования команды RET:

RET

; внутрисегментный возврат

RET 2

; внутрисегментный возврат с увеличением SP на 2

RETF

; межсегментный возврат

RETF 2

; межсегментный возврат с увеличением SP на 2

Команда INT вызывает программное прерывание и имеет следующий формат в мнемонике ассемблера:

INT type,

где type – непосредственный операнд со значением от 0 до 255.

Она записывает в стек содержимое регистра флагов, сбрасывает флаги трассировки (TF) и разрешения прерываний (IF), выполняет косвенный межсегментный вызов подпрограммы-обработчика прерывания через один из 256 возможных векторов прерывания. Таким образом, выполнение команды INT эквивалентно последовательному выполнению команд PUSHF, CLI (сбросить флаг IF) и CALL, если не обращать внимание на флаг TF.

Вектор прерывания – это адрес его обработчика, который располагается в так называемой таблице векторов прерываний – специальной области памяти, которая располагается с самого младшего адреса (0000:0000) и имеет размер 1024 байт. Каждый вектор имеет длину четыре байта. В первом слове хранится значение IP, а во втором – CS. Таким образом, в таблице векторов прерываний имеется место для 256 векторов. Вектор для прерывания 0 начинается с ячейки 0000:0000, прерывания 1 – с 0000:0004, 2 – с 0000:0008 и т.д.

Операнд type команды INT определяет номер вектора в таблице векторов прерываний.

Команда INT имеет следующие форматы машинного кода:

1) при type равно 3

11001100

2) при type не равно 3

11001101

type

Пример использования команды INT:

INT 3

; вызов прерывания с номером вектора 3

INT 21

; вызов прерывания с номером вектора 21h

Команда INTO не имеет операндов. Она вызывает обработчик прерывания переполнения. Вектор этого прерывания равен 4. В целом, эта команда аналогична команде INT 4, за тем лишь исключением, что передача управления обработчику осуществляется, если установлен флаг переполнения (OF). В противном случае команда INTO не выполняет ни каких действий.

Команда INTO имеет следующий формат машинного кода:

11001110

Пример использования команды INTO:

INTO

; вызов обработчика прерывания переполнения

Команда IRET не имеет операндов. Эта команда используется в обработчиках прерываний для завершения выполнения прерывания и возврата в прерванную программу. Она восстанавливает флаги из стека и передает управление по адресу возврата, запомненному в стеке. Выполнение команды IRET эквивалентно последовательному выполнению команд RET (межсегментный возврат) и POPF.

Команда IRET имеет следующий формат машинного кода:

11001111

Пример использования команды IRET:

IRET

; возврат из прерывания

Команда JMP выполняет безусловный переход и имеет следующий формат в мнемонике ассемблера:

JMP dest ,

где dest – операнд, который прямо или косвенно определяет адрес перехода. Существуют четыре типа команды JMP:

– прямой внутрисегментный переход;

– прямой межсегментный переход;

– косвенный внутрисегментный переход;

– косвенный межсегментный переход.

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

Команда JMP не изменяет значение регистра флагов.

Команда JMP имеет следующие форматы машинного кода.

1. Прямой внутрисегментный переход:

11101001

disp_low

disp_high

Поля disp_low и disp_high определяют смещение адреса перехода относительно текущего значения IP.

2. Короткий прямой внутрисегментный переход:

11101011

disp

Поле disp определяет смещение адреса перехода относительно текущего значения IP.

3. Прямой межсегментный переход:

11101010

offset_low

offset_high

seg_low

seg_ high

Поля seg_low и seg_high определяют сегмент, а поля offset_low и offset_high – смещение адреса перехода.

4. Косвенный внутрисегментный переход:

11111111

mod 101 r/m

disp_low

disp_high

Поля mod, r/m, disp_low и disp_high определяют 16-разрядный регистр или ячейку памяти, в которой располагается смещение адреса перехода.

5. Косвенный межсегментный переход:

11111111

mod 100 r/m

disp_low

disp_high

Поля mod, r/m, disp_low и disp_high определяют 32-разрядную ячейку памяти, в которой располагается сегмент и смещение адреса перехода. Смещение располагается в младших байтах этой ячейки памяти, а смещение – в старших байтах.

Примеры использования команды JMP:

JMP 0BD4

; прямой внутрисегментный переход

; к команде, располагаемой по адресу

; CS:0BD4h

JMP short 0BD4

; короткий прямой внутрисегментный

; переход; к команде, располагаемой

; по адресу CS:0BD4h

JMP 0234:0BD4

; прямой межсегментный переход к

; команде, располагаемой по адресу

; 0234:0BD4h

JMP AX

; косвенный внутрисегментный переход к

; команде, располагаемой по адресу CS:AX

JMP word ptr [BX + 123]

; косвенный внутрисегментный переход

JMP dword ptr [BX + 123]

; косвенный межсегментный переход

Команды JXX, входящие в группу команд условного перехода, передают управление по адресу своего операнда, когда выполняется некоторое, определяемое мнемоникой, условие, связанное с состоянием регистра флагов. Эти команды имеют следующий формат в мнемонике ассемблера:

JXX disp ,

где disp – адресное выражение типа метки с атрибутом NEAR, значение которого лежит в интервале от –128 до 127 от адреса следующей за условным переходом команды.

Все команда условного перехода имеют следующий формат машинного кода:

code

disp

Поле code определяет условие перехода, а поле disp – смещение, которое прибавляется к текущему значению IP, если условие истинно. Мнемоника, коды, условия перехода и их смысловые значения для всех команд условного перехода приведены в табл. 7.2.

Таблица 7.2

Команды условного перехода

Мнемо-ника

Поле code

Условие перехода

Смысловое значение

JA/JNBE

01110111

CF = 0 и ZF = 0

Более/Не менее или равно

JAE/JNB

01110011

CF = 0

Более или равно/Не менее

JNA/JBE

01110110

CF = 1 или ZF = 1

Не более/Менее или равно

JB/JNAE

01110010

CF = 1

Менее/Не более или равно

JC

01110010

CF = 1

Перенос

JNC

01110011

CF = 0

Нет переноса

JE/JZ

01110100

ZF = 1

Равно/Нуль

JNE/JNZ

01110101

ZF = 0

Не равно/Не нуль

JG/JNLE

01111111

ZF = 0 и SF = OF

Больше/Не меньше или равно

JGE/JNL

01111101

SF = OF

Больше или равно/Не меньше

JNG/JLE

01111110

ZF = 1 или SF  OF

Не больше/Меньше или равно

JL/JNGE

01111100

SF  OF

Меньше/Не больше или равно

JO

01110000

OF = 1

Переполнение

JNO

01110001

OF = 0

Нет переполнения

JP/JPE

01110010

PF = 1

Сумма битов четная

JNP/JPO

01111011

PF = 0

Сумма битов не четная

JS

01111000

SF = 1

Отрицательный результат

JNS

01111001

SF = 0

Положительный результат

Смысловое значение условия перехода отсылает к смыслу результата предшествующей команды, устанавливающей флаги. При этом "более" или "менее" относятся к отношению между двумя беззнаковыми величинами, а "больше" или "меньше" – к отношению между величинами со знаком.

Пример использования команд условного перехода:

CMP AX,123

; сравнить содержимое AX с числом 123h

JE M1

; если равно, перейти на метку M1

..

M1:

XOR AX,AX

..

TEST BX,1

; проверить установлен ли младший бит BX

JNZ M2

; перейти на метку M2, если это так

..

M2:

INT 20

Команда JCXZ передает управление по адресу своего операнда, если содержимое регистра CX равно нулю. Она имеет следующий формат в мнемонике ассемблера:

JCXZ disp ,

где disp – адресное выражение типа метки с атрибутом NEAR, значение которого лежит в интервале от –128 до 127 от адреса следующей за JCXZ команды. Эта команда во всем аналогична командам условного перехода.

Формат машинного кода команды JCXZ:

11100011

disp

Пример применения команды JCXZ для организации цикла "пока CX  0":

MOV CX,3

; установить счетчик цикла

M1:

JCXZ M2

; если цикл закончился, то выход

DEC CX

; изменить параметр цикла

JMP short M1

; возврат в цикл

M2:

...

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]