ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль...

123
Министерство образования и науки Российской Федерации Федеральное государственное бюджетное образовательное учреждение высшего профессионального образования «Сибирская государственная автомобильно-дорожная академия (СибАДИ)» Л. Е. Олейник ЯЗЫКИ ПРОГРАММИРОВАНИЯ Учебное пособие Часть 3 СДВИГОВЫЕ ОПЕРАЦИИ. ДАННЫЕ СО ЗНАКОМ И БЕЗ ЗНАКА. ВВОД-ВЫВОД НА ДИСК Омск СибАДИ 2012

Upload: others

Post on 10-Jul-2020

28 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

Министерство образования и науки Российской Федерации Федеральное государственное бюджетное образовательное

учреждение высшего профессионального образования «Сибирская государственная автомобильно-дорожная

академия (СибАДИ)»

Л. Е. Олейник

ЯЗЫКИ ПРОГРАММИРОВАНИЯ

Учебное пособие

Часть 3

СДВИГОВЫЕ ОПЕРАЦИИ. ДАННЫЕ СО ЗНАКОМ И БЕЗ ЗНАКА. ВВОД-ВЫВОД НА ДИСК

Омск СибАДИ

2012

Page 2: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

2

ББК 32.973.2 УДК 681.3.06

О 53

Рецензенты: д-р физ.-мат. наук, проф. А.К. Гуц (ОмГУ)

канд. техн. наук Д.Н. Лавров (ОмГУ) д-р техн. наук, доц. В.Н.Задорожный (ОмГТУ)

Работа одобрена редакционно-издательским советом академии в качестве учебного пособия.

Олейник, Л.Е. О 53 Языки программирования : учебное пособие: в 15-ти ч. Часть 3 : Сдвиговые операции. Данные со знаком и без знака. Ввод-вывод на диск / Л. Е. Олейник. Омск : СибАДИ, 2012.– 120 с.

Учебное пособие является третьей частью комплекта пособий из 15-ти частей по курсу «Языки программирования», изучаемому в ФГБОУ ВПО «СибАДИ» по направлению подготовки 230100.62 «Информатика и вычислительная техника», профиль «Автоматизированные системы обработки информации и управления».

Предназначается для студентов очной формы обучения (специалист, бакалавр) при выполнении работ по дисциплинам «Электронные вычислительные машины и периферийные устройства», «Системное программное обеспечение», «Системы реального времени», «Языки программирования» в компьютерных классах и при выполнении индивидуальных заданий на самостоятельную работу; преподавателем при подготовке и проведении работ в компьютерных классе.

Может использоваться желающими самостоятельно изучить программирование на ассемблере.

Табл. 19. Ил.1. Библиогр.: 3 назв.

Page 3: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

3

© ФГБОУ ВПО «СибАДИ», 2012

Page 4: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

4

ОГЛАВЛЕНИЕ

ВВЕДЕНИЕ ........................................................................................................................4

1. ЗАДАНИЕ НА ПРОГРАММИРОВАНИЕ (ОБЩАЯ ЧАСТЬ) .......................................7

2. РАЗЛИЧИЯ МЕЖДУ ПРОГРАММАМИ В EXE- И COM-ФАЙЛАХ.........................13

3. СДВИГИ И ЦИКЛИЧЕСКИЕ СДВИГИ .......................................................................20

4. ПРОГРАММИРОВАНИЕ ОБРАБОТКИ ДИСКОВЫХ ФАЙЛОВ ..............................24

5. АРИФМЕТИЧЕСКИЕ ОПЕРАЦИИ НАД ЦЕЛЫМИ ДВОИЧНЫМИ ЧИСЛАМИ СО ЗНАКОМ......................................................................................................................40

6. ДОПОЛНИТЕЛЬНЫЕ СВЕДЕНИЯ..............................................................................46

7. ТИПИЧНЫЕ ОШИБКИ ПРИ ВЫПОЛНЕНИИ РАБОТЫ ...........................................49

ЗАКЛЮЧЕНИЕ……………………………………………………………………………….

Приложение 1. ПРИМЕРЫ (ТЕКСТЫ) ПРОГРАММ ......................................................59

Приложение 2. Пример работы №3...................................................................................69

Приложение 3. Формулы (3-я работа).............................................................................890

Приложение 4. Редактирование, ассемблирование и компоновка программы. ..90 Приложение 5. Арифметические и логические операции в микропроцессорах МП8086 и МП80386…………………………….....………………………………..……..93 Приложение 6. Арифметические и логические операции в микропроцессорах МП8086 и МП80386 над числами со знаком…………………………………………..111

Page 5: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

5

ВВЕДЕНИЕ Учебное пособие включает описания лабораторных работ,

выполняемых на языке низкого уровня (язык ассемблера для микропроцессоров 8086 и 80386) под управлением операционных систем MS-DOS, Windows 95 (или выше: Windows 98 или Windows 2000) и Linux.

Состоит из 15-ти частей, каждая из которых содержит: - демонстрационные примеры, используемые преподавателем

при проведении работы в компьютерном классе (могут также использоваться при самостоятельном изучении);

- сведения, необходимые для выполнения работы; - задание на программирование (общая часть); - формулы вычислений или тексты индивидуальных заданий; - требования к программному средству, в т.ч. указания, для

каких процессора и операционной системы (ОС) оно разрабатывается, какие директивы и команды применяются, для какого режима работы процессора (реального или защищенного), какого типа (EXE- или COM-) они должны быть, сколько модулей и сегментов должны содержать и т.п.;

- описание наиболее часто встречающихся при выполнении работы ошибок программирования;

- детальные ссылки на литературу для более подробного изучения;

- примеры (тексты) программ, разработанные в соответствии с требованиями и содержащие поясняющие комментарии.

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

Таблица 1

Перечень частей

№ п/п

Название части Рассматриваемые вопросы, тип программы, количество модулей и операционная система

1 2 3 1 Определение данных.

Операции двоичной арифметики. Экранные операции

Арифметические операции сложения, вычитания, умножения и деления (операции двоичной арифметики; вычисление по формуле; определение данных; логика и организация программ - условные и безусловные переходы и циклы; ввод с клавиатуры и вывод на экран). EXE-программа (один модуль). ОС- MS-DOS

Page 6: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

6

Продолжение табл.1 1 2 3 2 Логические операции.

Условные и безусловные переходы, организация циклов, вызов процедур, использование стека

Арифметические и логические операции (И, ИЛИ, НЕ, ИСКЛЮЧАЮЩЕЕ ИЛИ; вычисление по формуле; логика и организация программ – вызов процедур near и far; использование стека; директивы extrn, public, global). EXE-программа (два модуля). ОС- MS-DOS

3 Сдвиговые операции, данные со знаком и без знака. Ввод-вывод на диск

Арифметические и логические операции и сдвиги; логика и организация программ – циклы и переходы; вызов процедур; использование стека; включаемые файлы; ввод-вывод на диск). СОМ-программа. ОС- MS-DOS

4 Использование макросов и макрокоманд. Строковые команды и команды манипуляции флагами

Вычисление по формулам и сдвиги. EXE-программа (один модуль, использование макросов и макрокоманд; строковые команды, команды манипуляции флагами). ОС- MS-DOS

5 Использование условных операторов ассемблирования Директива equ

Вычисление по формулам и сдвиги. EXE-программа (один модуль, использование макросов, макрокоманд и условных операторов ассемблирования; директива equ). ОС- MS-DOS

6 Демонстрация и опробование способов передачи параметров процедурам в модуле и между модулями

Демонстрация и опробование способов передачи процедурам в модуле и между модулями: параметра(ов) и указателя – через регистр(ы), общую ячейку, стек, в потоке кода. Передача фактических параметров макросам. Сохранение регистров в вызывающей и вызываемой процедурах. EXE-программа (два модуля; модели памяти – средняя и большая). ОС- MS-DOS

7 Оптимизация программы Минимизация объема программы (объем оперативной памяти, занимаемой машинными командами, данными и стеком) либо времени выполнения программы. Использование таблицы переходов, команд и возможностей МП Intel 80386. СОМ- или ЕХЕ-программа. ОС- MS-DOS

8 Определение интервала между событиями. Обработка прерываний, команды in и out

Определение паузы (интервала времени) между событиями. Обработка прерываний, команды in и out. EXE-программа. ОС- MS-DOS

9 Вычисление по формуле (операции двоичной арифметики и логические операции, сдвиги; ввод с клавиатуры и вывод

Вычисление по формуле (определение данных; логика и организация программ – условные и безусловные переходы и циклы; вызов процедур; ввод с клавиатуры и вывод на экран; использование стека).

на экран). Графическое приложение для Windows 95/98 и Windows NT

EXE-программа для МП Intel 80386. ОС - Windows 95/98 и Windows NT. (Модель памяти –.flat). Режим работы - процессора защищенный

Page 7: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

7

Окончание табл.1

1 2 3 10 Смешанное

программирование (связь с программами на языке Pascal; ассемблерные врезки в программу на Pascal’e)

Смешанное программирование (встроенный ассемблер; вычисление по формуле: операции двоичной арифметики и логические операции, сдвиги; определение данных; логика и организация программ – условные и безусловные переходы и циклы; вызов процедур; ввод с клавиатуры и вывод на экран; использование стека). EXE-программа для МП Intel 8086 на языке Pascal с вставками на ассемблере. ОС - MS-DOS

11 Смешанное програм-мирование (связь с программами на языке C++; ассемблерные врезки в программу на языке C++)

Смешанное программирование (ассемблер, встроенный в С++; операции двоичной арифметики и логические операции, определение данных, переходы и циклы, вызов процедур; ввод с клавиатуры и вывод на экран - средствами языка С++; сдвиги – средствами ассемблера). Режим работы процессора реальный. EXE-программа для МП Intel 80386. ОС - MS-DOS

12 Вычисление по формуле (операции двоичной арифметики и логические операции, сдвиги; ввод с клавиатуры и вывод на экран) в Linux

Вычисление по формулам. EXE-программа для МП Intel 80386, ОС – Linux

13 Резидентная программа или драйвер для MS-DOS

Разработать резидентную программу или драйвер. ОС - MS-DOS

14 Работа с дисковыми файлами (прямой и последовательный доступ) и несколькими областями DTA

Одновременная работа с несколькими файлами и несколькими областями DTA. (Назначение программы: 1) работа с файлами в базовой версии MS-DOS – ввод данных, запись в файл (прямой и последовательный доступ), чтение из файла (прямой и последовательный доступ), одновременная работа с несколькими файлами; 2) одновременная работа с несколькими областями DTA; 3) шифрование; 4) дешифрация). ЕХЕ-программа (модель памяти – компактная или большая). ОС- MS-DOS

15 Дизассемблирование программ

Восстановление текста программы по ее загрузочному модулю – COM или EXE. ОС - MS-DOS. Дизассемблер IDA Pro

Page 8: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

8

1. ЗАДАНИЕ НА ПРОГРАММИРОВАНИЕ (ОБЩАЯ ЧАСТЬ) 1.1. Составить СОМ-программу для МП Intel 8086 для

вычисления по формулам, содержащим арифметические операции сложения, вычитания, умножения и деления и логические операции И, ИЛИ, ИСКЛЮЧАЮЩЕЕ ИЛИ, НЕ. Формулы вычислений – те, что реализовывались в работах № 1 и 2 (см. уч.пос., ч.1 и 2), и дополнительно – четыре типа операций сдвига.

Таблица 1.1 Варианты используемых операций (сдвигов)

Тип сдвига Влево Вправо Логический байта

(b) слова

(w) двойного слова (d)

байта (b)

слова (w)

двойного слова (d)

Арифметический байта (b)

слова (w)

двойного слова (d)

байта (b)

слова (w)

двойного слова (d)

Циклический байта (b)

слова (w)

двойного слова (d)

байта (b)

слова (w)

двойного слова (d)

Циклический через флаг переноса

байта (b)

слова (w)

двойного слова (d)

байта (b)

слова (w)

двойного слова (d)

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

Таблица 1.2 Полный текст задания

Ассемблер для микропроцессора Intel 8086 Операционная система MS-DOS [1, с.127 128] Режим работы процессора реальный [1, с.20 60] Тип программы COM [2, с.39 40; 3, с.123] Назначение программы вычисление по формуле (арифметические и логические операции и операции сдвига); преобразование ЕХЕ-программы в COM-программу Модель памяти сверхмалая [1, с.112; 4, с. 45 46], т.е. один сегмент кода, что соответствует директиве определения модели памяти .tiny [1, с.112] Модуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху или внизу). Файл lab3_ol.asm получается из файлов lab2_1ol.asm (один сегмент стека, один сегмент данных и один сегмента кода) и lab2_1ol.asm (один сегмент кода) за счет слияния двух сегментов кода и одного сегмента данных в сегмент кода

Page 9: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

9

Продолжение табл.1.2

Директивы: определения сегментов стандартные (полные): segment, ends и assume [1, с.110 112, 4, с..43, 47 51]; -- позже: упрощенные директивы определения сегментов; определения процедур: proc и endp [2, с.43; 1, с.115]; завершения программы end [1, с.115]; определение данных: байта (db), слова (dw), двойного слова (dd); определение данных: байта (db), слова (dw), двойного слова (dd), четверного слова (dq) и десяти байтов (dt) [2, с.23 24]; префиксы переопределения типов byte ptr, word ptr, dword ptr [1, с.121] + и, кроме того, следующие: директива переопределения equ [1, с.116] директива org [1, с.116] директива include [1, с.125] Команды непривилегированные: (те же, что и во второй лабораторной работе) передачи данных: mov, lea [2, с.15 17]; -- позже: команды lahf, lds, les, sahf, xchg, xlat арифметические (двоичная арифметика): add, adc, sub, sbb, inc, dec, mul, imul, div, idiv, cbw, cwd [1, с.225; 4, с.63 67]; сравнения cmp [1, с.37; 2, с.19]; безусловного (jmp) и условного (jz, jnz, js, jns) перехода [2, с.27 28]; -- позже и самостоятельно: jp, jnp, ja, jna, jg, jge, jl, jle, jcxz, [2, с.27 28]; организации цикла loop [1, с.47 51, 2, с.28; 4, с.74]; -- позже и самостоятельно: loopz, loopnz, loope, loopne [2, с.28]; передачи управления (вызова процедур и возврата из процедур) call, ret, int [2, с.27-31]; -- позже : iret выход из обработчика прерываний [2, с.29, 1, с.120 121]; -- позже: операторы short (8), small (16), large (32) - в лаб. №7 [1, с.120

121]; работы со стеком: push, pop [2, с.27 31] -- позже и самостоятельно: pushf, popf [2, с.26]; логические: and, or, xor, not, test [2, с.23 24]. + и, кроме того, следующие: cдвига: логический влево (shl), вправо (shr); арифметический влево (sal), вправо (sar); циклический влево (rol), вправо (ror); циклический через флаг переноса (rcl), вправо (rcr) [2, с.24 - 25]; команды манипуляции флагами (установка и сброс флага): stc, clc команды условного перехода jc и jnc команда изменения знака (neg), [2, с.20]

Page 10: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

10

Продолжение табл.1.2 Адресация регистр регистр: mov ax,bx ; занести (скопировать) в ax содержимое bx [4, с.34] -- позже: mov ax,[bx] ; занести в регистр ax содержимое памяти по

адресу из регистра bx [4, с.34-40] – в уч. пос., ч.6 mov ax,[25] ; занести (скопировать) в регистр ax содержимое ячейки по смещению 25

mov al,bl ; занести (скопировать) в регистр al содержимое bl mov bx,cx ; занести (скопировать) в регистр bx содержимое cx регистр память: mov ax,worda ; занести в регистр ax значение переменной (слова) worda mov al,bytea; занести в регистр al значение переменной (байта) bytea mov dx,worda ; занести в регистр dx значение переменной (слова) worda память регистр: mov worda,ax ; занести в ячейку worda содержимое регистра ax (слово) mov bytea,al ; занести в ячейку bytea содержимое регистра al (байт) mov worda,cx ; занести в ячейку worda содержимое регистра cx (слово) регистр непосредственный операнд: mov ax,25 ; занести в регистр ax значение 25 mov bx,2 ; занести в регистр bx значение 2 mov al,25 ; занести в регистр al значение 25 память непосредственный операнд: mov worda,25 ; занести в ячейку worda значение 25 mov bytea,25 ; занести в ячейку bytea значение 25 Использование процедур операционной системы: (те же, что и во второй лабораторной работе) ввод с клавиатуры [2, с.57 62] вывод на экран [2, с.63 67] ввод-вывод на диск (FCB, последовательная запись и чтение; длина записи = 128 байтов при открытии и создании файла; создание (16h), открытие (0fh), определение области DTA (1ah), последовательная запись (15h), последовательное чтение (14h), закрытие файла (10h) -- позже: ввод/вывод на диск через дескрипторы [2, с. 48-52]; Дополнительная информация (рассматривается на практических занятиях): (те же, что и во второй лабораторной работе) - процессоры Intel в реальном режиме [1, с.20 60]; - последовательность выполнения команд [2, с.12 13]; - структура процессора 8086 [2, с.9, рис. 1.1.2]; - сегментная адресация [2, с.9, рис.1.1.3]; - представление данных в компьютерах [1, с.14 19]; - логика и организация программ:

Page 11: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

11

Продолжение табл.1.2 а) условные и безусловные переходы [3]; б) вызов процедур [3] в) циклы [1, с.215]; - использование стека; - дисковая память: а) организация [3, с.45 51]; б) функции базовой версии DOS [3]; - переопределение данных: префикс ptr [1]; + и, кроме того: - преобразование ЕХЕ - программы в COM - программу [3] - операции сдвига [2] - циклы и переходы [1, с. 47-51] - операции сравнения и тестирования - данные со знаком и без знака [1] - включаемые файлы – директива include - компоновка com-программы (tlink /tdc lab3_fio.obj) Примеры программ: l_3bnn.asm (СОМ-программа, но уже с макросами, которых в 3-й лабораторной не должно быть) в папке l#03 Используемое ПО: tasm.exe, tlink.exe, td.exe Формируемые файлы: lab3_fio.obj, lab3_fio.lst,lab3_fio.com Литература: 1. Зубков С.В. Assembler для DOS, Windows и UNIX. – 3-е изд., стереотип. – М.: ДМК Пресс; СПб.: Питер, 2005. – 608 с.

2. Бурдаев О.В., Иванов М.А., Тетерин И.И. Ассемблер в задачах защиты информации / под ред. И.Ю.Жукова. – М.: КУДИЦ-ОБРАЗ, 2002. – 320с.

3. Абель Питер. Язык ассемблера для IBM PC и программирования / пер. с англ. – М.: Высшая школа. – 1992. – 447 с.

4. Олейник Л.Е. Язык ассемблера для микропроцессора 8086: курс лекций. – Омск: Сибирская региональная школа бизнеса, 2000 5. Дао Л. Программирование микропроцессора 8088. – М.: Мир, 1988. – 356 с. 6. Абель Питер. Ассемблер. Язык и программирование для IBM PC: пер. с англ., - изд. 5-е, стереот. – Киев: Век; М.: Энтроп; Киев: НТИ, 2003. – 736 с. Задание (З_ЛР_3): Составить СОМ-программу для МП Intel 8086 для вычисления по трем формулам: 1) содержащей арифметические операции сложения, вычитания, умножения и

деления (формулу взять у преподавателя, а при самостоятельном изучении в уч.пос., ч.1), если X1=1; 2) содержащей логические операции (формулу 2 взять у преподавателя, а при

самостоятельном изучении из уч.пос., ч.2), если X1=2 или 2,3,4 и т.д.; 3) содержащей сдвиг логический, арифметический, циклический и

циклический с переносом (формулу взять у преподавателя, а при самостоятельном изучении в прил.3), если X1= N Использовать в качестве аргументов b1, b2,...,w1, w2,...,d1, d2,... байты,

слова и двойные слова.

Page 12: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

12

Продолжение табл.1.2 Все данные (b1, b2, b3,...,w1, w2, w3,...d1, d2, d3,....) вводятся c

клавиатуры. Результат выводится на экран (после очистки в свободную строку)

Данные для соответствующей формулы вводятся после запроса (в диалоге должна быть прокрутка снизу вверх). Применяется перевод из ASCII-формата в двоичный код (для данных, введенных с клавиатуры) и перевод из двоичного кода в ASCII-формат (для данных, выдаваемых на экран, на НМД и на принтер) В данной программе могут быть использованы в качестве процедур программы, реализующие задания для лабораторных работ № 1 и 2 (lab1 и lab2) Х1 вводится с клавиатуры по запросу Результат вывести на экран по формату:

"Вычисление по формуле (приводится соответствующая cтрока формулы) Y=

Кроме того, полученный pезультат заносится в файл на диске (после оставшейся в нем инфоpмациии о предыдущих вычислениях по формулам лабораторных работ № 1, или № 2, или № 3 по фоpмату:

"Вычисление по формуле (приводится соответствующая cтрока формулы) или «сдвиг <название, направление и на какое количество битов>», Y=____ для b1=__;b2=__;b3=__; b4=__;w1=___и т.д."

Лабораторная считается сданной, если: - в комментариях к вычислениям указана максимальная длина промежуточных результатов; - при ассемблировании и компоновке не обнаружено ошибок; - результат совпадает с результатом ручного просчета (получены правильные результаты при произвольно заданных исходных данных); - текст программы прокомментирован (комментарии поясняют последовательность вычисления по формуле; назначение используемых процедур; способ передачи параметров и получение результатов) Типичные ошибки: (те же, что и во второй лабораторной работе) - программист забывает о возврате в DOS [4, с. 99]; - программист забывает о стеке [4, с.103]; - вызывает процедуру, которая портит содержимое нужных регистров [4, с.104]; - неправильный порядок операндов [4, с.103]; - потеря содержимого регистра при умножении [4, с.115]; - изменение отдельными инструкциями флага переноса [4, с.116]; - программист долго не использует состояние флагов [4, с.116]; - открытая процедура или открытый сегмент [5, с.120 121]; - неопределенные символические имена [5, с.121 122]; - повторное определение символического имени [5, с.122 123];

Page 13: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

13

Окончание табл.1.2 - ошибки выполнения программы как результат ошибок программирования [5, с.123 124]; - ошибки при использовании регистров [5, с.124 125]: а) 8- и 16-разрядный регистры для записи двух операндов одной команды; б) 8-разрядный регистр указывается для работы со стеком; в) сегментные регистры прямо используются в арифметических вычислениях, логическихоперациях или для непосредственной передачи данных; г) сегментные регистры могут использоваться либо как источники операндов, либо как приемники операндов, но никак не одновременно - выход из диапазона адресов, т.е. относительный адрес символического имени, используемого в качестве операнда адреса перехода, выходит за диапазон +127 байтов –128 байтов от конца команды условного перехода [5, с.125]; - использование непосредственных данных в качестве операнда-приемника [5, с.125 126]; - программист забывает об инструкции ret [4, с.100]; - генерация неверного типа возврата [4, с.101]; - ошибки при использовании условных переходов [4, с.106]; - не путайте операнды в памяти и непосредственные операнды [4, с..117]; - границы сегментов [4, с.118] + и, кроме того: - программист забывает о стеке (на стек остается слишком мало места в кодовом сегменте СОМ-программы); Задание повышенной сложности (ЗПС_ЛР_3): Составить СОМ-программу для МП Intel 8086 для вычисления по трем формулам: 1) содержащей арифметические операции сложения, вычитания, умножения и

деления (формулу взять у преподавателя, а при самостоятельном изучении в уч.пос., ч.1), если X1=1; 2) содержащей логические операции (формулу 2 взять у преподавателя, а при

самостоятельном изучении - из уч.пос., ч.2), если X1=2 или 2,3,4 и т.д.; 3) содержащей сдвиг логический, арифметический, циклический и

циклический с переносом (формулу взять у преподавателя, а при самостоятельном изучении в прил.3), если X1= N; Результат выводится на экран (после очистки строк) со знаком.

Page 14: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

14

2. РАЗЛИЧИЯ МЕЖДУ ПРОГРАММАМИ В EXE- И COM-ФАЙЛАХ

2.1. Сравнение EXE-программ и COM- программ

Cуществуют определенные различия между программой,

выполняемой как EXE-файл, и программой, выполняемой как COM-файл.

Таблица 2.1 Сравнение EXE-программ и COM- программ

№ п/п

Отличия EXE-программа COM- программа Примечания

1 2 3 4 5 1 Размер

прог-раммы

Может иметь любой размер

Ограничен раз-мером одного сегмента и не превышает 64К

COM-файл всегда меньше, чем соответствующий EXE-файл

2 Сег-мент стека

Определяет программист

Стек генерируется автоматически

При создании ассемб-лерной программмы, которая будет преобра-зована в COM-файл, сегмент стека прог-рамммистом не задается

3 Сег-мент данных

Сегмент данных обычно опреде-ляяется, а ds инициализирует-ся адресом это-го сегмента

Сегмент данных отсутствует (все данные должны быть определены в сегменте кода)

Простой способ решения этого вопроса – см. ниже

4 Инициа-лизация

Программируют-ся запись нуле-вого слова в стек и инициализа-ция регистра ds

Т.к. COM-про-грамма не имеет ни стека, ни сегмента данных, то эти шаги отсутствуют

Когда COM-программа начинает работать, все сегментные регистры содержат адрес префик-са программного сег-мента (PSP), 256-байтового блока т.к. адресация начинается со смещения 100h от начала PSP, то в программе после директивы segment идёт директива org 100h

Page 15: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

15

Окончание табл. 2.1

1 2 3 4 5 5 Обра-

ботка: ассемб-лиро-вание и компо-новка

См. уч.пос., ч.1 (подраздел 2.3) и ч.2 (подраздел 2.3)

См. выше (подраздел 2.3)

Отличается параметром /tdc для tlink

Когда программа создается для выполнения как COM-файл, то

компоновщиком будет выдано сообщение: Warning: No STACK Segment (Предупреждение: Сегмент стека не определен) Это сообщение можно игнорировать, так как определение стека

в программе не предполагалось. Пример COM-программы приведен ниже [6, с. 124].

codesg segment para 'Code' assume cs:codesg,ds:codesg,ss:codesg,es:codesg org 100h ;начало программы после PSP

begin: jmp main ; обход данных (переход к следующей команде)

; --------------------------------------------------- flda dw 250 ;определение данных fldb dw 125 fldc dw ? ; --------------------------------------------------- main proc near

mov ax,flda ;переслать 0250 в ax add ax,fldb ;прибавить 0125 к ax mov fldc,ax ;записать сумму в fldc ret ;вернуться в DOS

main endp codesg ends

end begin Эта COM-программа выполнит те же действия, что и

приведенная ниже EXE-программа (измененные и удаленные из этой программы строки выделены прописными буквами и заливкой) STACKSG SEGMENT PARA SТACK 'Stack'

DB 32 DUP(?) STACKSG ENDS ;------------------------------------------------- DATASG SEGMENT PARA 'Data'

Page 16: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

16

flda dw 250 ;определение данных fldb dw 125 fldc dw ? DATASG ENDS ;------------------------------------------------- codesg segment para 'Code' begin proc far assume cs:codesg,ds:codesg,ss:codesg,es:nothing

PUSH DS ;записать ds в стек SUB AX,AX ;записать в стек PUSH AX ; нулевой адрес MOV AX,DATASG ;поместить адрес DATASG MOV DS,AX ; в регистр ds

mov ax,flda ;переслать 0250 в ax add ax,fldb ;прибавить 0125 к ax mov fldc,ax ;записать сумму в fldc ret ;вернуться в DOS

begin endp codesg ends

end begin Обратите внимание на следующие изменения в COM-программе

(по сравнению с EXE-программой): - сегмент стека и сегмент данных отсутствуют; - директива assume указывает ассемблеру установить

относительные адреса с начала сегмента кодов. Регистр cs также содержит этот адрес, являющийся к тому же адресом префикса программного сегмента (PSP). Директива org служит для резервирования 100h байтов от начального адреса под PSP;

- директива org 100h устанавливает относительный адрес для начала выполнения программы. Программный загрузчик использует этот адрес для командного указателя;

- команда jmp используется для обхода данных, определенных в программе.

Если элементы данных определяют после команд, то первая команда jmp не требуется. Кодирование элементов данных перед командами позволяет ускорить процесс ассемблирования и является методикой, рекомендуемой в руководстве по ассемблеру.

Page 17: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

17

2.2. Стек для COM-программы

Для COM-файла DOS автоматически определяет стек и устанавливает oдинаковый общий сегментный адрес во всех четырех сегментных pегистрах. Если для программы размер сегмента в 64К является достаточным, то DOS устанавливает в регистре SP адрес конца cегмента – шестнадцатеричное fffe (FFFEh). Это будет верх стека. В обоих случаях DOS записывает затем в стек нулевое слово.

Возможность использования стека зависит от размера программы и ограниченности памяти. С помощью команды dir можно определить pазмер файла и вычислить необходимое пространство для стека.

2.3. Программы в виде COM- файлов

Пример 1

; Умножение двойных слов codesg segment para 'Code'

assume cs:codesg,ds:codesg,ss:codesg org 100h

begin: jmp short main ; --------------------------------------------- multcnd dw 3206h ;элементы данных

dw 2521h multplr dw 6400h

dw 0A26h product dw 0

dw 0 dw 0 dw 0

; --------------------------------------------- main proc near ;основная процедура

call e10xmul ;вызвать 1-е умножение call z10zero ;очистить произведение call f10xmul ;вызвать 2-е умножение ret

main endp ; Умножение двойного слова на слово: ; ----------------------------------------------- e10xmul proc

mov ax,multcnd+2 ; умножить правое слово mul multplr ; множимого mov product+4,ax ;записать произведение

Page 18: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

18

mov product+2,dx

mov ax, multcnd ;умножить левое слово mul multplr ; множимого add product+2,ax ; сложить с полученным ранее adc product,dx ret

e10xmul endp ; Умножение двух двойных слов: ; -------------------------------------------- f10xmul proc

mov ax, multcnd+2 ; слово-2 множимого mul multplr+2 ; * слово-2 множителя mov product+6,ax ; сохранить результат mov product+4,dx

mov ax, multcnd+2 ; слово-2 множимого mul multplr ; * слово-1 множителя add product+4,ax ; сложить с предыдущим adc product+6,dx adc product,00 ;прибавить перенос

mov ax, multcnd ; слово-1 множимого mul multplr+2 ; * слово-2 множителя add product+4, ax ; сложить с предыдущим adc product+6,dx adc product,00 ; прибавить перенос mov ax,multcnd ; слово-1 множимого mul multplr ; * слово-1 множителя add product+2,ax ; сложить с предыдущим adc product,dx ret

f10xmul endp ; Очистка области результата: ; ---------------------------------------- z10zero proc

mov product,0000 mov product+2,0000 mov product+4,0000 mov product+6,0000 ret

z10zero endp codesg ends

Page 19: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

19

end begin -----------------------------------------------------------

Пример 2 ; Организация бесконечного цикла с помощью jmp codesg segment para 'Code'

assume cs:codesg,ds:codesg,ss:codesg,es:codesg org 100h

main proc near mov ax,01 ;инициализация ax mov bx,01 ;инициализация bx mov cx,01 ;инициализация cx

a20: add ax,01 ;прибавить 01 к ax add bx,ax ;прибавить ax к bx shl cx,1 ;удвоить cx jmp a20 ;переход на a20

main endp codesg ends

end main

После ассемблирования получится программа:

; Организация цикла с помощью jmp 0100 codesg segment para 'Code' 0100 assume cs:codesg,ds:codesg,ss:codesg,es:codesg 0100 org 100h 0100 main proc near 0100 B8 0001 mov ax,01 ;инициализация ax 0103 BB 0001 mov bx,01 ; инициализация bx 0106 B9 0001 mov cx,01 ; инициализация cx 0109 a20: 0109 05 0001 add ax,01 ; прибавить 01 к ax 010C 03 D8 add bx,ax ; прибавить 01 к bx 010E D1 E1 shl cx,1 ; удвоить cx 0110 EB F7 mp a20 ; переход на a20 0112 main endp 0112 codesg ends 0112 end main -----------------------------------------------------------

Пример 3 ; Организация цикла командой loop codesg segment para 'Code'

assume cs:codesg,ds:codesg,ss:codesg,es:codesg org 100h

Page 20: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

20

main proc near mov ax,01 ; инициализация ax mov bx,01 ; инициализация bx mov dx,01 ; инициализация dx mov cx,10 ; число циклов

; a20:

inc ax ; прибавить 01 к ax add bx,ax ; прибавить ax к bx shl dx,1 ; удвоить dx loop a20 ; уменьшить cx и повторить цикл, если

; не нуль, т.е. переход на a20 ret ;завершить работу

begin endp codesg ends

end begin

Контрольные вопросы 1. Каков максимальный размер СОМ-программы? 2. Какие сегменты можно определить в программе, которая будет

преобразована в COM-файл? 3. Как преобразовать исходный текст EXE-программы в СОМ-

программу? 4. Два варианта размещения данных в СОМ-программе. 5. Отличие директивы assume СОМ-программы от директивы

assume EXE-программы. 6. Как формируется стек для СОМ-программ?

Page 21: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

21

3. СДВИГИ И ЦИКЛИЧЕСКИЕ СДВИГИ

3.1. Перечень сдвиговых операций

В процессорах 8086 имеется возможность сдвигать биты регистра или переменной в памяти влево или вправо.

Возможны следующие операции: логический сдвиг влево или вправо; арифметический сдвиг влево или вправо; циклический сдвиг влево или вправо; циклический сдвиг через флаг переноса влево или вправо.

3.2. Логический сдвиг

Инструкция shl (сдвиг влево, синоним sal) перемещает

каждый бит операнда-приемника на один разряд влево, по направлению к самому значащему биту. Значение 10010110b (96h или 150 в десятичном представлении без знака), записанное в al, сдвигается влево с помощью инструкции shl al,1. В результате получается значение 00101100b (2Ch), которое записывается обратно в регистр al. Флаг переноса устанавливается в значение 1.

Самый значащий (старший) бит сдвигается из операнда и попадает во флаг переноса, а в наименее значащий бит заносится 0.

Сдвиг влево чаще всего используется для выполнения с помощью операции shl умножения на степень числа 2. Например, с помощью следующих инструкций dx умножается на 8:

shl dx,1 ; dx := dx * 2 shl dx,1 ; dx := dx * 2 shl dx,1 ; dx := dx * 2

Умножение с помощью сдвига выполняется гораздо быстрее, чем с помощью операции mul.

В предыдущем примере в инструкции shl используется второй операнд значение 1 указывает, что содержимое dx нужно сдвинуть на 1 бит. Процессор 8086 не поддерживает использования в качестве константы сдвига других, отличных от единицы, постоянных значений: 2, 3 и т.д. Однако в качестве счетчика сдвигов допускается использование регистра cl.

Например: mov cl,3 shl dx,cl ;dx := dx *8

умножают содержимое регистра dx на 8 (как и в предыдущем примере).

Page 22: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

22

Инструкция shr (сдвиг вправо) выполняет сдвиг разрядов операнда вправо на 1 или cl битов, затем сдвигает наименее значащий бит во флаг переноса и помещает 0 в самый значащий бит. Инструкция shr дает быстрый способ выполнения беззнакового деления на степень числа 2.

3.3. Арифметический сдвиг

Инструкция sar (арифметический сдвиг вправо) сдвигает

наиболее значащий бит операнда вправо в следующий бит, а затем копирует обратно. Значение 10010110b (96h или -106 в десятичном представлении со знаком), записанное в регистре al, сдвигается вправо с помощью инструкции sar al,1. В результате получается значение 11001011b (0cbh или -53 в десятичном представлении со знаком), которое записывается обратно в регистр al.

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

сохраняется знак операнда, поэтому инструкцию sar полезно использовать для выполнения деления со знаком на степень числа 2. Например, в результате выполнения инструкций:

mov bx,-4 sar bx,1 в регистре bx будет записано значение -2.

3.4. Циклический сдвиг

Инструкция циклического сдвига вправо ror наименее значащий бит сдвигает в наиболее значащий бит, а также во флаг переноса. Значение 10010110b, записанное в регистре al, циклически сдвигается вправо с помощью инструкции ror al,1. В результате получается значение 01001011b, которое записывается обратно в регистр al. Флаг переноса устанавливается в значение 0.

Операция циклического сдвига влево rol сдвигает наиболее значащий бит в наименее значащий.

Page 23: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

23

3.5. Циклический сдвиг через флаг переноса

Инструкция циклического сдвига вправо через флаг переноса rcr сдвигает операнд вправо, при этом наиболее значащий бит сдвигается из флага переноса. Значение 10010110b (96h или 159 в десятичном представлении), записанное в регистре al, циклически сдвигается вправо через флаг переноса, начальное значение которого равно 1, с помощью инструкции rcr al,1. В результате получается значение 11001011b, которое записывается обратно в регистр al. Флаг переноса устанавливается в значение 0, т.к. наименее значащий бит равен нулю.

Инструкция циклического сдвига влево через флаг переноса rcl сдвигает операнд влево, при этом наименее значащий бит сдвигается из флага переноса. Инструкции rcr и rcl полезно использовать для сдвига операнда, состоящего из нескольких слов. Например, следующие инструкции выполняют умножение значения в dx:ax, размером в двойное слово, на 4:

shl ax,1 ; бит 15 регистра ax сдвигается во флаг переноса rcl dx,1 ; флаг переноса сдвигается в бит 0 регистра dx shl ax,1 ; бит 15 регистра ax сдвигается во флаг переноса rcl dx,1 ; флаг переноса сдвигается в бит 0 регистра dx Инструкции циклического сдвига, аналогично инструкциям

сдвига, могут сдвигать операнд на 1 бит или на число битов, заданных регистром cl.

Контрольные вопросы 1. Можно ли применять инструкции (команды) сдвига по

отношению к регистрам: al, ah, bl, bh, cl, ch, dl,dh; ax, bx, cx, dx, si, di, cs, ds, ss, es, sp, bp, ip, flags; eax, ebx, ecx, edx, esi, edi, esp, ebp, eip, eflags?

2. Можно ли применять инструкции (команды) сдвига по отношению к ячейкам памяти:

размером один байт (b1, b2, …) размером одно слово (w1, w2, …) размером одно двойное слово (d1, d2,…)?

3. Назовите виды сдвигов. 4. Каков результат выполнения программы:

mov ax, 1 shl ax,1 ror ax,1?

5. Перечислите все восемь инструкций сдвигов.

Page 24: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

24

6. Каков результат выполнения программы: mov ax, 1 shr ax,1 rol ax,1?

7. Каков результат выполнения программы: mov ax, 32768 shl ax,1 ror ax,1?

8. Каков результат выполнения программы: mov ax, 32768 shr ax,1 rol ax,1?

9. Каков результат выполнения программы: mov ax, 32768 sal ax,1 ror ax,1?

10. Каков результат выполнения программы: mov ax, 32768 sar ax,1 rol ax,1?

11. Каков результат выполнения программы: mov ax, 32768 rcl ax,1 ror ax,1?

12. Каков результат выполнения программы: mov ax, 32768 rcr ax,1 rol ax,1?

13. Каков результат выполнения программы: mov ax, 32768 rcl ax,1 rcr ax,1?

14. Каков результат выполнения программы: mov ax, 32768 rcr ax,1 ror ax,1?

15. Каков результат выполнения программы: mov ax, 32768 mov dx,0 rcl ax,1 rcr dx,1?

Page 25: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

25

4. ПРОГРАММИРОВАНИЕ ОБРАБОТКИ ДИСКОВЫХ ФАЙЛОВ

4.1. Общие сведенья о работе с файлами

Обработка дисковых файлов в базовой DOS включает определение блока управления файлом (FCB file control block), который описывает файл и его записи. Передача адреса блока FCB в DOS обязательна для всех дисковых операций ввода-вывода.

Запись файла на диск требует, чтобы прежде он был "создан" и DOS сгенерировала соответствующий элемент в оглавлении. Когда все записи файла будут записаны, программа должна "закрыть" файл, чтобы DOS завершила обработку оглавления. Чтение файла требует, чтобы он был сначала "открыт" для того, чтобы убедиться в его существовании. Так как записи имеют фиксированную длину, обработка записей дискового файла может осуществляться как последовательно, так и произвольно.

Метод доступа к дисковой памяти, поддерживающий использование оглавления, "блокирование" и "разблокирование" записей, обеспечивается прерыванием DOS 21h. Более низкий уровень, обеспечивающий абсолютную адресацию дисковых секторов также через DOS, выполняется посредством прерываний 25h и 26h. Самый низкий уровень обеспечивается прерыванием BIOS 13h, которое позволяет выполнить произвольную адресацию в дисковой памяти по номеру дорожки и сектора. Методами DOS осуществляют некоторую предварительную обработку до передачи управления в BIOS.

Термин “кластер” определяет один или более секторов с данными в зависимости от дискового устройства.

Примеры работы с файлами и использования операций создания, открытия, записи или чтения и закрытия приведены на рис. 4.1

4.2. Блок управления файлом (FCB)

Для выполнения ввода-вывода на диск в базовой DOS необходимо определить блок FCB. Блок FCB не поддерживает путь доступа к файлу, поэтому он используется для обработки файлов в текущей директории. Блок FCB содержит (рис. 4.2) описание файла и его

Page 26: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

26

записей. Пользователь должен инициализировать байты 015 и 3236, DOS устанавливает байты 1631.

в) а)

Создать файл

Записать в файл

Закрыть файл

Открыть файл 1

Открыть файл 2

Чтение из файла 1

Вычисления

Закрыть файлы

Записать в файл 2

б)

Открыть файл

Чтение из файла

Закрыть файл

Открыть файл

Записать в файл

Записать в файл

Записать в файл

Закрыть файл

г) е)

Открыть файл

Чтение из файла

Вычисления

Записать в файл

Закрыть файл

д)

Открыть файл

Записать в файл

Закрыть файл

Page 27: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

27

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

Таблица 4.2

Байты Назначение 0 Указывает дисковод: 01 для дисковода A, 02 для B и т.д. 1-8 Имя файла, выровненное по левой границе с конечными пробелами, если

имя меньше 8 байтов. Поле может содержать зарезервированные имена, например LPT1 для принтера

9-11 Тип файла для дополнительной идентификации, например dat или asm. Если тип файла меньше трех байтов, то он должен быть выровнен по левой границе и дополнен конечными пробелами. DOS хранит имя и тип файла в оглавлении

12-13 Номер текущего блока. Блок содержит 128 записей. Для локализации конкретной записи используются номер текущего блока и номер текущей записи (байт 32). Первый блок файла имеет номер 0, второй 1 и т.д. Операция открытия файла устанавливает в данном поле 0

14-15 Логический размер записи. Операция открытия инициализирует размер записи значением 128 (т.е. 80h). После открытия и перед любой операцией чтения или записи можно устанавливать в данном поле любое требуемое значение длины записи

16-19 Размер файла. При создании файла DOS вычисляет и записывает это значение (произведение числа записей на размер записей) в оглавление. Операция открытия выбирает размер файла из оглавления и заносит его в данное поле. Программа может читать это поле, но не может менять его

20-21 Дата. При создании или последней модификации файла DOS записывает дату в оглавление. Операция открытия выбирает дату из оглавления и заносит в данное поле

22-31 Зарезервировано для DOS 32 Текущий номер записи. Данное поле содержит текущий номер записи (0-

127) в текущем блоке (см. байты 1213). Система использует текущие значения блока и записи для локализации записи в дисковом файле. Обычно номер начальной записи в данном поле 0, но его можно заменить для начала последовательной обработки на любое значение от 0 до 127

33-36 Относительный номер записи. Для произвольного доступа при операциях чтения или записи данное поле должно содержать относительный номер записи. Например, для произвольного чтения записи номер 25 (т.е. 19h), необходимо установить в данном поле 19000000h. Произвольный доступ характеризуется тем, что система автоматически преобразует относительный номер записи в текущие значения блока и записи. Ввиду ограничения на максимальный размер файла (1 073 741 824 байта), файл с короткими записями может содержать больше записей и иметь больший относительный номер записи. Если размер записи больше 64, то байт 36 всегда содержит 00

Рис.4.1 Примеры работы с файлами и использования операций создания, открытия, записи или чтения и закрытия

Page 28: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

28

4.3. Использование блока FCB для создания файла на диске

Для ссылки на каждый дисковый файл программа должна

содержать правильно составленный блок управления файлом (в той части COM-программы, где описываются данные, или в сегменте данных EXE-программы). Операции ввода-вывода на диск требуют установки адреса блока FCB в регистре dx. Доступ к полям блока FCB осуществляется по этому адресу с помощью регистровой пары ds:dx. Для создания нового файла программа использует функцию 16h в прерывании DOS int 21h следующим образом:

mov ah,16h ; создание lea dx,FCBname ; дискового файла int 21h ; вызов DOS DOS осуществляет поиск имени и типа файла, взятого из

соответствующих полей FCB в оглавлении. Если элемент оглавления, содержащий необходимое имя (и тип), будет найден, то DOS очищает найденный элемент для нового использования; если такой элемент не найден, то DOS ищет свободный элемент. Затем операция устанавливает размер файла в 0 и "открывает" файл. На этапе открытия происходит проверка доступного дискового пространства, результат такой проверки устанавливается в регистре al (табл. 4.3).

Таблица 4.3

al Результат проверки 00 На диске есть свободное пространство FF На диске нет свободного пространства

При открытии в блок FCB также устанавливаются номер текущего блока 0 и размер записей (по умолчанию) 128 байтов. Прежде чем начать запись файла, можно заменить это значение на требуемый размер записей.

В DTA не требуется устанавливать ограничитель конца записи, т.к. блок FCB содержит размер записей. Для указания на начало выводимой на диск информации необходимо с помощью функции 1ah сообщить DOS адрес DTA, т.е. области передачи данных (DTA disk trausfer area). В любой момент времени может быть активна только одна область DTA. В следующем примере инициализируется адрес DTA:

mov ah,1ah ; установка адреса lea dx,DTAname ; DTA int 21h ; вызов DOS

Page 29: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

29

Если программа обрабатывает только один дисковый файл, то должна быть только одна установка адреса DTA для всего выполнения. При обработке нескольких файлов программа должна устанавливать соответствующий адрес DTA непосредственно перед каждой операцией чтения или записи. Для последовательной записи на диск существует функция 15h:

mov ah,15h ; последовательная lea dx,FCBname ; запись int 21h ; вызов DOS Операция записи использует информацию из блока FCB и адрес

текущего буфера DTA. Если длина записи равна размеру сектора, то запись заносится на диск. В противном случае записи заполняют буфер по длине сектора и затем буфер записывается на диск. Например, если длина каждой записи составляет 128 байтов, то буфер заполняется четырьмя записями (4*128=512) и затем буфер записывается в дисковый сектор. После успешного занесения записи на диск DOS увеличивает в блоке FCB размер файла на размер записи и текущий номер записи на 1. Когда номер текущей записи достигает 128, про исходит сброс этого значения в 0 и в FCB увеличивается номер текущего блока на 1. Операция возвращает в регистре al следующие коды:

Таблица 4.4

al Результат проверки 00 Успешная запись 01 Диск полный 02 В области DTA нет места для одной записи

Когда запись файла завершена, можно, хотя и не всегда обязательно, записать маркер конца файла (1Ah). Для закрытия файла используется функция 10h:

mov ah,10h ; закрыть lea dx,FCBname ; файл int 21h ; вызов DOS Эта операция записывает на диск данные, которые ещё остались

в дисковом буфере DOS, и изменяет в соответствующем элементе оглавления дату и размер файла. В регистре al возвращаются следующие значения:

Таблица 4.5 al Результат проверки

00 Успешная запись FF Описание файла оказалось в неправильном элементе

оглавления (возможно, в результате смены дискеты)

Page 30: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

30

4.4. Последовательное чтение дискового файла

В базовой версии DOS программа, читающая дисковый файл, содержит блок управления файлом, который определяет файл точно так, как при его создании. В начале программа для открытия файла использует функцию 0f:

mov ah,0fh ; открытие lea dx,FCBname ; файла int 21h ; вызов DOS Операция открытия начинается с поиска в оглавлении элемента

с именем и типом файла, определенными в FCB. Если такой элемент не будет найден в оглавлении, то в регистре al устанавливается FFh. Если элемент найден, то в регистре al устанавливается 00 и в FCB заносится действительный размер файла, а также устанавливаются номер текущего блока в 0, длина записи в 80h. После открытия можно заменить длину записи на другое значение.

DTA должно содержать определение считываемой записи в соответствии с форматом, который использовался при создании файла. Для установки адреса DTA используется функция 1ah (не путать с маркером конца файла EOF 1ah) аналогично созданию дискового файла:

mov ah,1ah ; установка lea dx,DTAname ; адреса DTA int 21h ; вызов DOS

Для последовательного чтения записей с диска используется функция 14h:

mov ah,14h ; последовательное lea dx,FCBname ; чтение записей int 21h ; вызов DOS

Чтение записи с диска по адресу DTA осуществляется на основе информации в блоке FCB. Операция чтения устанавливает в регистре al следующие коды возврата:

Таблица 4.6 al Результат проверки

00 Успешное чтение 01 Конец файла, данные не прочитаны 02 В DTA нет места для чтения одной записи 03 Конец файла, прочитана частичная запись, заполненная нулями

Первая операция чтения заносит содержимое всего сектора в буфер DOS. Затем операция определяет из блока FCB размер записи и

Page 31: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

31

пересылает первую запись из буфера в DTA. Последующие операции чтения пересылают остальные записи (если имеются), пока буфер не будет исчерпан. После этого операция чтения определяет адрес следующего сектора и заносит его содержимое в буфер.

После успешной операции чтения в блоке FCB автоматически увеличивается номер текущей записи на 1. Завершение последовательного чтения определяется программой по маркеру конца файла (EOF), для чего в программе имеется соответствующая проверка. Так как оглавление при чтении файла не изменяется, то обычно нет необходимости закрывать файл после завершения чтения. Исключение составляют программы, которые открывают и читают несколько файлов одновременно. Такие программы должны закрывать файлы, так как DOS ограничивает число одновременно открытых файлов.

4.5. Прямой доступ

Если программа использует только последовательную

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

В некоторых случаях применяется доступ к конкретным записям файла для получения информации, например, о нескольких служащих или о части ассортимента товаров. Для доступа, скажем, к 300-й записи файла при произвольном доступе не требуется чтение всех 299 предшествующих записей, а при последовательной обработке требуется.

Примечание. Файл создается последовательно, а доступ к записям может быть последовательным или прямым (произвольным). Требования прямой обработки, использующей вызов DOS, заключаются в установке требуемого номера записи в соответствующее поле FCB и выдаче команды прямого чтения или записи.

Произвольный доступ использует относительный номер записи (байты 33 36) в блоке FCB. Поле имеет размер двойного слова и использует обратную последовательность байтов в словах.

Для локализации требуемой записи система автоматически преобразует относительный номер записи в номер текущего блока (байты 12 13) и номер текущей записи (байт 32).

Page 32: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

32

4.6. Прямое чтение

Операции открытия и установки DTA одинаковы как для прямой, так и для последовательной обработки. Предположим, что программа должна выполнить прямой доступ к пятой записи файла. Установим значение 05 в поле FCB для относительного номера записи и выполним команды для прямого чтения. В результате успешной операции содержимое пятой записи будет помещено в DTA.

Для прямого чтения записи необходимо поместить требуемое значение относительного номера записи в FCB и вызвать функцию 21h:

mov ah,21h ; запрос на lea dx,FCBname ; прямое чтение int 21h ; вызов DOS

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

Таблица 4.7

al Результат проверки 00 Успешное завершение 01 Данные не доступны 02 Чтение прекращено из-за нехватки места в DTA 03 Прочитана частичная запись, заполненная нулями

Как видно, среди перечисленных кодов возврата отсутствует

состояние “конец файла”. При корректном чтении записи предполагается единственный код возврата 00. Остальные коды возврата могут являться результатом установки неправильного относительного номера записи или некорректной установки адреса DTA или FCB. Так как такие ошибки легко допустить, то полезно выполнять проверку регистра al на ненулевое значение.

4.7. Прямая запись

Программа может, используя прямой доступ, считать

необходимую запись, внести изменения и вернуть запись на диск на то же место. Операция прямой записи использует относительный номер записи в блоке FCB и функцию 22h следующим образом:

mov ah,22h ; запрос на lea dx,FCBname ; прямую запись

Page 33: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

33

int 21h ; вызов DOS Операция устанавливает в регистре al следующие коды возврата:

Таблица 4.8

al Результат проверки 00 Успешная операция 01 На диске нет места 02 Операция прекращена, т.к. недостаточно места в DTA

При создании нового файла прямым доступом может быть получен ненулевой код возврата. Но при прямом чтении и переписывании измененных записей на том же месте диска код возврата должен быть только 00.

Как уже отмечалось (см. подраздел 4.5), используемый при прямом доступе относительный номер записи в блоке FCB имеет размер двойного слова (четыре байта); каждое слово в нем записывается в обратной последовательности байтов. Для небольших файлов, возможно, потребуется установка лишь самого левого байта или слова, но для больших файлов установка номера записи в трех или четырех байтах требует некоторой тщательности.

4.8. Прямой блочный доступ

Если в программе имеется достаточно места, то одна прямая

блочная операция может записать весь файл из DTA на диск, а также прочитать весь файл с диска в DTA. Данная особенность весьма полезна для записи на диск таблиц, которые другие программы могут считывать в память для обработки.

Начать можно с любого правильного относительного номера записи. Число записей также может быть любым, хотя блок должен находиться в пределах файла. Перед началом необходимо открыть файл и инициализировать DTA.

Для операции прямой блочной записи необходимо установить в регистре cx требуемое число записей, установить в FCB стартовый относительный номер записи и выдать функцию 28h:

mov ah,28h ; операция прямой блочной записи mov cx,records ; установка числа записей lea dx,FCBname int 21h ; вызов DOS

Операция преобразует относительный номер записи (байты 33 36) в номер текущего блока (байты 12 13) и текущий номер записи (байт 32). Полученные значения используются для определения

Page 34: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

34

начального адреса на диске. В результате операции в регистре al устанавливаются следующие коды возврата:

Таблица 4.9 al Значение кода возврата

00 Успешное завершение для всех записей 01 На диске недостаточно места

Кроме того, операция устанавливает в FCB в поле относительного номера записи и в полях текущих номеров блока и записи значения, соответствующие следующему номеру записи. Например, если были записаны записи с 00 до 24, то следующий номер записи будет 25 (19h).

Для операции прямого блочного чтения необходимо установить в регистре cx требуемое число записей и использовать функцию 27h:

mov ah,27h ; операция прямого блочного чтения mov cx,records ; установка числа записей lea dx,FCBname int 21h ; вызов DOS

Операция чтения возвращает в регистре al следующие значения: Таблица 4.10

al Значение кода возврата 00 Успешное чтение всех записей 01 Прочитана последняя запись файла 02 Прочитано предельное для DTA число записей 03 Прочитана последняя запись файла не полностью

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

Если необходимо загрузить в память весь файл, но число записей неизвестно, то следует после операции открытия разделить размер файла на длину записи. Например, для размера файла 320h (800) и длины записи 20h (32) число записей будет 19h (25).

4.9. Абсолютные операции

дискового ввода-вывода

Для непосредственного доступа к диску можно использовать операции абсолютного чтения и абсолютной записи с помощью функций DOS int 25h и 26h. В этом случае не используются

Page 35: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

35

оглавление диска и преимущества блокирования и разблокирования записей, обеспечиваемые функцией DOS int 21h.

Абсолютные операции предполагают, что все записи имеют размер сектора, поэтому прямой доступ осуществляется к полному сектору или блоку секторов. Адресация диска выполняется по "логическому номеру записи" (абсолютный сектор). Для определения логического номера записи на двухсторонних дискетах с девятью секторами счет секторов ведется с дорожки 0 сектора 1 следующим образом:

Таблица 4.11

Дорожка Сектор Логический номер записи

Дорожка Сектор Логический номер записи

0 1 0 1 4 12 0 2 1 1 . . . 0 3 2 1 9 17 0 . . . 2 1 18 0 9 8 2 2 19 1 1 9 2 . . . 1 2 10 2 9 26 1 3 11 . . .

Фрагмент программы для абсолютных операций ввода-вывода:

mov al,drive# ; 0 для A, 1 для B и т.д. mov bx,addr ; адрес области ввода-вывода mov cx,sectors ; число секторов mov dx,record# ; начальный логический номер записи int 25h или 26h ; абсолютное чтение или запись

Операции абсолютного чтения или запись разрушают содержимое всех регистров, кроме сегментных, и устанавливают флаг cf для индикации успешной (0) или безуспешной (1) операции. В случае безуспешной операции содержимое регистра al описывает характер ошибки:

Таблица 4.12

al Причина 1000 0000 Устройство не отвечает 0100 0000 Ошибка установки головок 0010 0000 Ошибка контролера 0001 0000 Ошибка дискеты? 0000 1000 Переполнение DMA при чтении 0000 0100 Сектор не найден 0000 0011 Попытка записи на защищенной дискете

Page 36: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

36

0000 0010 Не найден адресный маркер Команда int записывает содержимое флагового регистра в стек.

После завершения команды int следует восстановить флаги, но проверив перед этим флаг cf.

4.10. Другие операции

Кроме основных дисковых функций DOS имеется несколько

дополнительных полезных дисковых операций.

4.11. Сброс диска

Обычно нормальное закрытие файла приводит к занесению всех оставшихся в буфере записей на диск и корректировке оглавления. В особых случаях (например, при аварийном завершении) может потребоваться сброс диска. Функция DOS 0dh освобождает все файловые буферы и не корректирует оглавление диска. Если необходимо, то вначале данная функция закрывает все файлы.

mov ah,0dh ; запрос на сброс диска int 21h ; вызов DOS

4.12. Установка текущего дисковода

Основное назначение функции DOS 0eh установка номера

текущего (по умолчанию) дисковода. Номер дисковода помещается в регистр dl, причем 0 соответствует дисководу A, 1 B и т.д.

mov ah,0eh ; запрос на установку mov dl,02 ; дисковода C int 21h ; вызов DOS

Операция возвращает в регистр al число дисководов (независимо от типа). Так как для DOS необходимо, по крайней мере, два логических дисковода (A и B), то DOS возвращает значение 02 и для систем с одним дисководом. Для определения действительного числа дисководов используется команда int 11h.

4.13. Поиск элементов оглавления

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

переименовании, может потребоваться поиск в оглавлении. Для доступа к первому или единственному элементу оглавления

Page 37: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

37

необходимо загрузить в регистр dx адрес неоткрытого блока FCB и выполнить функцию 11h. При использовании расширенного блока FCB можно также получить код атрибута:

mov ah,11h ; запрос на первый элемент lea dx,FCBname ; неоткрытый FCB int 21h ; вызов DOS В регистре al операция возвращает следующие значения:

Таблица 4.13

al Значение кода возврата 00 Элемент найден FF Элемент не найден

Операция устанавливает в DTA номер дисковода (1=A, 2=B и т.д.), имя файла и тип файла. Если найдено несколько элементов при выборке по шаблону (например, *.asm), то для локализации элементов подмножества директории используется функция 12h:

mov ah,12h ; запрос следующего элемента lea dx,FCBname ; неоткрытый FCB int 21h ; вызов DOS Коды возврата в регистре al аналогичны кодам функции 11h.

4.14. Удаление файла

Для удаления файла в программе используется функция 13h.

Операция удаления устанавливает специальный байт в первой позиции имени файла в оглавлении.

mov ah,13h ; запрос на удаление файла lea dx,FCBname ; неоткрытый FCB int 21h ; вызов DOS

Если операция находит и удаляет элемент, то в регистре al устанавливается код возврата 00, иначе код равен шестнадцатеричному FF.

4.15. Переименование файла

Для переименования файла в программе старое имя файла

записывается в обычном месте блока FCB, а новое начиная со смещения 16.

mov ah,17h ; запрос на переименование lea dx,FCBname ; адрес FCB int 21h ; вызов DOS

Page 38: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

38

Символы ? и * в новом имени приводят к сохранению в соответствующих позициях символов из старого имени. Успешная операция устанавливает в регистре al код возврата 00, а безуспешная (файл по старому имени не найден или по новому имени уже существует) код FF.

4.16. Получение текущего номера дисковода

Функция 19h позволяет определить текущий номер дисковода: mov ah,19h ; получить текущий дисковод int 21h ; вызов DOS

Операция возвращает шестнадцатеричный номер дисковода в регистре al (0=A, 1=B и т.д.). Полученное значение можно поместить непосредственно в FCB для доступа к файлу с текущего дисковода.

Кроме перечисленных существуют функции для получения информации из таблицы FAT (1B и 10), установки поля прямой записи (24), установки вектора прерываний (25), создания нового программного сегмента (26) и анализа имени файла (29). Эти функции описаны в техническом руководстве по DOS.

Контрольные вопросы 1. Общие сведенья о работе с файлами. 2. Назначение блока управления файлом (FCB). 3. Как осуществляется создание, запись и закрытие файла. 4. Как осуществляется открытие, запись и закрытие файла. 5. Как осуществляется открытие, чтение и закрытие файла. 6. Какие значения принимают по умолчанию номер текущего

блока и размер записей при открытии файла? 7. Назначение области DTA? Как инициализируется адрес DTA? 8. Как инициализируется адрес DTA при обработке нескольких

файлов (например, чтение из двух файлов, побайтное суммирование и запись полученных сумм в третий файл)?

9. Последовательное чтение дискового файла. Замена длины записи.

10. Прямой доступ к дисковому файлу. Относительный номер записи.

11. Прямое чтение записей дискового файла. Использование относительного номера записи.

12. Прямая запись в дисковый файл. Использование относительного номера записи.

Page 39: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

39

13. Прямой блочный доступ: прямая блочная запись, задание количества записей, стартовый относительный номер записи. Как используются номер текущего блока и текущий номер записи?

14. Прямой блочный доступ: как загрузить в память весь файл, когда число записей неизвестно?

15. Абсолютные операции дискового ввода-вывода. Длина записи при выполнении операций абсолютного чтения и абсолютной записи с помощью функций DOS.

16. Сброс диска. В каких случаях осуществляется, и что при этом выполняется. Получение текущего номера дисковода.

17. Установка текущего дисковода. Удаление файла. 18. Напишите функции базовой версии DOS для следующих

операций: а) создание файла; б) установка DTA; в) последовательная запись; г) открытие файла; д) последовательное чтение.

19. Программа использует размер записи, устанавливаемый при открытии файла по умолчанию.

а) сколько записей содержит один сектор? б) сколько записей содержит дискета с тремя дорожками по

девять секторов на каждой? в) если на дискете (б) находится один файл, то при

последовательном чтении сколько произойдет физических обращений к диску?

20. Определите текущий блок и запись для следующих номеров записей при прямом доступе: а) 45, б) 73, в) 150, г) 260.

21. В каком виде номер записи 2652 (десятичное) устанавливается в поле относительной записи блока FCB?

22. Укажите шестнадцатеричные номера функций для следующих операций:

а) прямая запись, б) прямое чтение, в) прямая блочная запись, г) прямое блочное чтение.

23. Напишите команды для определения числа записей файла, предполагая, что операция открытия уже выполнена.

Имена полей с размером файла fcbflsz и размером записи fcbfcsz.

Page 40: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

40

24. Составьте блок-схему программы, которая вводит данные с клавиатуры и записывает эти данные на диск в двоичном формате.

25. Составьте блок-схему программы, которая использует операцию прямого чтения с диска данных в двоичном формате и вывод их на экран.

Page 41: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

41

5. АРИФМЕТИЧЕСКИЕ ОПЕРАЦИИ НАД ЦЕЛЫМИ

ДВОИЧНЫМИ ЧИСЛАМИ СО ЗНАКОМ

5.1. Общие сведения об арифметических операциях над числами со знаком

Рассмотрим особенности каждого из четырех основных

арифметических действий (сложение, вычитание, умножение и деление) для двоичных чисел со знаком.

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

5.2. Сложение двоичных чисел со знаком

Микропроцессор не подозревает о различии между числами со

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

флаг переноса cf, установка которого в 1 говорит о том, что произошел выход за пределы разрядности операндов;

команда adc, которая учитывает возможность такого выхода (перенос из младшего разряда).

Другое средство – это регистрация состояния старшего (знакового) разряда операнда, которое осуществляется с помощью флага переполнения of (бит 11).

Итак, числа в компьютере представляются следующим образом: положительные - в прямом коде, отрицательные - в дополнительном коде. Рассмотрим различные варианты сложения чисел микропроцессором 8086 для случая, когда оба операнда являются словами, т.е.занимают по 16 битов каждый. Примеры призваны показать поведение двух старших битов операндов и правильность результата операции сложения. Пример 1. 30566 = 01110111 01100110 +

Page 42: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

42

00687 = 00000010 10101111 = 31253 = 01111010 00010101

Следим за переносами из 14-го и 15-го разрядов и правильностью результата: переносов нет, результат правильный. Пример 2. 30566 = 01110111 01100110 + 30566 = 01110111 01100110 = 61132 = 11101110 11001100

Произошел перенос из 14-го разряда; из 15-го разряда переноса нет. Результат неправильный, так как имеется переполнение - значение числа получилось больше, чем то, которое может иметь 16-битное число со знаком (+32 767). Пример 3. -30566 = 10001000 10011010 + -04875 = 11101100 11110101 = -35441 = 01110101 10001111

Из 14-го разряда нет переноса, а из 15-го разряда произошел перенос. Результат неправильный, так как вместо отрицательного числа получилось положительное (в старшем бите находится 0). Пример 4. -4875 = 11101100 11110101 + -4875 = 11101100 11110101 = -9750 = 11011001 11101010

Есть переносы из 14-го и 15-го разрядов. Результат правильный. Таким образом, переполнения не происходит (то есть флагу of

присваивается 0), если есть перенос из обоих разрядов или из 14-го и из 15-го разрядов перенос отсутствует.

И наоборот, переполнение (установка of в 1) происходит при переносе:

из 14-го разряда (для положительных чисел со знаком); из 15-го разряда (для отрицательных чисел).

Дополнительно к флагу of при переносе из старшего разряда устанавливается в 1 и флаг переноса cf. Так как процессор не знает о

Page 43: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

43

существовании чисел со знаком и без знака, то вся ответственность за правильность действий с получившимися числами ложится на программиста. Проанализировать флаги cf и of можно командами условного перехода jc\jnc и jo\jno соответственно.

Сложение двух операндов, занимающих по 8 битов (т.е.сложение байтов), аналогично, но переполнение возникает при переносе из 6-го разряда для положительных и из 7-го разряда для отрицательных чисел. Для процессора 80386 и выше кроме этих двух случаев возможно сложение двойных слов. Переполнение при таком сложении возникает при переносе из 30-го для положительных и из 31-го – для отрицательных чисел.

Что же касается команд сложения чисел со знаком, то они те же, что и для чисел без знака.

5.3. Вычитание двоичных чисел со знаком

Процессору незачем иметь два устройства - сложения и

вычитания. Достаточно наличия только одного - устройства сложения. Но для вычитания способом сложения чисел со знаком необходимо представлять в дополнительном коде оба операнда - и уменьшаемое, и вычитаемое. Результат тоже нужно рассматривать как значение в дополнительном коде. Здесь возникают сложности. Прежде всего, они связаны с тем, что старший бит операнда рассматривается как знаковый. Рассмотрим пример вычитания отрицательного числа из положительного: 45 = 0010 1101 - -127 = 1000 0001 = -44 = 1010 1100

Судя по знаковому разряду, результат получился отрицательный, что, в свою очередь, говорит о том, что число нужно рассматривать как дополнение, равное –44. Правильный результат должен быть равен 172. Здесь мы, как и в случае знакового сложения, встретились с переполнением, когда значащий разряд числа изменил знаковый разряд операнда. Отследить такую ситуацию можно по содержимому флага переполнения of. Его установка в 1 говорит о том, что результат вышел за диапазон представления знаковых чисел (то есть изменился старший бит) для операнда данного размера, и

Page 44: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

44

программист должен предусмотреть действия по корректировке результата.

Пример вычитания положительного числа из отрицательного числа как сложение двух отрицательных чисел: -45 - 45 = -45 + (-45)= -90. -45 = 1101 0011 + -45 = 1101 0011 = -90 = 1010 0110

Здесь все нормально, флаг переполнения of сброшен в 0, а 1 в знаковом разряде говорит о том, что значение результата – число в дополнительном коде.

5.4. Умножение чисел со знаком

5.4.1. Эта команда имеет три формы, различающиеся числом

операндов: imul источник imul приемник, источник imul приемник, источник1, источник2

5.4.2. Если используется форма imul источник,

то источник (регистр или переменная) умножается на al или ax (в зависимости от размера операнда) и результат располагается в ax или dx:ax соответственно.

5.4.3. Если используется форма imul приемник, источник,

то источник (число, регистр или переменная) умножается на приемник (регистр) и результат заносится в приемник.

5.4.4. Если используется форма imul приемник, источник1, источник2,

то источник 1 (регистр или переменная) умножается на источник 2 (число) и результат заносится в приемник (регистр).

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

5.4.6. Флаги of и cf будут равны:

Page 45: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

45

единице, если это произошло; нулю, если результат умножения поместился целиком в

приемник (во втором и третьем случаях) или в младшую половину приемника (в первом случае).

Значения флагов sf, zf, af и pf после команды imul не определены.

5.4.7. Эта команда выполняется так же, как и команда mul. Отличительной особенностью команды imul является только формирование знака.

Если результат мал и умещается в одном регистре (то есть если cf = of = 0), то содержимое другого регистра (старшей части) является расширением знака - все его биты равны старшему биту (знаковому разряду) младшей части результата.

В противном случае (если cf = of = 1) знаком результата является знаковый бит старшей части результата, а знаковый бит младшей части является значащим битом двоичного кода результата.

5.5. Деление чисел со знаком

Для деления чисел со знаком предназначена команда

idiv делитель Выполняет целочисленное деление со знаком ax или dx:ax (в

зависимости от размера источника) на источник (регистр или переменная) и помещает результат в al или ax, а остаток — в ah или dx соответственно. Результат всегда округляется в сторону нуля, знак остатка всегда совпадает со знаком делимого, абсолютное значение остатка всегда меньше абсолютного значения делителя. Значения флагов cf, of, sf, zf, af и pf после этой команды не определены, а переполнение или деление на ноль вызывает исключение #DE (ошибка при делении) в защищенном режиме и прерывание 0 — в реальном.

Для этой команды справедливы все рассмотренные положения, касающиеся команд и чисел со знаком. Отметим лишь особенности возникновения исключения 0, “деление на ноль” в случае чисел со знаком. Оно возникает при выполнении команды idiv по одной из следующих причин:

делитель равен нулю; частное не входит в отведенную для него разрядную сетку.

Page 46: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

46

Последнее, в свою очередь, может произойти: при делении делимого величиной в слово со знаком на делитель

величиной в байт со знаком, причем значение делимого более чем в 128 раз больше значения делителя (т.к. частное не должно находиться вне диапазона от –128 до +127);

при делении делимого величиной в двойное слово со знаком на делитель величиной в слово со знаком, причем значение делимого более чем в 32 768 раз больше значения делителя (т.к. частное не должно находиться вне диапазона от –32 768 до +32 767).

Вспомогательные команды для целочисленных операций – рассматриваются ниже.

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

1. Общие сведенья об арифметических операциях над числами со знаком.

2. Сложение двоичных чисел со знаком. В каких случаях происходит переполнение и получается неправильный результат.

3. Вычитание двоичных чисел со знаком. Применение дополнительного кода. Вычитание положительного числа из отрицательного числа.

4. Умножение чисел со знаком. 5. Деление чисел со знаком. Причины возникновения ситуации

«деление на ноль».

Page 47: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

47

6. ДОПОЛНИТЕЛЬНЫЕ СВЕДЕНИЯ

6.1. Включаемые файлы

Часто оказывается желательным включить один и тот же блок исходного кода ассемблера в несколько исходных модулей. В этом случае чрезвычайно удобной оказывается директива include.

Когда ассемблер встречает директиву include (включить), текст включаемого файла включается в ассемблирование текущего исходного модуля ассемблера. Например, если файл mainprog.asm содержит:

. . . .code mov ax,1 include incprog.asm push ax

. . . а файл incprog.asm содержит:

mov bx,5 add ax,bx

то результат ассемблирования файла mainprog.asm будет в точности эквивалентен ассемблированию кода:

. . . .code mov ax,1 mov bx,5 add ax,bx push ax

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

глубину, т.е. включаемые файлы также могут содержать директивы include (включать другие файлы). В файле листинга ассемблер слева от каждой включенной строки помещает номер, указывающий глубину вложенности файлов модулей.

6.2. Команды преобразования типов

Что делать, если размеры операндов, участвующих в

арифметических операциях, разные? Например, один операнд является словом, а другой занимает двойное слово. Выше сказано, что в операции сложения должны участвовать операнды одного формата.

Page 48: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

48

Если числа без знака, то на базе исходного операнда (слова) надо сформировать новый (формата двойного слова), старшие разряды которого заполнить нулями.

Для чисел со знаком используются команды преобразования типа. Команды МП 8086 расширяют байты в слова, слова - в двойные слова. Команды преобразования типа особенно полезны при преобразовании целых со знаком, так как они автоматически заполняют старшие биты вновь формируемого операнда значениями знакового бита старого объекта. Эта операция приводит к целым значениям того же знака и той же величины, что и исходная, но уже в более длинном формате:

cbw (convert byte to word) - команда преобразования байта (в регистре al) в слово (в регистре ax) путем распространения значения старшего бита al на все биты регистра ah;

cwd (convert word to double) - команда преобразования слова (в регистре ax) в двойное слово (в регистрах dx:ax) путем распространения значения старшего бита ax на все биты регистра dx.

Например, сложение байта и слова, если это числа со знаком, может быть реализовано следующим образом:

.data b1 db ? w1 dw ? .code main proc far . . . mov al,b1 ;al:=b1 cbw ;ax:=b1 add ax,w1 ;ax:=b1+w1 ; проверка флага cf. Если cf=1, то ошибка . . . Другой пример, сложение двойного слова и слова, если это числа

со знаком: .data d1 dd ? w1 dw ? .code main proc far . . . mov al,w1 ;ax:=w1 cwd ;(dx:ax) :=w1 add ax,word ptr d1 adc dx,word ptr d1+2 ; (dx:ax):=d1+w1

Page 49: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

49

; проверка флага cf. Если cf=1, то ошибка . . .

6.3. Отрицание с дополнением до двух

Формат команды:

neg <операнд> Команда выполняет инвертирование значения операнда.

Физически команда выполняет вычитание значения операнда из нуля: <операнд>= 0 – <операнд>

Команду neg операнд можно применять: для смены знака; для выполнения вычитания из константы.

Т.к. команды sub и sbb не позволяют вычесть что-либо из константы, то данную операцию можно выполнить с помощью двух команд:

neg ax ;смена знака (ax) . . . add ax,340 ;фактически вычитание: ax:=340-ax

6.4. Арифметические и логические операции в микропроцессорах МП8086 и МП80386

6.4.1. Арифметические операции в микропроцессорах МП8086 и

МП80386 показаны для беззнаковых чисел на примерах вычисления по формулам (приложение 5):

d1+w1+b1+d2+w2+b2 d1-w1-b1-d2-w2-b2 b1*b2*w1*d1

6.4.2. Логические поразрядные операции в микропроцессорах МП8086 и МП80386 показаны на примерах вычисления по формулам (приложение 5):

d1 or w1 or b1 or d2 or w2 or b2 d1 and w1 and b1 and d2 and w2 and b2

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

1. Включаемые файлы. Директива include. 2. Команды преобразования типов для знаковых данных (cbw, cwd,

cdq). 3. Отрицание с дополнением до двух (neg).

Page 50: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

50

7. ТИПИЧНЫЕ ОШИБКИ ПРИ ВЫПОЛНЕНИИ РАБОТЫ

7.1. Перечень часто встречающихся ошибок

7.1.1. Перечень ошибок тот же, что и в первых двух работах (см.

уч.пос., ч.1 и 2): - открытая процедура или открытый сегмент; - программист забывает о возврате в DOS; - вызов процедуры, которая портит содержимое нужных регистров; - неопределенные символические имена; - повторное определение символического имени; - неправильный порядок операндов; - неправильное использование операндов; - потеря содержимого регистра при умножении; - не подготовлены регистры при делении; - неправильное использование регистра после деления; - потеря содержимого регистра при делении; - неправильное использование регистров в командах cbw и cwd; - применение команд преобразования cbw и cwd к беззнаковым

данным; - изменение отдельными инструкциями флага переноса; - программист долго не использует состояние флагов; - ошибки при использовании регистров; - выход из диапазона адресов; - программист забывает об инструкции ret; - генерация неверного типа возврата; - ошибки при использовании условных переходов; - перепутаны операнды в памяти и непосредственные операнды; - границы сегментов. 7.1.2 Типичные ошибки, которые допускаются при

программировании на ассемблере, и рекомендации, как можно их избежать, приведены ниже. Источники данной информации: [1; 4; 5; 6].

7.2. Открытая процедура или открытый сегмент

Если генерируется предупреждающее сообщение, что сегмент

открыт, наиболее вероятной причиной ошибки является: - неверная запись имени сегмента или процедуры

Page 51: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

51

- или отсутствие ends или endp. 7.3 Программист забывает о возврате в DOS

Имеется несколько вариантов возврата в DOS. Правильно

завершать работу будет, например, программа, использующая команду ret или функцию 4Ch (см. учеб.пособ., ч.1). Об ошибках при возврате из процедуры в вызвавшую программу см. подраздел 7.19.

7.4. Вызов процедуры, которая портит содержимое

нужных регистров

При разработке программы на ассемблере нередко подразумевают, что при обращении к другим процедурам регистры остаются неизмененными. На самом деле это не так. Каждая процедура может сохранить или уничтожить содержимое любого из регистров (см. учеб.пособ., ч.1, 2 и 6).

7.5. Неопределенные символические имена

Ассемблер генерирует сообщение о неопределенном

символическом имени, если имя не определено в поле метки какой-либо строки ассемблерной программы. Неправильная запись имени является наиболее вероятной причиной такой ошибки (см. учеб.пособ., ч.1).

7.6. Повторное определение символического имени

Ассемблер формирует сообщение об ошибке повторного

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

7.7. Неправильный порядок операндов

Многие программисты ошибаются и изменяют порядок

операндов в инструкциях процессора 8086 на обратный (см. учеб.пособ., ч.1).

7.8. Неправильное использование операндов

Page 52: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

52

7.8.1. В языке ассемблера первый операнд всегда используется в качестве приемника (кроме синтаксиса АТ&T для UNIX и Linux, см. учеб.пособ., ч.12). Операнд может быть записан в регистре общего назначения, регистре сегмента или ячейке памяти. Генерируется сообщение об ошибке при использовании непосредственных данных в качестве операнда-приемника:

cmp З,al; нельзя заменить значение 3 содержимым регистра al. Правильная запись:

cmp al,3 ; (содержимое регистра al станет равным 3). 7.8.2. Нельзя задавать 8- и 16-разрядный (а для процессора 80386

также 8- и 32-разрядный или 16- и 32-разрядный) операнды одной команды (это правило не распространяется на команды movsx и movzx, см. учеб.пособ., ч.7). Ошибочны следующие команды (несоответствие типов):

mov al, w1 ; al – однобайтовый регистр; ; w1 – однословная переменная памяти ( два байта); ; mov ax, b1 ; ax – однословный регистр; ; b1 – однобайтовая переменная. 7.8.3. Операции со стеком не должны содержать переменные

памяти (разрешаются – только однословные регистры). Если 8-разрядную или 16-разрядную переменную указывают для работы со стеком (push/pop), то выдается сообщение об ошибке. Примеры:

а) push w1 ; правильно будет: mov ax,w1 и затем push ax б) pop w1 ; правильно будет: pop ax и затем mov w1,ax в) push b1 ; правильно: mov al,b1 и затем xor ah,ah и push

ax г) pop b1 ; правильно будет: pop ax и затем mov al,b1/

Примечание. Использование стека для временного хранения однобайтовых переменных (см. примеры в) и г)) не эффективно.

7.9. Потеря содержимого регистра при умножении

Всегда нужно помнить о том, что при использовании инструкций mul и imul изменяется (не сохраняется) содержимое не только регистров al, ax или eax, но также и ah, dx или edx (см. учеб.пособ., ч. 1).

7.10. Не подготовлены регистры при делении

Page 53: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

53

Распространенной ошибкой для случаев, когда делимое по размеру совпадает с делителем и размещено в al, ax или eax, является то, что программист не обнуляет регистры ah, dx, edx (см. учеб.пособ., ч.1).

7.11. Неправильное использование регистра

после деления

Не учитывается, что регистры ah и dx содержат остаток, и используют их в качестве старших разрядов частного (см. учеб.пособ., ч. 1).

Пример ошибочного использования регистра edx после деления учетверенного слова на двойное слово приведен в учеб.пособ., ч.7.

7.12. Потеря содержимого регистра при делении

Потеря содержимого регистра при делении заключается в том,

что теряется значение, помещенное в регистр до операции деления (значение регистров al, ah , ax, dx, eax, edx,, помещенное в регистр до операции деления, теряется, т.к. в регистр будет помещено частное (в регистры al, ax, eax) или остаток от деления (в регистры ah , dx, edx), см. учеб.пособ., ч. 1 и 7.

7.13. Неправильное использование регистров

в командах cbw и cwd

Неправильное использование регистров при преобразованиях заключается либо в ошибочном размещении исходного значения, либо в не использовании в качестве результата регистров ax, (dx:ax). Для cbw и cwd исходные значения должны быть размещены в регистрах al и ax соответственно. Программисты же иногда ошибочно помещают исходное значение в какой-нибудь другой регистр (например, в bl или bx).

7.14. Применение команд cbw и cwd

к беззнаковым данным

При применении команд cbw и cwd к беззнаковым данным может возникнуть ошибка. Когда знаковый бит равен единице, старший байт или слово соответственно заполняется единицами, а не

Page 54: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

54

нулями, как требуется в этом случае. Это надо учитывать при выполнении логических операций и операций сдвига и вместо инструкций cbw и cwd применять зануление старшего байта или слова командой xor (см. учеб.пособ., ч.1).

7.15. Изменение отдельными инструкциями флага переноса

Некоторые инструкции не влияют на те флаги, изменения

которых вы ожидаете. Например, инструкция inc в случае слишком большого для операнда-приемника результата на флаг cf не влияет.

То же самое имеет место для инструкций dec, loop, loopz и loopnz (не влияют на состояние флагов, см. учеб.пособ., ч.6 и 7).

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

7.16. Программист долго не использует

состояние флагов

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

7.17. Ошибки при использовании регистров

При использовании регистров для записи операндов в

ассемблерной программе необходимо соблюдать следующие правила: 7.17.1. Нельзя задавать 8- и 16-разрядный (а для процессора

80386 также 8- и 32-разрядный или 16- и 32-разрядный) регистры для записи двух операндов одной команды (это правило не распространяется на команды movsx и movzx, см. учеб.пособ., ч.7).

7.17.2. Операции со стеком должны осуществляться только в шестнадцатибитовых кодах. Если 8-разрядный регистр указывают для работы со стеком (push/pop), то выдается сообщение об ошибке.

7.17.3. Сегментные регистры не могут прямо использоваться в арифметических вычислениях, логических операциях или для непосредственной передачи данных. Кроме того, сегментные регистры

Page 55: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

55

могут быть использованы либо как источники операндов, либо как приемники операндов, но никак не одновременно (см. учеб.пособ., ч. 1).

7.18. Выход из диапазона адресов

Все команды условного перехода используют режим относительной адресации с 8-битовым смещением. Если относительный адрес символа, используемого в качестве операнда-адреса перехода, выходит за диапазон + 127 байтов - 128 байтов от конца команды условного перехода, выдается сообщение об ошибке (см. учеб.пособ., ч. 1)

7.19. Программист забывает об инструкции ret

Правильный вызов подпрограммы состоит:

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

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

7.20. Генерация неверного типа возврата

Директива proc, во-первых, определяет имя, по которому будет

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

Тип процедуры используется ассемблером для определения того, какой тип вызовов нужно генерировать при вызове процедуры из того же исходного файла и для определения типа инструкции ret, которая выполняется, когда процедура возвращает управление. Например: ; Подпрограмма ближнего типа для сдвига dx:ax вправо на 2 байта. LongShiftRight2 proc near

shr dx,1 rcr ax,1 ; сдвиг dx:ax вправо на 1 бит shr dx,1 rcr ax,1 ; сдвиг dx:ax вправо еще на 1 бит

Page 56: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

56

ret LongShiftRight2 endp

Ассемблер обеспечивает, что инструкция ret будет ближнего типа, так как LongShiftRight2 это процедура ближнего типа (near). Однако, если директиву proc изменить следующим образом: LongShiftRight2 proc far, то будет генерироваться инструкция ret дальнего типа (far).

Часто группируют в одной и той же процедуре несколько процедур. Поскольку в этих процедурах отсутствует соответствующая директива proc, их инструкции ret будут иметь тип той процедуры, в которую они заключены, а для конкретных подпрограмм этот тип не всегда может оказаться корректным. Например: ; Подпрограмма дальнего типа для сдвига dx:ax на 2 бита LongShiftRight2 proc far

call LongShiftRight ; сдвиг dx:ax вправо на 1 бит call LongShiftRight ; сдвиг dx:ax вправо еще на 1 бит ret

LongShiftRight: shr dx,1 rcr ax,1 ; сдвиг dx:ax вправо на 1 бит ret

LongShiftRight2 endp работает неправильно. Процедура LongShiftRight2 обращается с вызовом ближнего типа к LongShiftRight (так как они находятся в одном сегменте кода). Однако, так как LongShiftRight встроена в процедуру LongShiftRight2, то возврат в конце подпрограммы LongShiftRight становится возвратом дальнего типа, а когда вызову ближнего типа соответствует возврат дальнего типа, это с большой вероятностью может привести к сбою (аварийному завершению программы).

Хорошим решением здесь будет наличие в каждой подпрограмме директивы proc. Вложенные директивы proc прекрасно работают. ; Подпрограмма дальнего типа для сдвига dx:ax на 2 бита. ; LongShiftRight2 proc far

call LongShiftRight ; сдвиг dx:ax вправо на 1 бит call LongShiftRight ; сдвиг dx:ax вправо еще на 1 бит ret

LongShiftRight proc near shr dx,1

Page 57: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

57

rcr ax,1 ; сдвиг dx:ax вправо на 1 бит ret

LongShiftRight2 endp LongShiftRight endp

Также, как и последующие процедуры: ; Подпрограмма дальнего типа для сдвига dx:ax на 2 бита. ; LongShiftRight2 proc far

call LongShiftRight; сдвиг dx:ax вправо на 1 бит call LongShiftRight; сдвиг dx:ax вправо еще на 1 бит ret

LongShiftRight2 endp LongShiftRight proc near

shr dx,1 rcr ax,1 ; сдвиг dx:ax вправо на 1 бит ret

LongShiftRight endp Для явной генерации ближнего или дальнего возврата можно

использовать соответственно инструкции retn и retf. Вы можете обеспечить с их помощью корректную генерацию инструкций возврата.

7.21. Ошибки при использовании условных переходов

Использование в языке ассемблера инструкций условных

переходов (je, jne, jc, jnc, ja, jb, jg и т.д.) обеспечивает большую гибкость в программировании, но при этом очень просто ошибиться, выбрав неверный переход. Типичные ошибки:

7.21.1. Использование инструкций ja, jb, jae или jbe для сравнения значений со знаком или, соответственно, инструкций jg, jl, jge или jle для сравнения беззнаковых значений.

7.21.2. Использование, скажем, инструкции ja там, где нужно использовать jae. Нужно помнить о том, что без буквы e в конце инструкции в сравнении не учитывается случай, когда два операнда равны.

7.21.3. Использование инвертированной логики, например, применение инструкции js там, где нужно использовать jns.

Один из подходов, позволяющий минимизировать ошибки при использовании условных переходов состоит в комментировании

Page 58: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

58

переходов в соответствии с обозначениями, аналогичными языку Си. Например: ; ; if { Length > MaxLength } { ;

mov ax,[Length] cmp ax,[MaxLength] jng LengthIsLessThanMax . . . jng EndMaxLengthTest ;

; } else { ; LengthIsLessThanMax: . . . ;

; } ; EndMaxLengthTest: 7.22. Путают операнды в памяти и непосредственные

Программа на ассемблере может ссылаться либо на переменную

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

Например, смещение переменной в памяти размером в слово MemLoc представляет собой константу 5002, которую можно получить с помощью оператора OFFSET. Например, инструкция

mov bx,OFFSET MemLoc загружает значение 5002h в регистр bx. Значение 5002h представляет собой непосредственный операнд. Другими словами, оно встроено непосредственно в инструкцию и не изменяется.

Значением MemLoc является 1234h. Оно считывается из памяти со смещением 5002h в сегменте данных. Один из способов считывания данного значения состоит в загрузке в регистр bx, si, di или bp смещения MemLoc и использовании данного регистра для адресации к памяти. Инструкции

mov bx,OFFSET MemLoc mov ax,[bx]

загружают значение MemLoc в регистр ax. Значение MemLoc можно также загрузить непосредственно в ax с помощью инструкции

mov ax,MemLoc

Page 59: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

59

или mov ax,[MemLoc] Здесь значение 1234h получается как прямой, а не как

непосредственный операнд: инструкция mov использует встроенное в нее смещение 5002h и загружает в ax значение по смещению 5002h, которое в данном случае равно 1234h.

Часто встречающейся ошибкой является то, что часто забывают использовать операцию offset, например:

mov si,MemLoc, где нужно использовать смещение MemLoc. На первый взгляд, данная строка не выглядит неправильной, и так как MemLoc это переменная размером в слово, то эта строка не приведет к ошибке ассемблирования. Однако при выполнении в si будут загружены содержащиеся в переменной MemLoc данные (1234h), а не ее смещение (5002h) и результаты будут непредсказуемы.

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

mov si,offset MemLoc и

mov si,[MemLoc] становится совершенно понятной, в то время как инструкция

mov si,MemLoc будет настораживать.

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

1. Зубков С.В. Assembler для DOS, Windows и UNIX. / С.В. Зубков 11-е изд., стер. М.: ДМК Пресс; СПб.: Питер, 2010. 640 с.

2. Бурдаев О.В. Ассемблер в задачах защиты информации / О.В. Бурдаев, М.А. Иванов, И.И. Тетерин Под ред. И.Ю. Жукова. – 3-е изд., стер. – М.: КУДИЦ-ОБРАЗ, 2008. – 544 с.

Page 60: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

60

3. Абель Питер. Язык и программирование для IBM PC. / Питер Абель. Изд-во КОРОНА-Век, 2009.

Page 61: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

61

Приложение 1 Примеры (тексты) программ

Пример П.1.1 ;lab3pr1.asm ; Примеры mov al,b1 sar al,1 ; арифметический сдвиг байта вправо mov byte ptr rezult,al ; ---------------------------------------- mov al,b1 rol al,1 ; циклический сдвиг байта влево mov byte ptr rezult,al ; ---------------------------------------- mov al,b1 ror al,1 ; циклический сдвиг байта вправо mov byte ptr rezult,al =================================================================

Пример П.1.2 ; lab3pr2.asm COM-программа создания файла на диске и вывода в файл codesg segmentPARA 'Code'

assume cs:codesg,ds:codesg,ss:codesg,es:codesg org 100h ; обход PSP

begin: jmp main ;обход через данные ; --------------------------------------------------- flda dw 250 ;определение данных fldb dw 125 fldc dw ? soob1 db 'Привет!','$',0ah,0dh soob2 db 'Error ','$',0ah,0dh fcbrec label byte fcbdriv db 03 ;диск С fcbname db 'file1 ' fcbext db 'dat' fcbblk dw 0000 fcbrcsz dw ? fcbflsz dd ?

dw ? dt ?

fcbsqrc db 00 dd ?

; --------------------------------------------------- Main proc near

mov ah,09 lea dx, soob1 int 21h --------------------------------------------------- mov ah,16h lea dx,fcbrec int 21h ---------------------------------------------------

Page 62: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

62

cmp al,00 jnz error mov fcbrcsz,1 mov ah,1ah lea dx,soob2 int 21h --------------------------------------------------- mov ah,15h lea dx,fcbrec int 21h --------------------------------------------------- jmp exit

error: mov ah,09 lea dx, soob2 int 21h ---------------------------------------------------

exit: ret ;возврат в DOS

main endp codesg ends

end begin =================================================================

Пример П.1.3 formula3 proc ; lab3pr3.asm, АБП(1), ЦСЛ(10), СДП(11)П, СДЛ(12) ; Примеры:

cmp x1,3 jz fabp_1 cmp x1,4 jz fcsl_10 cmp x1,5 jz fsdr_11 cmp x1,6 jz fsdl_12

; Вычислительная часть! fabp_1: ;АБП(1)

mov al,b1 sar al,1 mov byte ptr rezult,al ret

fcsl_10: ;ЦСЛ(10) mov ax,w1 mov cx,10

csl_10: rol ax,1 loop csl_10 mov word ptr rezult,ax ret

fsdr_11: ;СДП(11)П mov ax,word ptr d1 mov dx,word ptr d1[2] mov cx,11

Page 63: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

63

cmp cf,0 jnz cf1

cf0: clc jmp sdr_11

cf1: stc sdr_11:

rcr dx,1 rcr ax,1 loop sdr_11 jc rcf1 jnc rcf0

rcf1: mov cf,1 jmp next

rcf0: mov cf,0 next: mov word ptr rezult,ax

mov word ptr rezult[2],dx ret

fsdl_12: ;СДЛ(12) mov ax,word ptr d1 mov dx,word ptr d1[2] mov cx,12

sdl_12: clc rcl ax,1 rcl dx,1 clc loop sdl_12 mov word ptr rezult,ax mov word ptr rezult[2],dx ret

formula3 endp =================================================================

Пример П.1.4 ; lab3pr4.asm использование блока управления файлом FCB для создания файла ;---------------------------------------------------------- codesg segment para 'Code'

assume cs:codesg,ds:codesg,ss:codesg,es:codesg org 100h ; обход PSP

begin: jmp main ;обход через данные ; --------------------------------------------------- reclen equ 32 namepar label byte ;список параметров: maxlen db reclen ; макс.длина имени namelen db ? ; число введенных символов namedta db reclen dup(' ') ; область передачи (DTA) fcbrec label byte ;FCB для дискового файла fcbdriv db 04 ; дисковод D fcbname db 'namefile' ; имя файла fcbext db 'dat' ; тип файла fcbblk dw 0000 ; номер текущего блока

Page 64: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

64

fcbrcsz dw ? ; размер логической записи fcbflsz dd ? ; размер файла (DOS)

dw ? ; дата (DOS) dt ? ; зарезервировано (DOS)

fcbsqrc db 00 ; номер текущей записи dd ? ; относительный номер

crlf db 13,10,'$' errcde db 00 prompt db 'Name? ','$' row db 01 opnmsg db '*** Open error ***', '$' wrtmsg db '*** Write error ***', '$' ; --------------------------------------------------------- main proc far

mov ax,0600h call q10scr ;очистить экран call q20curs ;установить курсор call c10open ;открыть, установить DTA cmp errcde,00 ;есть место на диске? jz a20loop ; да - продолжить, ret ; нет - вернуться в DOS

a20loop: call d10proc cmp namelen,00 ;конец ввода? jne a20loop ; нет продолжить, call g10clse ; да закрыть файл ret ; и вернуться в DOS

main endp ; Открытие дискового файла: c10open proc near

mov ah,16h ;функция создания файла lea dx,fcbrec int 21h cmp al,00 ;есть место на диске? jnz c20 ; нет ошибка

mov fcbrcsz,reclen ;размер записи (EQU) lea dx,namedta ;загрузить адрес DTA mov ah,1ah int 21ah ret

c20: lea dx,opnmsg ;сообщение об ошибке call x10err ret

c10open endp ; Ввод с клавиатуры: d10proc proc near

mov ah,09 ;функция вывода на экран

Page 65: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

65

lea dx,prompt ;выдать запрос int 21h

mov ah,0ah ;функция ввода lea dx,namepar ;ввести имя файла int 21h call e10disp ;прокрутка на экране

cmp namelen,00 ;имя введено? jne d20 ; да продолжить, ret ; нет выйти

d20: mov bh,00 ;заменить символ Return mov bl,namelen mov namedta[bx],' ' ;записать пробел call f10writ ;вызвать подпрограмму записи

; cld lea di,namedta ;очистить mov cx,reclen/2 ; поле mov ax,2020h ; имени rep stosw ret ;выйти

d10proc endp ; Прокрутка и установка курсора: e10disp proc near

mov ah,09 ;функция вывода на экран lea dx,crlf ;CR/LF int 21h ;вызов DOS cmp row,18 ;последняя строка экрана? jae e20 ; да обойти, inc row ; нет увеличить строку ret

e20: mov ax,0601h ;прокрутка на 1 строку call q10scr call q20curs ;установить курсор ret

e10disp endp ; Запись на диск: f10writ proc near

mov ah,15h ;функция записи lea dx,fcbrec int 21h cmp al,00 ;запись без ошибок? jz f20 ; да lea dx,wrtmsg ; нет call x10err ; выдать сообщение mov namelen,00

Page 66: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

66

f20: ret f10writ endp ; Закрытие дискового файла: g10clse proc near

mov namedta,1ah ;установить конец файла EOF call f10writ mov ah,10h ;функция закрытия lea dx,fcbrec int 21h ret

g10clse endp ; Прокрутка экрана: q10scr proc near ;ax уже установлен

mov bh,1eh ;цвет желтый на синем mov cx,0000 mov dx,184fh int 10h ;прокрутка ret

q10scr endp ; Установка курсора: q20curs proc near

mov ah,02 mov bh,00 mov dl,00 mov dh,row ;установить курсор int 10h ret

q20curs endp ; Вывод сообщения об ошибке на диске: x10err proc near

mov ah,09 ;dx содержит int 21h ; адрес сообщения mov errcde,01 ;установить код ошибки ret

x10err endp codesg ends

end begin __________________________________________________________________________

Программа, приведенная в данном примере, создает дисковый файл по имени, которое вводится пользователем с клавиатуры. Блок FCB (fcbrec) в данной программе содержит следующие поля:

fcbdriv программа должна создать файл на диске 4 (или D). fcbname имя файла namefile. fcbext тип файла dat. fcbblk Начальное значение номера текущего блока 0. fcbrcsz Размер записей не определен, так как операция открытия

устанавливает в данном поле значение 128. fcbsqrc -начальное значение номера текущей записи 0.

Page 67: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

67

В программе организованы следующие процедуры: begin вызывает c10open для создания файла и установки адреса DTA для

DOS, вызывает d10proc для ввода имени файла. Если ввод пустой, то происходит вызов g10clse для завершения программы;

c10open создает для файла элемент в директории, устанавливает размер записей 32 (шест.20) и инициализирует адрес буфера DTA для DOS.

d10proc выдает запрос на ввод имен, вводит имена с клавиатуры и вызывает процедуру f10writ для записи вводимых имен на диск.

e10disp управляет прокруткой и установкой курсора. f10writ записывает имена в дисковой файл. g10clse записывает маркер конца файла и закрывает файл. x10err выдает на экран сообщение об ошибке в случае некорректной

операции создания файла или записи данных. Каждая операция записи автоматически добавляет 1 к fcbsqrc (номер

текущей записи) и шест. 20 (размер записи) к fcbflsz (размер файла). Так как каждая запись имеет длину 32 байта, то операция заносит в буфер 16 записей и затем записывает весь буфер в сектор диска. Ниже показано содержимое DTA и буфера:

DTA: |текущая запись| Буфер: |запись 00|запись 01|запись 02|...|запись 15| Если пользователь ввел 25 имен, то счетчик записей увеличится от 1 до 25

(шест.19). Размер файла составит: 25 * 32 байта = 800 байтов или шест. 320 Операция закрытия заносит во второй сектор оставшиеся в буфере девять

записей и изменяет в оглавлении дату и размер файла. Размер записывается байтами в переставленном порядке: 20030000. Последний буфер имеет следующий вид:

Буфер: |запись 16|запись 17|...|запись 24|шест.1A|...|...| Для простоты в приведенной программе создаются записи файла,

содержащие только одно поле. Записи большинства других файлов, однако, содержат различные символьные и двоичные поля и требуют описания записи в DTA. Если записи содержат двоичные числа, то не следует использовать маркер конца файла (EOF), так как двоичное число может совпасть с шест. кодом 1A.

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

Пример П.1.5 ; lab3pr5.asm программа, использующая FCB для чтения дискового файла ; Чтение записей созданных в CREATDSK ; ------------------------------------------------------- codesg segmentPARA 'Code'

assume cs:codesg,ds:codesg,ss:codesg,es:codesg org 100h ; обход PSP

begin: jmp main ;обход через данные

Page 68: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

68

; --------------------------------------------------- fcbrec label byte ;FCB для файла fcbdriv db 04 ; дисковод D fcbname db 'namefile' ; имя файла fcbext db 'dat' ; тип файла fcbblk dw 0000 ; номер текущего блока fcbrcsz dw 0000 ; длина логической записи fcbflsz dd ? ; размер файла (DOS)

dw ? ; дата (DOS) dt ? ; зарезервировано (DOS)

fcbsqrc db 00 ; текущий номер записи dd ? ; относительный номер

reclen equ 32 ;длина записи namefld db reclen dup(' '), 13, 10, '$' endcde db 00 openmsg db '*** Open error ***', '$' readmsg db '*** Read error ***', '$' row db 00 main proc far

mov ax,0600h call q10scr ;очистить экран call q20curs ;установить курсор call e10open ;открыть файл и установить DTA cmp endcde,00 ;открытие без ошибок? jnz a90 ; нет завершить

a20loop: call f10read ;прочитать запись cmp endcde,00 ;чтение без ошибок? jnz a90 ; нет выйти call g10disp ;выдать имя на экран jmp a20loop ;продолжить

a90: ret ;завершить begin endp ; Открытие файла на диске: e10open proc near

lea dx,fcbrec mov ah,0fh ;функция открытия int 21h cmp al,00 ;файл найден? jnz e20 ; нет ошибка mov fcbrcsz,reclen ;длина записи (EQU) mov ah,1ah lea dx,namefld ;адрес DTA int 21h ret

e20: mov endcde,01 ;сообщение об ошибке lea dx,openmsg call x10error

Page 69: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

69

ret e10open endp ; Чтение дисковой записи: f10read proc near

mov ah,14h ;функция чтения lea dx,fcbrec int 21h cmp namefld,1ah ;считан маркер EOF? jne f20 ; нет mov endcde,01 ; да jmp f90

f20: cmp al,00 ;чтение без ошибок? jz f90 ; да выйти mov endcde,01 ; нет: cmp al,01 ;конец файла? jz f90 ; да выйти, lea dx,readmsg ; нет значит call x10err ; ошибка чтения

f90: ret

f10read endp ; Вывод записи на экран: g10disp proc near

mov ah,09 ;функция вывода на экран lea dx,namefld int 21h cmp row,20 ;последняя строка экрана? jae g30 ; нет... inc row ; да увеличить строку jmp g90

g30: mov ax,0601h call q10scr ; прокрутить call q20curs ; установить курсор

g90: ret g10disp endp ; Прокрутка (скроллинг) экрана: q10scr proc near ;ax уже установлен

mov bh,1eh ;установить цвет mov cx,0000 mov dx,184fh ;функция прокрутки int 10h ret

q10scr endp ; Установка курсора: q20curs proc near

mov ah,02 mov bh,00

Page 70: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

70

mov dh,row mov dl,00 int 10h ret

q20curs endp ; Вывод сообщения об ошибке на диске: x10err proc near

mov ah,09 ;dx содержит адрес int 21h ; сообщения ret

x10err endp codesg ends

end begin В данном примере приведена программа, которая выполняет чтение файла,

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

begin вызывает процедуру e10open для открытия файла и установки DTA и вызывает f10read для чтения записей. Если считан маркер конца файла, то программа завершается, если нет, то вызывается процедура g10disp.

e10open открывает файл, устанавливает значение размера и записей, равное 32 (шест. 20), и инициализирует адрес DTA.

f10read выполняет последовательное чтение записей. Операция чтения автоматически увеличивает номер текущей записи в блоке FCB.

g10disp выводит на экран содержимое прочитанной записи. x10err выводит на экран сообщение об ошибке в случае некорректной

операции открытия или чтения. Операция открытия выполняет поиск имени и типа файла в оглавлении. Если

необходимый элемент оглавления найден, то автоматически в блок FCB заносятся размер файла, дата и длина записей. Первая операция чтения записи с номером 00 получает доступ к диску и считывает весь сектор (16 записей) в буфер. После этого первая запись заносится в DTA, а номер текущей записи в FCB увеличивается с 00 до 01:

Буфер: |запись 00|запись 01|запись 02|... |запись 15| DTA : |запись 00|

Второй операции чтения нет необходимости обращаться к диску. Так как требуемая запись уже находится в буфере, то операция просто пересылает запись 01 из буфера в DTA и увеличивает номер текущей записи на единицу.

Таким же образом выполняются следующие операции чтения, пока все 16 записей из буфера не будут обработаны.

Операция чтения 16-й записи приводит к физическому чтению следующего сектора в буфер и пересылке первой записи сектора в DTA. Последующие операции чтения переносят остальные записи из буфера в DTA. Попытка прочитать после последней записи вызовет состояние конца файла и в регистр al будет записан код возврата шест. 01.

Page 71: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

71

Приложение 2 Пример работы № 3

;================================================================ ; l_3bnn.asm, Работа №3 ; выполнена студентом 1 курса СибАДИ группы 11 БИ ; Буслаевым Н.Н. (здесь чужого кода еще меньше) ;================================================================ codesg segment para 'Code' ;начало сегмента кода assume cs:codesg,ds:codesg,ss:codesg org 100h start: jmp begin ;обход данных soob1 db ' Программа расчёта по формулам',0ah,0dh,'$' soobform1 db '#1 b1*b2*b3-d1/b3+w1+w2',0ah,0dh,'$' soobform3 db '#3 логический сдвиг слова влево на 2',0ah,0dh,'$' soobform4 db '#4 арифметический сдвиг двойного слова вправо на 3',0ah,0dh,'$' soobform5 db '#5 циклический сдвиг байта влево на 4',0ah,0dh,'$' soobform6 db '#6 циклический сдвиг слова вправо через флаг переноса на 5',0ah,0dh,'$' soobform34 db '#34 w1 or w2 ',0ah,0dh,'$' soobform35 db '#35 w1 xor w2 ',0ah,0dh,'$' soobform49 db '#49 w13 and b13 ',0ah,0dh,'$' soobform57 db '#57 w19 and not(b16) ',0ah,0dh,'$' soobform62 db '#62 w21 and neg(w2) ',0ah,0dh,'$' soobformnum db 'Введите, пожалуйста номер формулы: $' soobCFval1 db 'Флаг CF содержит 1 $' soobCFval0 db 'Флаг CF содержит 0 $' soobCFent db 'Введите значение флага CF: $' soob_vixod db 'Для выхода нажмите любую клавишу! ', '$' soobformerr db 'Формулы с таким номером не существует! $' X db 1 CFval db 0 b1 db 5 ;_____________________________ b2 db 2 b3 db 1 w1 dw 1 w2 dw 1 d1 dd 1 b13 db 1 b16 db 1 w13 dw 1 w19 dw 1 w21 dw 1 rezult dd 0 ;_____________________________ res dd 0 res1w dw 0 res2 dd 0

Page 72: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

72

namepar_b label byte ;_____________________________ maxlen_b db 4 faktlen_b db ? namefld_b db 4 dup(' ') namepar_w label byte ;_____________________________ maxlen_w db 6 faktlen_w db ? namefld_w db 6 dup(' ') namepar_d label byte ;_____________________________ maxlen_d db 12 faktlen_d db ? namefld_d db 12 dup(' ') binval_b dw 0 ;_____________________________ binval_w dw 0 binval dd 0 binval_d dw 0

dw 0 ascval db '00000000000000000000','$' kol dd 0 ln db 0 del dd 0 soob2 db 'Введите b1 ','$' ;_____________________________ soob3 db 'Введите b2 ','$' soob4 db 'Введите b3 ','$' soob5 db 'Введите b13 ','$' soob6 db 'Введите b16 ','$' soob7 db 'Введите w1 ','$' soob8 db 'Введите w2 ','$' soob11 db 'Введите d1 ','$' ;soobask db 'Ещё раз вычислять будем ? Если да, нажмите "1"',0ah,0dh,'$' strerr1 db 'Ошибка! Значение больше 127',0ah,0dh,'$' strerr2 db 'Ошибка! Значение больше 32767',0ah,0dh,'$' strerr3 db 'Ошибка! Значение больше 2147483647',0ah,0dh,'$' strerr4 db 'Недопустимое значение CF! $' mult10 dw 1 ;_____________________________

dw 0 ;область DTA reclen equ 20 namepar label byte maxlen db reclen namelen db ? namedta db reclen dup (' ') ; блок управления файлом FCB fcbrec label byte ;FCB для дискового файла fcbdriv db 03 ; дисковод C fcbname db 'result00' ; имя файла fcbext db 'txt' ; тип файла

Page 73: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

73

fcbblk dw 0 ; номер текущего блока fcbrcsz dw ? ; размер логической записи fcbflsz dd ? ; размер файла (DOS)

dw ? ; дата (DOS) dt ? ; зарезервировано (DOS)

fcbsqrc db 0 ; номер текущей записи dd ? ; относительный номер

begin proc far ;главная процедура ;_________________________ ; mov ln,1 mov ax,0600h ;очистка экрана mov bh,011 mov cx,0000 mov dx,184fh int 10h call stroka call himess entfnum: call entx ; ввод и преобразование номера формулы (Х) mov maxlen_b,4 mov word ptr namefld_b, 2020h cmp x,1 ;вычисление по формуле 1? jnz f34 ; нет call entb1 ; ввод и преобразование b1 call entb2 ; ввод и преобразование b2 call entb3 ; ввод и преобразование b3 call entw1 ; ввод и преобразование w1 call entw2 ; ввод и преобразование w2 call entd1 ; ввод и преобразование d1 call form1 ;вызов процедуры вычислений по формуле 1 jmp rgn f34: cmp X,34 jnz f35 call entw1 call entw2 call form34 jmp rgn f35: cmp X,35 jnz f49 call entw1 call entw2 call form35 jmp rgn f49: cmp X,49 jnz f57 call entw13 call entb13 call form35 jmp rgn f57: cmp X,57

Page 74: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

74

jnz f62 call entw19 call entb16 call form57 jmp rgn f62: cmp X,62 jnz f3 call entw21 call entw2 call form62 jmp rgn f3: cmp X,3 jnz f4 call entw1 call form3 jmp rgn f4: cmp X,4 jnz f5 call entd1 call form4 jmp rgn f5: cmp X,5 jnz f6 call entb1 call form5 jmp rgn f6: cmp X,6 jnz ferr call entw1 call entcf call form6 jmp rgn ferr: mov ah,09h lea dx,soobformnumerr int 21h call stroka jmp entfnum rgn: call bin2asc ;вызов преобразования из bin в ascii call diskwrite ;вывод результата на диск mov ah,9 ;\ lea dx,ascval ; вывод на экран результата int 21h ;/ call stroka cmp X,6 jnz mmmmm call printcf mmmmm: mov ah,02 ;\ | установка курсора mov bh,00 ; \ | экран 0 mov dh,24 ; управление курсором | строка 23

Page 75: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

75

mov dl,00 ; / | столбец 00 int 10h ;/ | передача упр. в BIOS mov ah,09 lea dx,soob_vixod int 21h mov ah,0 ;-ожидание нажатия клавиши int 16h ;/ int 20h ; ret ;передача управления в DOS begin endp ;конец главной процедуры diskwrite proc mov ah,16h ;функция создания файла lea dx,fcbrec int 21h ; cmp al,00 ;есть место на диске? ; jnz c20 ; нет ошибка mov fcdrcsz,reclen ;размер записи (EQU) ; lea dx,namedta ;эагрузить адрес DTA lea dx,ascval mov ah,1ah int 21h mov ah,15h ;функция записи lea dx,fcbrec int 21h mov ah,10h ;функция закрытия ; lea dx,fcbrec int 21h ret diskwrite endp himess proc mov ah,09 ;вывод на экран lea dx,soob1 ;заслать в dx адрес soob1 int 21h ; call stroka ; mov ah,09 ;вывод на экран lea dx,soobform1 ;заслать в dx адрес soobform int 21h ;прерывание (передача управления в BIOS) ; call stroka lea dx,soobform34 int 21h ; call stroka lea dx,soobform35 int 21h ; call stroka lea dx,soobform49 int 21h ; call stroka lea dx,soobform57 int 21h ; call stroka

Page 76: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

76

lea dx,soobform62 int 21h ; call stroka lea dx,soobform3 int 21h ; call stroka lea dx,soobform4 int 21h ; call stroka lea dx,soobform5 int 21h ; call stroka lea dx,soobform6 int 21h ; call stroka add ln,11 ret himess endp ;************************************************************************ ; Процедура вычисления по формуле b1*b2*b3-d1/b3+w1+w2 ;************************************************************************ form1 proc ; Вычисление w1+w2: xor dx,dx ;dx=0 mov ax,w1 ;ax=w1 add ax,w2 ;ax =ax+w2=w1+w2 adc dx,0 ;dx=dx+0+CF ;(dx:ax)= w1+w2 mov word ptr rezult,ax mov word ptr rezult+2,dx ;результат в rezult ; Вычисление b1*b2*b3 mov al,b1 ;al=b1 mul b2 ;ax=al*b2=b1*b2 mov bl,b3 ;bl=b3 xor bh,bh ;bx=bl=b3 mul bx ;(dx:ax)=ax*bx=b1*b2*b3

mov word ptr res, ax mov word ptr res+2, dx ; результат в res ; Вычисление d1/b3 mov ax,word ptr d1 mov dx,word ptr d1+2 mov bL,b3 xor bh,bh div bx ;(dx:ax)/bx ;частное в ax, остаток в dx ; можно по-другому: div bl ;ax/bl ; но частное в al, а остаток в ah mov res1w,ax ; Вычисление res (b1*b2*b3) - d1/b3

Page 77: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

77

mov ax,word ptr res mov dx,word ptr res+2 ;(dx:ax)=res sub ax,res1w ;ax=ax-res1w sub dx,0 ;dx=dx-0-CF ;(dx:ax)= res - res1w ; mov word ptr res,ax ; mov word ptr res+2,dx ; Вычисление (b1*b2*b3-d1/b3) + (w1+w2) add ax,word ptr rezult adc dx,word ptr rezult+2 ;прибавляем к (dx:ax) rezult ; т.е. w1+w1 mov word ptr rezult,ax ; заносим результат в rezult mov word ptr rezult+2,dx ; в итоге результат хранится в ячейке rezult (двойное слово) ret form1 endp ;************************************************************************* ; Ввод и преобразование номера формулы (числа X) ;************************************************************************* entx proc Xb: mov ah,09 ; вывод приглашения lea dx,soobformnum int 21h mov ah,0Ah ; ввод с клавиатуры X lea dx,namepar_b int 21h call stroka call asc2bin_byte ;перевод из ASCII в bin xor ax,ax ;переносим переведённый байт в X mov al,byte ptr binval_b mov X,al ; mov al,b1 ;b1 сравниваем с 127 ; cmp al,127 ; ja Xm ;если >, то на метку Хm jmp Xe ;если <= , то на метку Хe Xm: mov ah,09 ;вывод на экран lea dx,strerr1 ;сообщения об ошибке int 21h jmp Xb ;переход на Xb Xe: ret entx endp ;================================================================ ; Процедура перевода из двоичного в ASCII ; (исправлено для перевода двойного слова...) ; чтобы преревести четверное, надо раскомментировать строчки ;================================================================ bin2asc proc

Page 78: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

78

lea si,ascval[19] m1: ; cmp word ptr rezult[6],0 ; jne m2 ; cmp word ptr rezult[4],0 ; jne m2 cmp word ptr rezult[2],0 jne m2 cmp word ptr rezult,10 jnb m2 mov ax,word ptr rezult or al,30h mov [si],al dec si jmp m3 m2: sub word ptr rezult,10 sbb word ptr rezult[2],0 ; sbb word ptr rezult[4],0 ; sbb word ptr rezult[6],0 add word ptr kol,1 adc word ptr kol[2],0 ; adc word ptr kol[4],0 ; adc word ptr kol[6],0 jmp m1 m3: ; cmp word ptr kol[6],0 ; jne m4 ; cmp word ptr kol[4],0 ; jne m4 cmp word ptr kol[2],0 jne m4 cmp word ptr kol,0 jne m4 ret ; выход из процедуры bin2asc m4: mov ax,word ptr kol mov word ptr rezult,ax mov ax,word ptr kol[2] mov word ptr rezult[2],ax ; mov ax,word ptr kol[4] ; mov word ptr rezult[4],ax ; mov ax,word ptr kol[6] ; mov word ptr rezult[6],ax mov word ptr kol,0 mov word ptr kol[2],0 ; mov word ptr kol[4],0 ; mov word ptr kol[6],0 jmp m1 bin2asc endp

Page 79: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

79

clrascval proc mov cx,20 mov si,19 clr1: and ascval[si],30h dec si loop clr1 ret clrascval endp ;================================================================= asc2bin_byte proc ;процедура перевода из ASCII в bin для байта mov mult10,1 mov binval_b,0 xor ax,ax xor dx,dx mov cx,10 ; фактор умножения lea si,namefld_b – 1 ; адрес ascval mov bl,faktlen_b ; длина ascval mov bh,0 a21: mov al,[si+bx] ; выбрать ASCII-символ and ax,000Fh ; очистить зону тройки mul mult10 ; умножить на фактор 10 add binval_b,ax ; прибавить к двоичному mov ax,mult10 ; вычислить следующий mul cx ; фактор умножения mov mult10,ax dec bx ; последний. ASCII-символ? jnz a21 ; нет - продолжить ret asc2bin_byte endp ;================================================================ asc2bin_word proc ;процедура перевода из ASCII в bin для слова mov mult10,1 mov binval_w,0 xor ax,ax xor dx,dx mov cx,10 ; фактор умножения lea si,namefld_w – 1 ; адрес ascval mov bl,faktlen_w ; длина ascval mov bh,0 b20: mov al,[si+bx] ; выбрать ASCII-символ and ax,000Fh ; очистить зону тройки mul mult10 ; умножить на фактор 10 add binval_w,ax ; прибавить к двоичному mov ax,mult10 ; вычислить следующий mul cx ; фактор умножения mov mult10,ax

Page 80: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

80

dec bx ; последний. ASCII-символ? jnz b20 ; нет - продолжить ret asc2bin_word endp ;================================================================ asc2bin_dword proc ;процедура перевода из ASCII в bin для двойного слова comment @ mov mult10,1

mov binval_d,0 xor ax,ax xor dx,dx mov cx,10 lea si,namefld_d-1 mov bl,faktlen_d mov bh,0

abd20: mov al,[si+bx] and ax,000fh

mov DI,mult10 mul DI ; mul mult10

add word ptr binval_d,ax adc word ptr binval_d+2,dx mov ax,mult10 mul cx mov mult10,ax dec bx jnz abd20 ret

@ xor ax,ax xor bx,bx xor cx,cx xor dx,dx mov word ptr binval_d,ax mov word ptr binval_d[2],ax mov word ptr mult10[2],ax mov word ptr mult10,1 mov al,faktlen_d mov cl,al dec al mov si,ax met1_d: mov bl,namefld_d[si] cmp bx,30h jb error_d cmp bx,39h ja error_d and bl,0fh mov dx,0 mov ax,0 abd1: cmp bl,0

Page 81: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

81

jz abd2 add ax,word ptr mult10 adc dx,word ptr mult10[2] dec bl jmp abd1 abd2: add word ptr binval_d,ax adc word ptr binval_d[2],dx mov bl,9 mov dx,word ptr mult10[2] mov ax, word ptr mult10 abd3: cmp bl,0 jz abd4 add word ptr mult10,ax adc word ptr mult10[2],dx dec bl jmp abd3 abd4: dec si loop met1_d mov dx,word ptr binval_d[2] mov ax,word ptr binval_d jmp end_error_d error_d: call stroka mov ah,09h lea dx,strerr3 int 21h ; mov osh_v,1 end_error_d: ret asc2bin_dword endp ;************************************************************************* ; Перевод из ASCII в bin числа b1 ;************************************************************************* entb1 proc b1b: ; вывод сообщения 'b1= ' mov ah,09

lea dx,soob2 int 21h

; ввод с клавиатуры b1 mov ah,0Ah lea dx,namepar_b int 21h call stroka call asc2bin_byte ;перевод из ASCII в bin xor ax,ax ;переносим переведённый байт в b1 mov al,byte ptr binval_b

mov b1,al ; mov al,b1 cmp al,127 ;b1 сравниваем с 127

Page 82: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

82

ja b1m ;если >, то на метку b1m jmp b1e ;если <= , то на метку b1e

b1m: mov ah,09 ;вывод на экран lea dx,strerr1 ;сообщения об ошибке int 21h jmp b1b ; переход на B1B

b1e: ret entb1 endp ;************************************************************************* ; Перевод из ASCII в bin числа b2 ;************************************************************************* entb2 proc b2b:

mov ah,09 ; вывод сообщения: 'b2= ' lea dx,soob3 int 21h

; ввод с клавиатуры b2 mov ah,0Ah lea dx,namepar_b int 21h

; mov mult10,1 call stroka

call asc2bin_byte ;перевод из ASCII в bin xor ax,ax ;переносим переведённый байт в b2 mov al,byte ptr binval_b mov b2,al ; mov al,b2 cmp al,127 ;b2 сравниваем с 127 ja b2m ;если >, то на метку b2m jmp b2e ;если <= , то на метку b2e

b2m: mov ah,09 ;вывод на экран lea dx,strerr1 ;сообщения об ошибке int 21h jmp b2b ; переход на b2b

b2e: ret entb2 endp ;************************************************************************ ; Перевод из ASCII в bin числа b3 ;************************************************************************ entb3 proc b3b:

mov ah,09 ; вывод сообщения 'b3= ' lea dx,soob4 int 21h

; ввод с клавиатуры b3 mov ah,0Ah

Page 83: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

83

lea dx,namepar_b int 21h

call stroka ; mov mult10,1 ; перевод из ASCII в bin

call asc2bin_byte ; переносим переведённый байт в b3

xor ax,ax mov al,byte ptr binval_b mov b3,al ; mov al,b3 cmp al,127 ;b3 сравниваем с 127 ja b3m ;если >, то на метку b3m jmp b3e ;если <= , то на метку b3e

b3m: mov ah,09 ;вывод на экран lea dx,strerr1 ;сообщения об ошибке int 21h jmp b3b ; переход на b3b

b3e: ret entb3 endp ;************************************************************************ ; Перевод из ASCII в bin числа b13 ;************************************************************************ entb13 proc b13b: ; вывод сообщения 'b13= ' mov ah,09

lea dx,soob5 int 21h

; ввод с клавиатуры b13 mov ah,0Ah lea dx,namepar_b int 21h call stroka call asc2bin_byte ;перевод из ASCII в bin xor ax,ax ;переносим переведённый байт в b13 mov al,byte ptr binval_b mov b13,al ; mov al,b13 cmp al,127 ;b13 сравниваем с 127 ja b13m ;если >, то на метку b13m jmp b13e ;если <=, то на метку b13e

b13m: mov ah,09 ;вывод на экран lea dx,strerr1 ;сообщения об ошибке int 21h jmp b13b ; переход на b13b

b13e:

Page 84: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

84

ret entb13 endp ;************************************************************************ ; Перевод из ASCII в bin числа b16 ;************************************************************************ entb16 proc b16b: ; вывод сообщения 'b16= ' mov ah,09

lea dx,soob6 int 21h

; ввод с клавиатуры b16 mov ah,0Ah lea dx,namepar_b int 21h call stroka call asc2bin_byte ;перевод из ASCII в bin xor ax,ax ;переносим переведённый байт в b16 mov al,byte ptr binval_b

mov b16,al ; mov al,b16 cmp al,127 ;b16 сравниваем с 127 ja b16m ;если >, то на метку b16m jmp b16e ;если <= , то на метку b16e

b16m: mov ah,09 ;вывод на экран lea dx,strerr1 ;сообщения об ошибке int 21h jmp b16b ; переход на b16b

b16e: ret entb16 endp ;************************************************************************ ; Перевод из ASCII в bin числа w1 ;************************************************************************ entw1 proc w1b:

mov ah,09 ; вывод сообщения 'w1= ' lea dx,soob7 int 21h

; ввод с клавиатуры w1 mov ah,0ah lea dx,namepar_w int 21h call stroka

;mov mult10,1 call asc2bin_word ;перевод из ASCII в bin ; xor ax,ax mov ax,binval_w ;переносим переведённое значение в w1 mov w1,ax

Page 85: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

85

; mov ax,w1 cmp ax,32767 ;w1 сравниваем с 32767 ja w1m ;если >, то на метку w1m jmp w1e ;если <= , то на метку w1e

w1m: mov ah,09 ;вывод на экран lea dx,strerr2 ;сообщения об ошибке int 21h jmp w1b ; переход на w1b

w1e: ret

entw1 endp ;************************************************************************ ; Перевод из ASCII в bin числа w2 ;************************************************************************ entw2 proc w2b:

mov ah,09 ; вывод сообщения 'w2= ' lea dx,soob8 int 21h

; ввод с клавиатуры w2 mov ah,0Ah lea dx,namepar_w int 21h

call stroka ;mov mult10,1

call asc2bin_word ;перевод из ASCII B BIN xor ax,ax ;переносим переведённый байт в w2 mov ax, binval_w mov w2,ax ; mov ax,w2 cmp ax,32767 ;w2 сравниваем с 32767 ja w2m ;если >, то на метку w2m jmp w2e ;если <= , то на метку w2e

w2m: mov ah,09 ;вывод на экран lea dx,strerr2 ;сообщения об ошибке int 21h jmp w2b ; переход на w2b

w2e: ret entw2 endp ;************************************************************************ ; Перевод из ASCII в bin числа w13 ;************************************************************************ entw13 proc w13b:

mov ah,09 ; вывод сообщения 'w13= ' lea dx,soob7 int 21h

Page 86: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

86

; ввод с клавиатуры w13 mov ah,0Ah lea dx,namepar_w int 21h

call stroka ;mov mult10,1

call asc2bin_word ;перевод из ASCII в bin ; xor ax,ax mov ax,binval_w ;переносим переведённый байт в w1 mov w1,ax ; mov ax,w1 cmp ax,32767 ;w13 сравниваем с 32767 ja w13m ;если >, то на метку w13m jmp w13e ;если <=, то на метку w13e

w13m: mov ah,09 ;вывод на экран lea dx,strerr2 ;сообщения об ошибке int 21h jmp w1b ; переход на w1b

w13e: ret entw13 endp ;************************************************************************ ; Перевод из ASCII в bin числа w19 ;************************************************************************ entw19 proc w19b:

mov ah,09 ; вывод сообщения 'w19= ' lea dx,soob7 int 21h

; ввод с клавиатуры w19 mov ah,0Ah lea dx,namepar_w int 21h

call stroka ;mov mult10,1

call asc2bin_word ;перевод из ASCII в bin xor ax,ax ;переносим переведённое значение в w19 mov ax,binval_w mov w19,ax ; mov ax,w19 cmp ax,32767 ;w19 сравниваем с 32767 ja w19m ;если >, то на метку w19m jmp w19e ;если <= , то на метку w19e

w19m: mov ah,09 ;вывод на экран lea dx,strerr2 ;сообщения об ошибке int 21h jmp w19b ; переход на w19b

w19e:

Page 87: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

87

ret entw19 endp ;************************************************************************ ; Перевод из ASCII в bin числа w21 ;************************************************************************ entw21 proc w21b:

mov ah,09 ; вывод сообщения 'w21= ' lea dx,soob8 int 21h

;ввод с клавиатуры w21 mov ah,0ah lea dx,namepar_w int 21h

call stroka ;mov mult10,1

call asc2bin_word ;перевод из ASCII в bin xor ax,ax ;переносим переведённое значение в w2 mov ax, binval_w mov w21,ax ; mov ax,w21 cmp ax,32767 ;w21 сравниваем с 32767 ja w21m ;если >, то на метку w21m jmp w21e ;если <=, то на метку w21e

w21m: mov ah,09 ;вывод на экран lea dx,strerr2 ;сообщения об ошибке int 21h jmp w21b ; переход на w21b

w21e: ret entw21 endp ;************************************************************************ ; Перевод из ASCII в bin числа d1 ;************************************************************************ entd1 proc d1b:

mov ah,09 ; вывод сообщения 'd1= ' lea dx,soob11 int 21h mov ah,0ah ; ввод с клавиатуры d1 lea dx,namepar_d int 21h

call stroka ;mov mult10,1

call asc2bin_dword ;перевод из ASCII в bin ; xor ax,ax xor bx,bx xor cx,cx ; xor dx,dx

Page 88: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

88

mov ax,word ptr binval_d ;переносим переведённое значение в d1 mov dx,word ptr binval_d+2 mov word ptr d1,ax mov word ptr d1+2,dx

; cmp dx,21474 ;dx сравниваем с 21474 ; ja d1m ;если >, то на метку d1m

jmp d1e ;если <= , то на метку d1e d1m:

mov ah,09 ;вывод на экран lea dx,strerr3 ;сообщения об ошибке

int 21h jmp d1b ; переход на d1b

d1e: ret entd1 endp ;************************************************************************ ; Процедура перевода строки ;************************************************************************ stroka proc near ;процедура перевода курсора на новую строку push inc ln mov ah,02 mov bh,00 mov dh,ln mov dl,00 int 10h pop

ret stroka endp printCF proc shr CFval,1 mov ah,09h jnc mcf0 lea dx,soobcfval1 jmp mcfe mcf0: lea dx,soobcfval0 mcfe: int 21h call stroka ret printcf endp entcf proc CFb: mov ah,09h ; вывод приглашения lea dx,soobcfent int 21h mov ah,0ah ; ввод с клавиатуры X lea dx,namepar_b int 21h

Page 89: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

89

call stroka call asc2bin_byte ;перевод из ASCII в bin ; xor ax,ax mov al,byte ptr binval_b mov CFval,al ;переносим переведённый байт в CFval cmp al,1 jna CFe mov ah,09 lea dx,strerr4 int 21h call stroka jmp Xb CFe: ret entcf endp ; #34 w1 or w2 form34 proc mov ax,w1 or ax,w2 mov word ptr rezult,ax mov word ptr rezult+2,0000h ret form34 endp ; #35 w1 xor w2 form35 proc mov ax,w1 xor ax,w2 mov word ptr rezult,ax mov word ptr rezult+2,0000h ret form35 endp ; #49 w13 and b13 form49 proc ; xor ax,ax mov ax,w13 and al,b13 xor ah,ah mov word ptr rezult,ax mov word ptr rezult+2,0000h ret form49 endp ; #57 w19 and not(b16) form57 proc not b16 mov ax,w19 and al,b16 xor ah,ah mov word ptr rezult,ax mov word ptr rezult+2,0000h ret form57 endp ; #62 w21 and neg(w2) form62 proc

Page 90: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

90

neg w2 mov ax,w21 and ax,w2 mov word ptr rezult,ax mov word ptr rezult+2,0000h ret form62 endp ; #3 логический сдвиг слова влево на 2 form3 proc mov ax,w1 shl ax,1 shl ax,1 mov word ptr rezult,ax ret form3 endp ; #4 арифметический сдвиг двойного слова вправо на 3 form4 proc mov ax,word ptr d1 mov dx,word ptr d1+2 mov cx,3 f4b: clc sar dx,1 jnc f4e shr ax,1 or ah,10000000b jmp f4ee f4e: shr ax,1 f4ee: loop f4b mov word ptr rezult,ax mov word ptr rezult+2,dx ret form4 endp ; #5 циклический сдвиг байта влево на 4 form5 proc ; xor ax,ax mov al,b1 ; xor cx,cx mov cl,4 rol al,cl mov byte ptr rezult,al ret form5 endp ; #6 логический сдвиг слова вправо через флаг переноса на 5 form6 proc shr CFval,1 mov ax,w1 mov cl,5 rcr ax,cl mov word ptr rezult,ax rcl CFval,1 ret form6 endp codesg ends ;конец сегмента кода

end start

Page 91: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

91

Приложение 3 Формулы (3-я работа)

№ п/п

Выполняемые вычисления или действия

№ п/п

Выполняемые вычисления или действия

1 СБЛ(1), АСП(2), ЦДЛ(3), ЦБП(4)П

13 СБЛ(5), АСП(14), ЦДЛ(15), ЦБП(1)П

2 ССЛ(2), АДП(3), ЦБЛ(4), ЦСП(5)П

14 ССЛ(14), АДП(15), ЦБЛ(7), ЦСП(1)П

3 СДЛ(3), АБП(4), ЦСЛ(5), ЦДП(6)П

15 СДЛ(15), АБП(3), ЦСЛ(3), ЦДП(18)П

4 СБЛ(4), АСП(5), ЦДЛ(6), ЦБП(7)П

16 СБЛ(3), АСП(4), ЦДЛ(17), ЦБП(3)П

5 ССЛ(5), АДП(6), ЦБЛ(7), ЦСП(8)П

17 ССЛ(2), АДП(19), ЦБЛ(1), ЦСП(4)П

6 СДЛ(6), АБП(7), ЦСЛ(8), ЦДП(9)П

18 СДЛ(18), АБП(4), ЦСЛ(2), ЦДП(21)П

7 СБЛ(7), АСП(8), ЦДЛ(9), ЦБП(2)П

19 СБЛ(4), АСП(3), ЦДЛ(20), ЦБП(6)П

8 ССЛ(8), АДП(9), ЦБЛ(2), ЦСП(11)П

20 ССЛ(5), АДП(22), ЦБЛ(2), ЦСП(7)П

9 СДЛ(9), АБП(2), ЦСЛ(11), ЦДП(12)П

21 СДЛ(6), АБП(1), ЦСЛ(3), ЦДП(8)П

10 СБЛ(2), АСП(11), ЦДЛ(12), ЦБП(5)П

22 СБЛ(7), АСП(2), ЦДЛ(4), ЦБП(7)П

11 ССЛ(11), АДП(12), ЦБЛ(5), ЦСП(14)П

23 ССЛ(1), АДП(3), ЦБЛ(5), ЦСП(10)П

12 СДЛ(12), АБП(5), ЦСЛ(14), ЦДП(15)П

24 СДЛ(6), АБП(4), ЦСЛ(6), ЦДП(27)П

Здесь применяются следующие обозначения: 1) первый символ: С – логический сдвиг; А – арифметический сдвиг; Ц –

циклический сдвиг; 2) второй символ: Б – байт; С – слово; Д – двойное слово; 3) третий символ: Л – влево; П – вправо; 4) четвертый символ: П – с переносом.

Page 92: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

92

Приложение 4 Редактирование, ассемблирование

и компоновка программы

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

первых шести работ достаточно: - установить операционную систему Windows 95 (или выше: Windows 98,

Windows XP Edition, Windows XP Proffetional, Windows 2000, кроме Windows Millenium);

- установить Far; -создать папку C:\assebler и поместить в нее все содержимое папки

u_m_lab3, т.е. следующие файлы: tasm.exe, tlink.exe, rtm.exe, dpmiload.exe, dpmimem.dll, примеры lab3pr1.asm, lab3pr2.asm, lab3pr3.asm, lab3pr4.asm, lab3pr5.asm, l_3bnn.asm.

2. Создание и редактирование исходного текста программы, компиляция и

выполнение программы. 2.1. Демонстрационные примеры приведены в прил.1 (примеры П.1.1–

П.1.1.5). Используются преподавателем при проведении работы в компьютерном классе и могут использоваться студентами при самостоятельном изучении.

2.2. Включение ПК, запуск операционной системы Windows 95, Windows 98, Windows XP или Windows 2000 (не применять Windows Millenium).

2.3. Вызов оболочки (пакета) Far и открытие папки C:\Assembler\u_m_lab3. 2.4. Ассемблирование программы lab3pr1.asm, т.е. получение объектного

модуля lab3pr1.obj (в командной строке набрать и выполнить команду tasm lab3pr1.asm); компоновка (в командной строке набрать и выполнить команду tlink /tdc lab3pr1.obj) и выполнение (исполнение) полученной программы lab3pr1.com.

2.5. Проверка правильности решения контрольных примеров. Таблица П.4.1

№ п/п b1 b2 w1 w2 d1 d2 1 1 1 1 1 1 1 2 10 10 10 10 10 10 3 100 100 1 000 1 000 100 000 100 000 4 200 200 40 000 40 000 2 000 000 000 2 000 000 000

2.6. Ассемблирование программы, компоновка и выполнение программы l_3bnn.asm (прил. 2). Проверка правильности решения контрольных примеров:

Page 93: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

93

Таблица П.4.2

№ п/п

№ фор- мулы

b1 b2 b3 w1 w2 d1 Флаг cf

1 1 1 1 1 1 1 1 2 1 10 10 10 100 100 1 000 3 1 200 200 200 50 00

0 50

000 200 000 000

4 3 1 5 3 32768 6 4 2 147 483 648 7 4 131 072 8 5 16 9 5 128

10 1 0 11 0 1

2.7. Ассемблирование программы, компоновка и выполнение программы l_3bnn.asm (прил. 3). Проверка правильности решения контрольных примеров:

3. Редактирование, компиляция и выполнение демонстрационных

примеров. 3.1. В папке C:\assebler\u_m_lab3 создать файл lab3_fio.asm, где fio –

инициалы выполняющего работу (первые буквы фамилии, имени и отчества – латинскими буквами).

3.2. Проверить функцию создания файла на одном из имеющихся на компьютере дисков, выполняя пример 3.4.

3.3. Проверить функцию чтения файла, выполняя пример 3.5. 4. Подготовка к выполнению индивидуального задания.

4.1. На основе файлов lb2_1bnn.asm и lb2_2bnn.asm (прил. 2.2 в учеб.пособ., ч.2) создать файл l_3_fio.asm. Для этого:

скопировать файл lb2_1bnn.asm в папку C:\assebler\u_m_lab3; переименовать его в файл l_3_fio.asm; вставить после его последней строки содержимое файла lb2_2bnn.asm; преобразовать текст полученного файла l_3_fio.asm в COM-файл

(убрать сегмент стека, соединить два сегмента кода в один, переделать сегмент данных в блок (набор) данных, размещенных в сегменте кода, и т.д. см. подразд. 4.1).

4.2. Добавить проверку номера выполняемой формулы для вызова процедур, реализующих сдвиги.

4.3. Добавить заготовки процедур, реализующих сдвиги (начало, окончание процедур и команду ret в каждой из них).

5. Ассемблирование программы и получение загрузочного файла.

Page 94: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

94

5.1. Для ассемблирования программы необходимо файлы с программой (то есть файл l_3_fio.asm) поместить в каталог с ассемблером (то есть с файлом tasm.exe), набрать в командной строке команду

tasm.exe <имя файла>.asm /l и нажать клавишу Enter. Т.е. в нашем случае набрать и выполнить команду

tasm.exe l_3_fio.asm /l В результате будут получены файл с расширением .obj (полное его имя:

l_3_fio.obj) и файл с расширением .lst (полное его имя: l_3_fio. lst). Затем с помощью программы tlink.exe получить загрузочный модуль. Для

этого необходимо, чтобы файл tlink.exe был в каталоге с ассемблером. Набрать в командной строке и выполнить команду

tlink.exe l_3_fio.obj \tdc В результате будет получен файл l_3_fio.com. Запустите программу (для этого

наведите курсор на полученный файл и нажмите клавишу Enter).

Page 95: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

95

Приложение 5

Арифметические и логические операции в микропроцессорах МП8086 и МП80386

Сложение чисел без знака МП 8086 Вычисление d1+w1+b1+d2+w2+b2 mov ax, word ptr d1 mov dx, word ptr d1+2 31 16 15 2 1 0

d1

dx ax 15 2 1 0

w1

add ax, w1 adc dx, 0 d1+w1 31 16 15 2 1 0

рег. dx:ax dx ax

7 1 0

b1

mov bx,0 0 …...…….0

mov bl,b1 15 8 7 1 0

рег. bx 0 0 0 b1

add ax, bx adc dx, 0 d1+w1+b1 31 16 15 2 1 0

рег. dx:ax dx ax

31 16 15 2 1 0

d2 add ax, word ptr d2 adс dx, word ptr d2+2 d1+w1+b1+d2 31 16 15 2 1 0

рег. dx:ax dx ax 15 2 1 0

Page 96: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

96

w2

add ax, w2 adc dx, 0 d1+w1+b1+d2+w2 31 16 15 2 1 0

рег. dx:ax dx ax

7 1 0

b2 mov bx,0 0…………. … ...…….0

mov bl,b2 15 8 7 1 0

рег. bx 0 0 0 b2

add ax, bx adc dx, 0 d1+w1+b1+d2+w2+b2 31 16 15 2 1 0

рег. dx:ax dx ax

Занесение результата в ячейку памяти rezult (определена как четверное слово) mov word ptr rezult,ax mov word ptr rezult+2,dx mov word ptr rezult+4,0 mov word ptr rezult+6,0

d1+w1+b1+d2+w2+b2 rezult

rezult+2 rezult 31 16 15 2 1 0 rezult+6 rezult+4 63 46 47 33 32

Page 97: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

97

Сложение чисел без знака МП 80386 Вычисление d1+w1+b1+d2+w2+b2 mov ecx, d1 31 16 15 2 1 0

d1 ecx 15 2 1 0

w1 mov eax, 0

mov ax, w1 ax 31 16 15 2 1 0

рег. eax (w1) 0 0 0 0 0 w1

eax add ecx,eax d1+w1 31 16 15 2 1 0

рег. ecx ecx

7 1 0

b1 mov eax,0 31 16 15 8 7 1 0

рег. eax 0 0 0 0 0 0 0 0 0 0 0 mov al,b1 31 16 15 8 7 1 0

рег. eax 0 0 0 0 0 0 0 0 b1

eax add ecx, eax d1+w1+b1 31 16 15 2 1 0

рег. ecx ecx

31 16 15 2 1 0

d2 d2 add ecx, d2 d1+w1+b1+d2 31 16 15 2 1 0

рег. ecx ecx 15 2 1 0

w2

mov eax, 0

Page 98: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

98

mov ax, w2 31 16 15 2 1 0

рег. eax (w2) 0 0 0 w2 eax add ecx, eax d1+w1+b1+d2+w2 31 16 15 2 1 0

рег. ecx ecx 7 1 0

b2 mov eax,0 mov al,b2 31 16 15 7 2 1 0

рег. eax b2

eax add ecx, eax d1+w1+b1+d2+w2+b2 31 16 15 2 1 0

рег. ecx ecx

Занесение результата в ячейку памяти rezult (определена как четверное слово) mov dword ptr rezult,ecx mov dword ptr rezult+4,0 d1+w1+b1+d2+w2+b2

rezult rezult+2 rezult

31 16 15 2 1 0 rezult+6 rezult+4 63 46 47 33 32

Page 99: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

99

Вычитание чисел без знака МП 8086

Вычисление d1-w1-b1-d2-w2-b2 mov cx, word ptr d1 mov dx, word ptr d1+2 31 16 15 2 1 0

d1

dx cx 15 2 1 0

w1

sub cx, w1 sbc dx, 0 d1-w1 31 16 15 2 1 0

рег. dx:cx dx cx

7 1 0

b1 mov al,b1 cbw 15 8 7 1 0

рег. ax 0 0 0 b1

sub cx ax sbb dx, 0 d1-w1-b1 31 16 15 2 1 0

рег. dx:cx

dx cx

31 16 15 2 1 0

d2 sub cx, word ptr d2 sbb dx, word ptr d2+2 d1-w1-b1-d2 31 16 15 2 1 0

рег. dx:cx dx cx 15 2 1 0

W2

Page 100: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

100

sub cx, w2 sbb dx, 0 d1-w1-b1-d2-w2 31 16 15 2 1 0

рег. dx:cx dx cx

7 1 0

b2 mov al,b2 cbw 15 8 7 1 0

рег. ax 0 0 0 b2

sub cx, ax sbb dx, 0 d1-w1-b1-d1-w2-b2 31 16 15 2 1 0

рег. dx:cx dx cx

Занесение результата в ячейку памяти rezult (определена как четверное слово)

mov word ptr rezult,cx mov word ptr rezult+2,dx mov word ptr rezult+4,0

mov word ptr rezult+6,0 d1-w1-b1-d1-w2-b2

rezult rezult+2 rezult 31 16 15 2 1 0 rezult+6 rezult+4 63 46 47 33 32

Page 101: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

101

Вычитание чисел без знака МП 80386

Вычисление d1-w1-b1-d2-w2-b2 mov ecx, d1 31 16 15 2 1 0

d1 ecx 15 2 1 0

w1 mov eax, 0

mov ax, w1 ax 31 16 15 2 1 0

рег.eax (w1) 0 0 0 0 0 w1

eax sub ecx,eax d1-w1 31 16 15 2 1 0

рег. ecx ecx

7 1 0

b1 mov eax,0 mov al,b1 31 16 15 2 1 0

рег. eax 0 0 0 0 0 b1 eax sub ecx, eax d1-w1-b1 31 16 15 2 1 0

рег. ecx ecx

31 16 15 2 1 0

d2 sub ecx, d2 d1-w1-b1-d2 31 16 15 2 1 0

рег. ecx ecx 15 2 1 0

w2

mov eax, 0 mov ax, w2 31 16 15 2 1 0

Page 102: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

102

рег.eax (w2) 0 0 0 w2 eax sub ecx, eax d1-w1-b1-d2-w2 31 16 15 2 1 0

рег. ecx ecx 7 1 0

b2 mov eax,0 mov al,b2 31 16 15 7 2 1 0

рег. eax 0 0 0 0 0 0 b2

eax sub ecx, eax d1-w1-b1-d2-w2-b2 31 16 15 2 1 0

рег. ecx ecx

Занесение результата в ячейку памяти rezult (определена как четверное слово)

mov dword ptr rezult,ecx mov dword ptr rezult+4,0 d1-w1-b1-d2-w2-b2

rezult rezult+2 rezult

31 16 15 2 1 0 rezult+6 rezult+4 63 46 47 33 32

Page 103: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

103

Умножение чисел без знака МП 8086

Вычисление b1*b2*w1*d1 mov al,b1 mul b2 15 2 1 0

ax

cx mul w1 15 2 1 0

w1

b1*b2*w1 31 16 15 2 1 0

рег. dx:ax dx ax

b1 см. ПИТЕР АБЕЛЬ (умножение двойных слов)

рег. ax 31 16 15 2 1 0

Page 104: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

104

Умножение чисел без знака МП 80386

Вычисление b1*b2*w1*d1 mov al,b1 mul b2 b1*b2 15 2 1 0

ax

cx mul w1 15 2 1 0

w1

b1*b2*w1 31 16 15 2 1 0

рег. еax eax

d1 b1*b2*w1*d1 mul d1

результат 63 486 47 32

e d x рег.edx:eax 31 16 15 2 1 0

e a x

Page 105: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

105

Логическое ИЛИ (поразрядное) МП 8086

Вычисление d1 or w1 or b1 or d2 or w2 or b2 mov cx, word ptr d1 mov dx, word ptr d1+2 31 16 15 2 1 0

d1 dx cx 15 2 1 0

w1

or cx, w1 d1 or w1 31 16 15 2 1 0

рег. dx:cx dx cx

7 1 0

b1 or cl,b1 d1 or w1 or b1 31 16 15 2 1 0

рег. dx:cx dx cx

31 16 15 2 1 0

d2 or cx, word ptr d2 or dx, word ptr d2+2 d1 or w1 or b1 or d2 31 16 15 2 1 0

рег. dx:cx dx cx

15 2 1 0 w2

or cx, w2 d1 or w1 or b1 or d2 or w2 31 16 15 2 1 0

рег. dx:cx dx cx 7 1 0

b2 or cl,b2

Page 106: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

106

d1 or w1 or b1 or d2 or w2 or b2 31 16 15 2 1 0

рег. dx:cx dx cx

Занесение результата в ячейку памяти rezult (определена как четверное слово)

mov word ptr rezult,cx mov word ptr rezult+2,dx mov word ptr rezult+4,0 mov word ptr rezult+6,0 d1 or w1 or b1 or d2 or w2 or b2

rezult rezult+2 rezult 31 16 15 2 1 0 rezult+6 rezult+4 63 46 47 33 32

Page 107: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

107

Логическое ИЛИ (поразрядное) МП 80386

Вычисление d1 or w1 or b1 or d2 or w2 or b2 mov ecx, d1 31 16 15 2 1 0

d1 ecx 15 2 1 0

w1

or cx, w1 d1 or w1 31 16 15 2 1 0

рег. ecx ecx

7 1 0

b1 or cl,b1 d1 or w1 or b1 31 16 15 2 1 0

рег. ecx ecx

31 16 15 2 1 0

d2

or ecx, d2 d1 or w1 or b1 or d2 31 16 15 2 1 0

рег. ecx ecx 15 2 1 0

w2

or cx, w2 d1 or w1 or b1 or d2 or w2 31 16 15 2 1 0

рег. ecx ecx 7 1 0

b2 or cl,b2 d1 or w1 or b1 or d2 or w2 or b2

Page 108: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

108

31 16 15 2 1 0 рег. ecx

ecx

Занесение результата в ячейку памяти rezult (определена как четверное слово) mov dword ptr rezult,ecx mov dword ptr rezult+4,0 d1 or w1 or b1 or d2 or w2 or b2

rezult rezult+2 rezult 31 16 15 2 1 0 rezult+6 rezult+4 63 46 47 33 32

Page 109: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

109

Логическое И (поразрядное) МП 8086

Вычисление d1 and w1 and b1 and d2 and w2 and b2 mov cx, word ptr d1 mov dx, word ptr d1+2 31 16 15 2 1 0

d1 dx cx 15 2 1 0

w1

and cx, w1 d1 and w1 15 2 1 0

рег. cx cx

7 1 0

b1 and cl,b1 d1 and w1 and b1 7 1 0

рег. cl cl

31 16 15 2 1 0

d2 and cl, byte ptr d2 d1 and w1 and b1 and d2 7 1 0

рег. cl cl

15 2 1 0

w2

and cl, byte ptr w2 d1 and w1 and b1 and d2 and w2 7 1 0

рег. cl cl 7 1 0

b2

Page 110: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

110

and cl,b2 d1 and w1 and b1 and d2 and w2 7 1 0

рег. cl cl

Занесение результата в ячейку памяти rezult (определена как четверное слово)

mov byte ptr rezult,cl mov byte ptr rezult+1,0 mov word ptr rezult+2,0 mov word ptr rezult+4,0

mov word ptr rezult+6,0 d1 and w1 and b1 and d2 and w2 and b2

rezult rezult+2 rezult 31 16 15 2 1 0 0 0 0 0 0 rezult+6 rezult+4 63 46 47 33 32 0 0 0 0

Page 111: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

111

Логическое И (поразрядное) МП 80386 Вычисление d1 and w1 and b1 and d2 and w2 and b2 mov ecx, d1 31 16 15 2 1 0

d1 ecx 15 2 1 0

w1

and cx,w1 d1 and w1 15 2 1 0

рег. cx

7 1 0

b1 and cl,b1 d1 and w1 and b1 7 1 0

рег. cl cl

31 16 15 2 1 0

d2 and cl, byte ptr d2 d1 and w1 and b1 and d2 7 1 0

рег. cl cl

15 2 1 0

w2

and cl, byte ptr w2 d1 and w1 and b1 and d2 and w2

7 1 0

b2 and cl,b2

Page 112: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

112

d1 and w1 and b1 and d2 and w2 7 1 0

рег. cl cl

Занесение результата в ячейку памяти rezult (определена как четверное слово) mov byte ptr rezult,cl mov byte ptr rezult+1,0 mov word ptr rezult+2,0 mov dword ptr rezult+4,0 d1 and w1 and b1 and d2 and w2 and b2

rezult rezult+2 rezult 31 16 15 8 7 2 1 0 rezult+6 rezult+4 63 46 47 33 32

Page 113: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

113

Приложение 6 Арифметические и логические операции в микропроцессорах

МП8086 и МП80386 над числами со знаком Сложение чисел со знаком МП 8086 Вычисление d1+w1+b1+d2+w2+b2 mov cx, word ptr d1 mov dx, word ptr d1+2 31 16 15 2 1 0

d1 зн

dx cx 15 2 1 0

w1 зн w1

mov ax,w1 15 2 1 0

рег. ax зн w1

mov bx,0 ax jns met1 mov bx,FFFFh m et1: add cx, w1 adc dx, 0 31 16 15 0

знак зн w1

bx ax d1+w1 31 16 15 2 1 0

рег. dx:cx зн dx cx 7 1 0

b1 зн mov al,b1 cbw 15 8 7 1 0

рег. ax знак зн b1

mov bx,0 jns met2 mov bx,FFFFh 31 16 15 8 7 1 0

рег. bx:ax знак знак зн b1

bx ax met 2: add cx, ax

adc dx, bx d1+w1+b1 31 16 15 2 1 0

рег. dx:cx зн dx cx

Page 114: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

114

31 16 15 2 1 0 d2 зн

add cx, word ptr d2 adс dx, word ptr d2+2 d1+w1+b1+d2 31 16 15 2 1 0

рег. dx:сx зн dx сx 15 2 1 0

w2 зн w2 add сx, w2 adc dx, 0 d1+w1+b1+d2+w2 31 16 15 2 1 0

рег. dx:сx зн dx сx 7 1 0

b2 зн mov al,b2 cbw 15 8 7 1 0

рег. ax знак зн b2 mov bx,0 jns met3 mov bx,FFFFh 31 16 15 8 7 1 0

рег. bx:ax знак знак зн b1 bx ax met3: add cx, ax adc dx, bx d1+w1+b1+d2+w2+b2 31 16 15 2 1 0

рег. dx:ax зн dx ax

Занесение результата в ячейку памяти rezult (определена как четверное слово) mov word ptr rezult,ax mov word ptr rezult+2,dx d1+w1+b1+d2+w2+b2

rezult rezult+2 rezult 31 16 15 2 1 0 зн

Page 115: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

115

Сложение чисел со знаком МП 80386 Вычисление d1+w1+b1+d2+w2+b2 mov ecx, d1 31 16 15 2 1 0

d1 зн ecx 15 2 1 0

w1 зн w1

mov ax, w1 ax cwde 31 16 15 2 1 0

рег.eax (w1) з н а к зн w1

eax add ecx,eax d1+w1 31 16 15 2 1 0

рег. ecx зн ecx

7 1 0

b1 зн b1 mov al,b1 cbw 15 8 7 2 1 0

рег. ax (b1) з н а к зн b1 ax cwde 31 16 15 8 7 1 0

рег. eax (b1) з н а к з н а к зн b1 eax add ecx, eax d1+w1+b1 31 16 15 2 1 0

рег. ecx зн ecx 31 16 15 2 1 0

d2 зн d2 add ecx, d2 d1+w1+b1+d2 31 16 15 2 1 0

рег. ecx зн ecx 15 2 1 0

w2 зн w2

mov ax, w2

Page 116: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

116

cwde 31 16 15 2 1 0

рег.eax (w2) з н а к зн w2 eax add ecx, eax d1+w1+b1+d2+w2 31 16 15 2 1 0

рег. ecx зн ecx 7 1 0

b2 зн b2 mov al,b2 cbw 15 8 7 2 1 0

рег. ax (b2) з н а к зн b2 ax cwde 31 16 15 8 7 1 0

рег. eax (b2) з н а к з н а к зн b2 eax add ecx, eax d1+w1+b1+d2+w2+b2 31 16 15 2 1 0

рег. ecx зн ecx

Занесение результата в ячейку памяти rezult (определена как четверное слово)

mov dword ptr rezult,ecx d1+w1+b1+d2+w2+b2

rezult rezult+2 rezult

31 16 15 2 1 0

Page 117: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

117

Вычитание чисел со знаком МП 8086

Вычисление d1-w1-b1-d2-w2-b2 mov cx, word ptr d1 mov dx, word ptr d1+2 31 16 15 2 1 0

d1 зн

dx cx 15 2 1 0

w1 зн w1

mov ax, w1 cwde 31 16 15 2 1 0

eax (w1) з н а к зн w1

eax sub ecx, eax d1-w1 31 16 15 2 1 0

рег. dx:cx зн dx cx

7 1 0

b1 mov al,b1 зн b1 cbw 15 8 7 2 1 0

рег. ax з н а к зн b1

ax cwde 31 16 15 8 7 1 0

рег. eax (b1) з н а к з н а к зн b1 eax sub ecx, eax d1-w1-b1 31 16 15 2 1 0

рег. ecx зн

ecx 31 16 15 2 1 0

d2 sub ecx, d2 d1-w1-b1-d2 31 16 15 2 1 0

рег. ecx зн ecx

Page 118: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

118

15 2 1 0

w2 зн w2

mov ax, w2 cwde 31 16 15 2

рег. eax (w2) з н а к зн w2

eax sub ecx, eax d1-w1-b1-d2-w2 31 16 15 2 1 0

рег. ecx зн Ecx 7 1 0

b2 mov al,b2 cbw 15 8 7 1 0

рег. ax 0 0 0 b2

sub cx, ax sbb dx, 0 d1-w1-b1-d1-w2-b2 31 16 15 2 1 0

рег. dx:cx dx cx

Занесение результата в ячейку памяти rezult (определена как четверное слово)

mov word ptr rezult,cx mov word ptr rezult+2,dx mov word ptr rezult+4,0

mov word ptr rezult+6,0 d1-w1-b1-d1-w2-b2

rezult rezult+2 rezult 31 16 15 2 1 0 rezult+6 rezult+4 63 46 47 33 32

Page 119: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

119

Вычитание чисел со знаком МП 80386

Вычисление d1-w1-b1-d2-w2-b2 mov ecx, d1 31 16 15 2 1 0

d1 ecx 15 2 1 0

w1 mov eax, 0

mov ax, w1 ax 31 16 15 2 1 0

рег. eax (w1) 0 0 0 0 0 w1

eax sub ecx,eax d1-w1 31 16 15 2 1 0

рег. ecx ecx

7 1 0

b1 mov eax,0 mov al,b1 31 16 15 2 1 0

рег. eax 0 0 0 0 0 b1 eax sub ecx, eax d1-w1-b1 31 16 15 2 1 0

рег. ecx ecx

31 16 15 2 1 0

d2 sub ecx, d2 d1-w1-b1-d2 31 16 15 2 1 0

рег. ecx ecx 15 2 1 0

w2

mov eax, 0 mov ax, w2

Page 120: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

120

31 16 15 2 1 0

рег. eax (w2) 0 0 0 w2 eax sub ecx, eax d1-w1-b1-d2-w2 31 16 15 2 1 0

рег. ecx ecx 7 1 0

b2 mov eax,0 mov al,b2 31 16 15 7 2 1 0

рег. eax 0 0 0 0 0 0 b2

eax sub ecx, eax d1-w1-b1-d2-w2-b2 31 16 15 2 1 0

рег. ecx ecx

Занесение результата в ячейку памяти rezult (определена как четверное слово)

mov dword ptr rezult,ecx mov dword ptr rezult+4,0 d1-w1-b1-d2-w2-b2

rezult rezult+2 rezult

31 16 15 2 1 0 rezult+6 rezult+4 63 46 47 33 32

Page 121: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

121

Умножение чисел со знаком МП 8086

Вычисление b1*b2*w1*d1 mov al,b1 mul b2 15 2 1 0

рег. ax

аx mul w1 15 2 1 0

w1

b1*b2*w1 31 16 15 2 1 0

рег. dx:ax dx ax

b1 см. ПИТЕР АБЕЛЬ (умножение двойных слов)

рег. ax 31 16 15 2 1 0

Page 122: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

122

Умножение чисел со знаком МП 80386

Вычисление b1*b2*w1*d1 mov al,b1 mul b2 b1*b2 15 2 1 0

рег. ax

аx mul w1 15 2 1 0

w1

b1*b2*w1 31 16 15 2 1 0

рег. еax eax

d1 b1*b2*w1*d1 mul d1

результат 63 48647 32

e d x рег. edx:eax 31 16 15 2 1 0

e a x

Page 123: ЯЗЫКИ ПРОГРАММИРОВАНИЯbek.sibadi.org/fulltext/epd629.pdfМодуль lab3_ol.asm (один сегмент кода, содержит и данные – вверху

Учебное издание

Леонид Ефимович Олейник

ЯЗЫКИ ПРОГРАММИРОВАНИЯ

Учебное пособие

Часть 3

СДВИГОВЫЕ ОПЕРАЦИИ. ДАННЫЕ СО ЗНАКОМ И БЕЗ ЗНАКА. ВВОД-ВЫВОД НА ДИСК

Редактор Е.В.Садина

Подписано к печати Формат 60 x 90 1/16. Бумага писчая Гарнитура Таймс Оперативный способ печати Усл. п. л. 6.0, уч.-изд. Л. _,_ Тираж 100 экз. Заказ № Цена договорная

Издательство СибАДИ 644099, Омск, ул. П. Некрасова, 10

Отпечатано в ПЦ издательства СибАДИ