Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Основы программирования на Ассемблере. Учебное пособие.pdf
Скачиваний:
0
Добавлен:
11.08.2026
Размер:
607 Кб
Скачать

Приложение 1

ПЕРЕЧЕНЬ КОМАНД

AAA: Коррекция ASCII-формата для сложения

AAD: Коррекция ASCII-формата для деления

AAМ: Коррекция ASCII-формата для умножения

AAS: Коррекция ASCII-формата для вычитания

ADC: Сложение с переносом

ADD: Сложение двоичных чисел

AND: Логическое И

CALL: Вызов процедуры

CBW: Преобразование байта в слово

CLC: Сброс флага переноса

CLD: Сброс флага направления

CLI: Сброс флага прерывания

CMC: Переключение флага переноса

CMP: Сравнение

CMPS/CMPSB/CMPSW: Сравнение строк

CWD: Преобразование слова в двойное слово

DAA: Десятичная коррекция для сложения

DAS: Десятичная коррекция для вычитания

DEC: Декремент

DIV: Деление

HLT: Останов микропроцессора

IDIV: Целое деление знаковых величин

IMUL: Целое умножение знаковых величин

IN: Ввод байта или слова из порта

INC: Инкремент

INT: Прерывание

INTO: Прерывание по переполнению

IRET: Возврат из обработки прерывания

JA/JNBE: Переход по «выше» или «не ниже или равно»

JAE/JNB: Переход по «выше или равно» или «не ниже»

JB/JNAE: Переход по «ниже» или «не выше или равно»

JBE/JNA: Переход по «ниже или равно» или «не выше»

88

JC: Переход по переносу

JCXZ: Переход по «CX равно нулю»

JE/JZ: Переход по «равно» или по «нулю»

JG/JNLE: Переход по «больше» или «не меньше или равно»

JGE/JNL: Переход по «больше или равно» или «не меньше»

JL/JNGE: Переход по «меньше» или «не больше или равно»

JLE/JNG: Переход по «меньше или равно» или «не больше»

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

JNC: Переход если нет переноса

JNE/JNZ: Переход по «не равно» или по «не нуль»

INO: Переход, если нет переполнения

JNP/JPO: Переход, если нет паритета или паритет нечетный

JHS: Переход, если нет знака

JO: Переход по переполнению

JP/JPE: Переход, если есть паритет или паритет четный

JS: Переход по знаку

LAHF: Загрузка флагов в регистр АН

LDS: Загрузка регистра сегмента данных

LES: Загрузка регистра дополнительного сегмента

LODS/LODSB/LODSW: Загрузка однобайтовой или двухбайтовой строки

LOOP: Цикл

LOOPE/LOOPZ: Цикл, если равно или нуль

LOOPNE/LOOPNZ: Цикл, если не равно или не нуль

MOV: Пересылка данных

MOVS/MOVSB/MOVSW: Пересылка строки байт или строки слов

MUL: Беззнаковое умножение

NEG: Изменение знака числа

NOP: Нет операции

NOT: Логическое НЕТ

OR: Логическое ИЛИ

OUT: Вывод байта или слова в порт

POP: Извлечение слова из стека

POPA: Извлечение из стека всех общих регистров (80188, 80186, 80286)

POPF: Извлечение флагов из стека

89

PUSH: Занесение слова в стек

PUSHA: Занесение в стек всех общих регистров (80188, 80186,

80286)

PUSHF: Занесение флагов в стек

RCL и RCR: Циклический сдвиг влево через перенос и циклический сдвиг вправо через перенос

REP/REPE/REPZ/REPNE/REPNZ: Повтор строковой операции

RET: Возврат из процедуры

ROL и ROR: Циклический сдвиг влево и циклический сдвиг вправо

SAHF: Установка флагов из регистра АН

SAL, SAR, SHL и SHR: Сдвиг влево или вправо

SBB: Вычитание с заемом

SCAS/SCASB/SCASW: Поиск байта или слова в строке

STC: Установка флага переноса

STD: Установка флага направления

STI: Установка флага прерывания

STOS/STOSB/STOSW: Запись однобайтовой или двухбайтовой строки

SUB: Вычитание двоичных чисел

TEST: Проверка битов

WAIT: Установка процессора в состояние ожидания

XCHG: Перестановка байт или слов

XLAT: Перекодировка

XOR: Исключающее ИЛИ

90

Приложение 2

РАСЧЕТ СЛОЖНОСТИ АЛГОРИТМА НА ПРИМЕРЕ ПЕРЕМЕШИВАНИЯ СЛУЧАЙНЫХ ЧИСЕЛ

Программистские задачи редко решаются единственным способом. Почти всегда есть много решений . Один из существенных критериев – скорость работы программы. Если для решения какой-то задачи программа выполняет меньше действий, чем другая программа, то она работает быстрее на любом компьютере.

Задача. Расположить некоторый набор элементов в случайном порядке. Предположим, что в нашем распоряжении имеется идеальный датчик случайных чисел.

Решение 1. Будем получать от датчика случайных чисел числа от 1 до N. Первое полученное число запишем, а каждое последующее будем по очереди сравнивать со всеми уже записанными. Если это число уже встречалось, то его надо выбросить, а если еще нет, то записать. Через некоторое время записанными окажутся числа от 1 до N в случайном порядке.

Главные действия

1.Обращение к датчику случайных чисел,

2.Сравнение нового числа с имеющимися (записанными). Алгоритм может работать сколь угодно долго, так как одно число

от 1 до N может вообще не выпасть. Подсчет количества действий в среднем

Определение количества (D) обращений к датчику:

D = d[0] +d[1] +... +d[N 1],

где D – количество обращений (общее); d[k] – количество обращений к датчику для получения следующего числа, когда k-чисел уже записано.

Найдем d[k]для произвольного k.

С вероятностью q = kN при очередном обращении к датчику выпадает число, которое уже есть и с вероятностью p =1q выпадает

новое число.

Тогда p – вероятность одного обращения к датчику; pq – вероятность двух обращений к датчику (1-е обращение неудачное, 2-е –

удачное), pq2 – вероятность трех обращений к датчику.

91

Среднее число обращений получим, умножив каждую из этих вероятностей на соответствующее ей число обращений и сложив все эти произведения.

d[k] =1p +2 pq +3pq2 +... =(т.к.p =1q) =

=1q +2(1q)q +3(1q)q2 +... =

=1q +2q 2q2 +2q2 +3q2 3q3 +... =

=1q +q2 +q3 +... =11q = NNk ,

учитывая, что

q =

k

.

 

 

 

N

Тогда общее количество обращений к датчику:

D = NN + NN1 + NN2 + NN3 +... + N2 + N1 =

 

 

1

 

1

 

1

 

= N 1

+

2

+

3

+... +

 

N ln N ,

 

 

 

 

 

 

 

N

 

так как сумма N членов

гармонического ряда равна lnN

+ С,

где С = 0,5772. D(N) = N ln N , где N – количество элементов.

 

Определение количества (Т) сравнений:

 

T =t[0] +t[1] +...

+t[N 1],

(*)

где T – общее количество сравнений, t[k] – количество сравнений при записи в список числа с номером k + 1.

Для записи числа с номером k + 1 необходимо d[k] обращений к датчику. После каждого обращения полученное число сравнивается с записанными. После получения нужного сравниваем его со всеми предыдущими, т. е. проводим k сравнений.

При первых ( d[k] 1) обращениях число сравнений может оказать-

ся с равной вероятностью любым от 1 до k , так как вновь полученное

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

92

Среднее число сравнений при этом равно

k +1

, тогда

 

 

 

 

 

 

 

 

 

 

 

2

 

 

 

N

k +1

 

k(k +1)

 

k(2N k +1)

 

t[k] = k +

 

1

 

= k +

 

 

=

 

 

.

 

2

2N k

 

 

2(N k)

N k

 

 

 

 

 

 

Если вместо количества уже записанных чисел k использовать количество оставшихся чисел m, где k +m = N, то для t[k] :

t[N m] =

(N m)(N +m +1)

=

 

N 2

 

m2 + N m

=

 

N 2 + N

m +1

.

 

 

 

 

 

 

2m

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2m

 

 

 

 

 

 

2m

 

 

2

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Подставим t[k] в выражение (*):

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

T

=

 

N 2 + N

 

N +1

+

N 2

+ N

 

 

N

+... +

 

N

2 + N

2

=

 

 

 

 

 

 

 

 

 

2m

 

2

 

 

 

2(N 1)

 

2

 

 

 

 

2

 

2

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

N 2

+ N

 

1

 

 

 

 

 

 

1

 

 

 

 

1

(2 +3 +... + N +1) =

 

 

 

 

 

 

 

 

=

 

 

 

 

 

 

 

1+

 

+... +

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2

 

 

2

 

 

2

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

N

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

N 2

+ N

 

 

 

 

 

 

 

N(N +3)

 

 

N 2

 

 

 

 

 

 

1

 

 

N

 

 

 

 

3

 

 

=

 

 

 

 

 

 

 

H (N)

 

 

 

 

 

 

 

 

=

 

 

 

 

 

 

H (N)

 

+

 

 

 

H (N)

 

.

 

 

2

 

 

 

 

 

 

 

 

4

 

 

 

 

 

2

 

 

2

 

2

2

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

При больших N:

T (N)

N 2 ln N

;

 

 

T (N) =0(N 2 ln N) .

 

 

 

 

 

 

2

Итак, наше решение требует в худшем случае бесконечного количества действий, а в среднем:

N · lnN –обращений к датчику и порядка N · 2lnN сравнений.

N · 2 lnN – вычислительная сложность алгоритма.

Решение 2. Основное время при реализации решения 1 тратится на проверку следующие: «а не записано ли уже в последовательности полученное от датчика число». Попробуем сократить число проверок.

Заведем таблицу, в которой будем отмечать числа, которые уже есть в последовательности. В программе этой таблице будет соответствовать дополнительный массив из N элементов. В начальный момент таблица очищена, так как никаких чисел в последовательности нет.

93

Записывая в последовательность число i, мы отмечаем его использование в i-м элементе таблицы. Теперь каждое обращение к датчику потребует ровно одной проверки. Соответствующий элемент таблицы покажет, встречалось ли ранее полученное число. В остальном алгоритм такой же, как и в решении 1.

Количество обращений к датчику будет таким, как и в решении 1. Количество сравнений будет такое же, как количество обращений,

так как на каждое обращение приходится ровно одно сравнение.

N · lnN – вычислительная сложность алгоритма. Лучше чем в предыдущем случае, но это количество сравнений в среднем. В худшем случае оно бесконечно.

Решение 3. Предыдущие решения требовали большого числа обращений к датчику.

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

Будем запрашивать у датчика числа от 1 до m, где m – количество незаполненных мест в последовательности.

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

Например, для N = 7 в начале последовательности записаны числа

3, 6 и 2.

Необходимо записать в последовательность еще четыре элемента, поэтому при очередном обращении к датчику мы запрашиваем числа от 1 до 4.

Предположим, что получилось 3. Это означает, что необходимо записать третье из неиспользованных чисел. Будем последовательно проверять все элементы таблицы, подсчитывая при этом пустые клетки. В третью пустую клетку поставим знак «+», а ее номер покажет очередное число в последовательности. У нас число 5.

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

Количество сравнений после каждого обращения к датчику зависит и от результата этого обращения, и от результатов предыдущих обра-

94

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

T =1+2 +3 +... + N = N(N2 +1) ,

T 0(N 2 ).

Таким образом, алгоритм в решении 3 имеет вычислительную сложность N2, т. е. алгоритм квадратичный. N2>N · lnN при больших N, т. е. третий алгоритм медленнее второго, но для третьего алгоритма найденное нами количество действий постоянно, а у второго достигается только в среднем, а в худшем случае может быть сколь угодно большим. На практике это означает, что второй алгоритм быстрее, но в отдельных случаях он может работать очень долго. Третий алгоритм в среднем медленнее, но зато гарантированно завершается в фиксированное время.

Подобная ситуация типична: одно решение оказалось лучше в среднем, другое в худшем случае. Какой вариант выбрать, зависит от того, где используется программа; в случае, если необходимо многократно выполнять какие-то расчёты, важна бывает средняя скорость, и не страшно, если какой-то единичный расчёт займёт много времени. Для программ, которые должны работать в экстренных ситуациях, важна скорость, в худшем случае необходимо гарантировать, что результат будет получен вовремя.

Решение 4. В решении 3 время уходило на поиск нужного элемента в таблице. Сделаем так, чтобы результат, полученный от датчика, сразу показывал номер этого элемента. Для этого будем заносить в таблицу не плюсики, а сами числа. В начальный момент в таблице находятся все числа от 1 до N. Когда очередное число заносится в выходную последовательность, будем сдвигать элементы таблицы так, чтобы все неиспользованные значения группировались в ее начале.

95

Пусть N = 7, в начале последовательности записаны числа 3, 6 и 2. Если теперь при обращении к датчику будет получено число 2, в выходную последовательность попадает 2-й элемент, т. е. число 4, а в

таблице произойдёт очередной сдвиг.

Количество обращений к датчику равно N – 1, никаких сравнений нет, но появились сдвиги.

Количество сдвигаемых элементов на каждом шаге может быть различным – от 0 (если выпал последний из оставшихся элементов) до числа m (если выпал 1-й элемент).

Поскольку все элементы выпадают с равной вероятностью, то сред-

нее число сдвигов будет

m , а в ходе работы m изменяется от N до 2.

 

 

 

2

 

 

 

 

 

Общее количество сдвигов будет:

 

 

 

 

V =

N

+

N 1

+... +

2

=

(N 1)(N +2)

,

2

 

2

 

2

 

4

 

V 0(N 2 ).

Получился алгоритм сложности N 2, мы ничего не выиграли. Лишь коэффициент при N2 стал меньше. Но N 2 – это количество сдвигов, а не сравнений, и много будет зависеть от того, как реализованы операции сдвига и сколько времени занимает каждая из них.

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

Поэтому вместо сдвига можно просто переносить на освободившееся место в таблице ее последний (текущий) элемент.

Теперь на каждое из N – 1 обращений к датчику приходится единственный перенос элемента. Вычислительная сложность алгоритма N (линейный алгоритм).

Дальнейшее снижение сложности невозможно, так как получить последовательность из N элементов меньше, чем за N действий нельзя.

Решение 6. Кроме времени можно проанализировать память.

Для реализации последнего решения требуется 2N элементов памяти: для полученной перестановки и для вспомогательной таблицы.

96

Можно обойтись только количеством N элементов. В последнем решении мы выводим элемент из таблицы в итоговую последовательность и одновременно переносим в освободившееся место последний элемент, а последнее место в таблице не используем. Будем помещать на это последнее место тот элемент, который мы выбрали для включения в перестановку. Тем самым всё сводится к перестановке последнего элемента со случайно выбранным. А сама случайная перестановка будет формироваться с конца таблицы.

97

 

ОГЛАВЛЕНИЕ

 

Перечень сокращений..................................................................................

3

Предисловие.................................................................................................

4

1.

Архитектура микропроцессора i8086.....................................................

5

 

Регистр флагов.........................................................................................

7

2.

Структура и образ памяти программы типа .EXE и .COM..................

9

 

2.1. Структура программы типа . EXE...................................................

9

 

2.2. Структура и образ памяти программы типа .COM......................

11

3.

Процесс подготовки программы на Ассемблере ................................

13

4.

Описание данных...................................................................................

15

 

Примеры резервирования памяти........................................................

19

5.

Система команд, режимы адресации....................................................

20

6.

Циклы......................................................................................................

27

7.

Обработка строк байтов и слов.............................................................

29

 

7.1. Пересылка и сравнение строк........................................................

31

 

7.2. Поиск в строке, загрузка регистра из строки, запись в строку

 

 

из регистра.......................................................................................

32

8.

Переходы.................................................................................................

33

 

8.1. Прямой короткий (short) переход..................................................

34

 

8.2. Прямой ближний (near), или внутрисегментный переход..........

35

 

8.3. Прямой дальний (far), или межсегментный переход...................

35

 

8.4. Косвенный ближний (внутрисегментный) переход.....................

36

 

8.5. Косвенный дальний (межсегментный) переход...........................

39

 

8.6. Условный переход ..........................................................................

41

 

98

 

9. Вызовы процедур...................................................................................

43

9.1. Прямой ближний вызов..................................................................

45

9.2. Косвенный ближний вызов............................................................

46

9.3. Прямой дальний вызов...................................................................

46

9.4. Косвенный дальний вызов.............................................................

47

10.

Основные команды пересылки, обмена, ввода-вывода....................

47

11.

Основные арифметические команды.................................................

49

 

Многословное сложение.....................................................................

52

12.

ASCII-формат.......................................................................................

55

12.1. Сложение в ASCII-формате.........................................................

55

12.2. Преобразование ASCII-формата в двоичный формат...............

57

12.3. Преобразование двоичного формата в ASCII-формат ..............

60

13.

Команды логических операций: AND, OR, XOR, TEST, NOT ........

61

14.

Работа с файлом...................................................................................

62

14.1. Уровни обращения к дискам, основные понятия: блок

 

 

управления файлом, дескриптор файла, блок описания файла...

62

14.2. Функции DOS. Создание, открытие и закрытие файла.............

63

14.3. Функции DOS. Чтение и запись данных, изменение

 

 

характеристик файла.....................................................................

66

15.

Ввод информации с клавиатуры по прерываниям DOS и BIOS......

69

15.1. Ввод с клавиатуры средствами файловой системы...................

69

15.2. Использование группы функций DOS посимвольного ввода

 

 

с клавиатуры...................................................................................

72

15.3. Работа с клавиатурой на уровне BIOS ........................................

73

16.

Вывод информации на экран по прерываниям DOS и BIOS.

 

Управление экраном с помощью ESC-последовательности..................

74

Управление экраном через ESC-последовательности........................

75

17.

Сортировка одномерных массивов выбором, обменом,

 

 

вставками.............................................................................................

76

18.

Команды сдвига и циклического сдвига............................................

79

 

99

 

19. Макросредства......................................................................................

81

Использование параметров в макрокомандах.....................................

82

Библиографический список .....................................................................

85

Приложение 1.

Перечень команд..............................................................

87

Приложение 2.

Расчет сложности алгоритма на примере

 

 

перемешивания случайных чисел..................................

90

100

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