Ассемблер и программирование для IBM PC

       

Прерывания BIOS и DOS


------------------------------------------------------------

Прерывания BIOS и DOS

Цель: Описать функции, доступные через прерывания BIOS и DOS.

ВВЕДЕНИЕ ------------------------------------------------------------

Прерывание представляет собой операцию, которая приоста навливает выполнение программ для специальных системных действий. Необходимость прерываний обусловлено двумя основными причинами: преднамеренный запрос таких действий, как операции ввода-вывода на различные устройства и непредвиденные программные ошибки (например, переполнение при делении). Система BIOS (Basic Input/Output System) находится в ROM и управляет всеми прерываниями в системе. В предыдущих главах уже использовались некоторые прерывания для вывода на экран дисковых операций ввода-вывода и печати. В этой главе описаны различные BIOS- и DOS-прерывания, резидентные программы и команды IN и OUT.

ОБСЛУЖИВАНИЕ ПРЕРЫВАНИЙ ------------------------------------------------------------

В компьютерах IBM PC ROM находится по адресу FFFF0H. При включении компьютера процессор устанавливает состояние сброса, выполняет контроль четности, устанавливает в регистре CS значение FFFFH, а в регистре IP - нуль. Первая выполняемая команда поэтому находится по адресу FFFF:0 или FFFF0, что является точкой входа в BIOS. BIOS проверяет различные порты компьютера для определения и инициализации подключенных устрой ств. Затем BIOS создает в начале памяти (по адресу 0) таблицу прерываний, которая содержит адреса обработчиков прерываний, и выполняет две операции INT 11H (запрос списка присоединенного оборудования) и INT 12H (запрос размера физической памяти). Следующим шагом BIOS определяет имеется ли на диске или дискете операционная система DOS. Если обнаружена системная дискета, то BIOS выполняет прерывание INT 19H для доступа к первому сектору диска, содержащему блок начальной загрузки. Этот блок представляет собой программу, которая считывает системные файлы IBMBIO.COM, IBMDOS.COM и COMMAND.COM с диска в память. После этого память имеет следующее распределение:


Таблица векторов прерываний Данные BIOS IBMBIO.COM и IBMDOS.COM Резидентная часть COMMAND.COM
Ассемблер для IBM PC. Глава 23 56
Доступная память для прикладных программ Транзитная часть COMMAND.COM Конец RAM (ОЗУ) ROM BASIC ROM BIOS
Внешние устройства передают сигнал внимания через контакт INTR в процессор. Процессор реагирует на этот запрос, если флаг прерывания IF установлен в 1 (прерывание разрешено), и (в большинстве случаев) игнорирует запрос, если флаг IF установлен в 0 (прерывание запрещено). Операнд в команде прерывания, например, INT 12H, содержит тип прерывания, который идентифицирует запрос. Для каждого типа система содержит адрес в таблице векторов прерываний, начинающейся по адресу 0000. Так как в таблице имеется 256 четырехбайтовых элементов, то она занимает первые 1024 байта памяти от шест.0 до шест.3FF. Каждый элемент таблицы указывает на подпрограмму обработки указанного типа прерывания и содержит адрес кодового сегмента и смещение, которые при прерывании устанавливаются в регистры CS и IP соответственно. Список элементов таблицы векторов прерываний приведен на рис. 23.1. Прерывание заносит в стек содержимое флагового регистра, регистра CS и регистра IP. Например, для прерывания 12H (которое возвращает в регистре AX размер памяти) адрес элемента таблицы равен шест.0048 (шест.12 х 4 = шест.48). Операция выделяет четырехбайтовый элемент по адресу шест. 0048 и заносит два байта в регистр IP и два байта в регистр SS. Адрес, который получается в регистровой паре CS:IP, представляет собой адрес начала подпрограммы в области BIOS, которая получает управление. Возврат из этой подпрограммы осуществляется командой IRET (Interrupt Return), которая восстанавливает флаги и регистры CS и IP из стека и передает управление на команду, следующую за выполненной командой прерывания.
ПРЕРЫВАНИЯ BIOS ------------------------------------------------------------


В данном разделе представлены основные прерывания BIOS.
INT 05H (Печать экрана). Приводит к передаче содержимого экрана на печатающее устройство. INT 05H применяется для внутренних целей, т.е. из программ, клавиши Ctrl/PrtSc активизируют печать с клавиатуры. Данная операция маскирует прерывания и сохраняет позицию курсора.


------------------------------------------------------------
Адрес Функция прерыаний (шест) (шест) 0-3 0 Деление на нуль 4-7 1 Пошаговый режим (трассировка DEBUG)
Ассемблер для IBM PC. Глава 23 57
8-B 2 Немаскированное прерывание (NMI) C-F 3 Точка останова (используется в DEBUG) 10-13 4 Переполнение регистра 14-17 5 Печать экрана 18-1F 6,7 Зарезервировано 20-23 8 Сигнал от траймера 24-27 9 Сигнал от клавиатуры 28-37 A,B,C,D Используются в компьютерах AT 38-3B E Сигнал от дискетного дисковода 3C-3F F Используется для принтера 40-43 10 Управление дисплеем (см.гл. 8, 9, 10) 44-47 11 Запрос оборудования (см.гл.9) 48-4B 12 Запрос размера памяти (см.гл.2) 4C-4F 13 Дисковые операции ввода-вывода (см.гл.18) 50-53 14 Управление коммуникационным адаптером 54-57 15 Кассетные операции и спец. функции AT 58-5B 16 Ввод с клавиатуры (см.гл.9) 5C-5F 17 Вывод на принтер (см.гл.19) 60-63 18 Обращение к BASIC, встроенному в ROM 64-67 19 Перезапуск системы 68-6B 1A Запрос и установка времени и даты 6C-6F 1B Прерывание от клавиатуры 70-73 1C Прерывание от таймера 74-77 1D Адрес таблицы параметров дисплея 78-7B 1E Адрес таблицы параметров дисковода 7C-7F 1F Адрес таблицы графических символов 80-83 20 Нормальное завершение программы (DOS) 84-87 21 Обращение к функциям DOS 88-8B 22 Адрес обработки завершения задачи (DOS) 8C-8F 23 Адрес реакции по Ctrl/Break (DOS) 90-93 24 Адрес реакции на фатальную ошибку (DOS) 94-97 25 Абсолютное чтение с диска (DOS) 98-9B 26 Абсолютная запись на диск (DOS) 97-9F 27 Создание резидентной программы (DOS) AO-FF 28-3F Другие функции DOS 100-1FF 40-7F Зарезервировано 200-217 80-85 Зарезервировано для BASIC 218-3C3 86-F0 Используются BASIC-интерпретатором 3C4-3FF F1-FF Зарезервировано
Примечание: Прерывания 00-1F относятся к BIOS, прерывания 20-FF относятся к DOS и BASIC.
------------------------------------------------------------ Рис.23.1. Таблица адресов прерываний.
ПРЕРЫВАНИЯ BIOS ------------------------------------------------------------
В данном разделе приведены основные прерывания BIOS.


Ассемблер для IBM PC. Глава 23 58
INT 05H Печать экрана. Выполняет вывод содержимого экрана на печатающее устройство. Команда INT 05H выполняет данную операцию из программы, а нажатие клавишей Ctrl/PrtSc - с клавиатуры. Операция запрещает прерывания и сохраняет позицию курсора.
INT 10H Управление дисплеем. Обеспечивает экранные и кла виатурные операции, детельно описанные в главе 9.
INT 11H Запрос списка присоединенного оборудования. Опре деляет наличие различных устройств в системе, результирующее значение возвращает в регистре AX. При включении компьютера система выполняет эту операцию и сохраняет содержимое AX в памяти по адресу шест.410. Значения битов в регистре AX:
Бит Устройство 15,14 Число подключенных принтеров 13 Последовательный принтер 12 Игровой адаптер 11-9 Число последовательных адаптеров стыка RS232 7,6 Число дискетных дисководов, при бите 0=1: 00=1, 01=2, 10=3 и 11=4 5,4 Начальный видео режим: 00 = неиспользуется 01 = 40х25 плюс цвет 10 = 80х25 плюс цвет 11 = 80х25 черно-белый режим 1 Значение 1 говорит о наличии сопроцессора 0 Значение 1 говорит о наличии одного или более дисковых устройств и загрузка операционной системы должна осуществляться с диска
INT 12H Запрос размера физической памяти. Возвращает в регистре AX размер памяти в килобайтах, например, шест.200 соответствует памяти в 512 К. Данная операция полезна для выравнивания размера программы в соответствии с доступной памятью.
INT 13H Дисковые операции ввода-вывода. Обеспечивает опе рации ввода-вывода для дискет и винчестера, рассмотренные в главе 16.
INT 14H Управление коммуникационным адаптером. Обеспечи вает последовательный ввод-вывод через коммуникационный порт RS232. Регистр DX должен содержать номер (0 или 1) адаптера стыка RS232. Четыре типа операции, определяемые регистром AH, выполняют прием и передачу символов и возвращают в регистре AX байт состояния коммуникационного порта.
INT 15H Кассетные операции ввода-вывода и специальные функции для компьютеров AT. Обеспечивает операции ввода- вывода для касетного магнитофона, а также расширенные операции для компьютеров AT.


Ассемблер для IBM PC. Глава 23 59
INT 16H Ввод с клавиатуры. Обеспечивает три типа команд ввода с клавиатуры, подробно описанные в главе 9.
INT 17H Вывод на принтер. Обеспечивает вывод данных на пе чатающее устройство. Подробно рассмотрено в главе 19.
INT 18H Обращение к BASIC, встроенному в ROM. Вызывает BASIC-интерпретатор, находящийся в постоянной памяти ROM.
INT 19H Перезапуск системы. Данная операция при доступном диске считывает сектор 1 с дорожки 0 в область начальной загрузки в памяти (сегмент 0, смещение 7C00) и передает управление по этому адресу. Если дисковод не доступен, то операция передает управление через INT 18H в ROM BASIC. Данная операция не очищает экран и не инициализирует данные в ROM BASIC, поэтому ее можно использовать из программы.
INT 1AH Запрос и установка текущего времени и даты. Считы вает и записывает показание часов в соответствии со значением в регистре AH. Для определения продолжительности выполнения программы можно перед началом выполнения установить часы в 0, а после считать текущее время. Отсчет времени идет примерно 18,2 раза в секунду. Значение в регистре AH соответствует следующим операциям: AH=00 Запрос времени. В регистре CX устанавливается стар шая часть значения, а в регистре DX - младшая. Если после последнего запроса прошло 24 часа, то в регистре AL будет не нулевое значение. AH=01 Установка времени. Время устанавливается по регист рам CX (старшая часть значения) и DX (младшая часть значе ния). Коды 02 и 06 управляют временем и датой для AT.
INT 1FH Адрес таблицы графических символов. В графическом режиме имеется доступ к символам с кодами 128-255 в 1К таблице, содержащей по восемь байт на каждый символ. Прямой доступ в графическом режиме обеспечивается только к первым 128 ASCII-символам (от 0 до 127).
ПРЕРЫВАНИЯ DOS ------------------------------------------------------------
Во время своей работы BIOS использует два модуля DOS: IBMBIO.COM и IBMDOS.COM. Так как модули DOS обеспечивают большое количество разных дополнительных проверок, то операция DOS обычно проще в использовании и менее машинно зависимы, чем их BIOS аналоги. Модуль IBMBIO.COM обеспечивает интерфейс с BIOS низкого уровня. Эта программа выполняет управление вводом-выводом при чтении данных из внешних устройств в память и записи из памяти на внешние устройства.


Ассемблер для IBM PC. Глава 23 60
Модуль IBMDOS.COM содержит средства управления файлами и ряд сервисных функций, таких как блокирование и деблокиро вание записей. Когда пользовательская программа выдает запрос INT 21H, то в программу IBMDOS через регистры передается определенная информация. Затем программа IBMDOS транслирует эту информацию в один или несколько вызовов IBMBIO, которая в свою очередь вызывает BIOS. Указанные связи приведены на следующей схеме:
Пользовательский Высший Низший ROM Внешний уровень уровень уровень уровень +-----------+ +----------+ +----------+ |Программный| | DOS | | DOS | +----+ +----------+ |запрос в/в ||IBMDOS.COM||IBMBIO.COM||BIOS||Устройство| +-----------+ +----------+ +----------+ +----+ +----------+
Как показано выше, прерывания от шест.20 до шест.62 зарезервированы для операций DOS. Ниже приведены наиболее основные из них:
INT 20H Завершение программы. Запрос завершает выполнение программы и передает управление в DOS. Данный запрос обычно находится в основной процедуре.
INT 21H Запрос функций DOS. Основная операция DOS, вызыва ющая определенную функцию в соответствии с кодом в регистре AH. Назначение функций DOS описано в следующем разделе.
INT 22H Адрес подпрограммы обработки завершения задачи. (см.INT 24H).
INT 23H Адрес подпрограммы реакции на Ctrl/Break. (см.INT 24H).
INT 24H Адрес подпрограммы реакции на фатальную ошибку. В этом элементе и в двух предыдущих содержатся адреса, которые инициализируются системой в префиксе программного сегмента и, которые можно изменить для своих целей. Подробности приве дены в техническом описании DOS.
INT 25H Абсолютное чтение с диска. См.гл.17.
INT 26H Абсолютная запись на диск. См.гл.17.
INT 27H Завершение программы, оставляющее ее резедентной. Позволяет сохранить COM-программу в памяти. Подробно данная операция рассмотренна в последующем разделе "Резиденные прогарммы".
ФУНКЦИИ ПРЕРЫВАНИЯ DOS INT 21H ------------------------------------------------------------
Ассемблер для IBM PC. Глава 23 61


Ниже приведены базовые функции для прерывания DOS INT 21H. Код функции устанавливается в регистре AH:
00 Завершение программы (аналогично INT 20H). 01 Ввод символа с клавиатуры с эхом на экран. 02 Вывод символа на экран. 03 Ввод символа из асинх. коммуникационного канала. 04 Вывод символа на асинх. коммуникационный канал.
Ассемблер для IBM PC. Приложения 1
ПРИЛОЖЕНИЕ 1 -----------------------------------------------------------
Коды ASCII-символов
Ниже представлены первые 128 символов ASCII-кода. В руко водстве по языку BASIC приведены остальные 128 символов. На помним, что шест.20 представляет стандартный символ пробела.
ПРИЛОЖЕНИЕ 2 ------------------------------------------------------------
Шестнадцатерично-десятичные преобразования
В данном приложении представлены приемы преобразования между шестнадцатеричным и десятичным форматами. В первом разделе показан пример преобразования шест. A7B8 в десятичное 42936, а во втором - 42936 обратно в шест. A7B8.
Преобразование шестнадцатеричного формата в десятичный ---------------------------------------------------------
Для перевода шест. A7B8 в десятичное число необходимо последовательно, начиная с самой левой шест. цифры (A), умножать на 16 и складывать со следующей цифрой. Так как операции выполняются в десятичном формате, то шест. числа от A до F необходимо преобразовать в десятичные от 10 до 15.
Первая цифра: A (10) 10 Умножить на 16 *16 160 Прибавить следующую цифру, 7 7 167 Умножить на 16 *16 2672 Прибавить следующую цифру, B (11) 11 2683 Умножить на 16 *16 42928 Прибавить следующую цифру, 8 8 Десятичное значение 42936
Можно использовать также таблицу преобразования. Для шест. числа A7B8 представим правую цифру (8) как позицию 1, следующую влево цифру (B) как позицию 2, следующую цифру (7) как позицию 3 и самую левую цифру (A) как позицию 4. Из таблицы B-1 выберем значения для каждой шест. цифры:
Для позиции 1 (8), столбец 1 8 Для позиции 1 (8), столбец 1 176 Для позиции 1 (8), столбец 1 1792 Для позиции 1 (8), столбец 1 40960


Ассемблер для IBM PC. Приложения 2
Десятичное значение 42936
Преобразование десятичного формата в шестнадцатеричный --------------------------------------------------------- Для преобразования десятичного числа 42936 в шестнадцате ричный формат необходимо сначала исходное число 42936 разделить на 16; число, получившееся в остатке, (6) является младшей шестнадцатеричной цифрой. Затем полученное частное необходимо снова разделить на 16 и полученный остаток (11 или B) дает следующую влево шестнадцатеричную цифру. Продол жая таким образом деления до тех пор, пока в частном не получится 0, получим из остатков все необходимые шестнадцате ричные цифры.
Частное Остаток Шест. 42936 / 16 2683 8 8 (младшая цифра) 2683 / 16 167 11 B 167 / 16 10 7 7 10 / 16 0 10 A (старшая цифра)
Для преобразования чисел из десятичного формата в шестнад цатеричный можно также воспользоваться таблицей B-1. Для десятичного числа 42936 необходимо найти в таблице число равное или ближайшее меньшее исходному, и записать соот ветствующую шестнадцатеричную цифру и ее позицию. Затем следует вычесть найденное десятичное число из 42936 и с полу ченной разностью проделать проделать ту же операцию:
Дес. Шест. Исходное десятичное число 42936 Вычесть ближайшее меньшее 40960 A000 Разность 1976 Вычесть ближайшее меньшее 1792 700 Разность 184 Вычесть ближайшее меньшее 176 B0 Разность 8 8 Результирующее шест. число 7 A7B8
ПРИЛОЖЕНИЕ 3 ------------------------------------------------------------
Зарезервированные слова
Большинство из следующих зарезервированных слов при ис пользовании их для определении элементов данных могут привес ти к ошибкам ассемблирования (в ряде случаев - к весьма грубым):
Имена регистров
AH BH CH DH CS SS BP AL BL CL DL DS SI SP
Ассемблер для IBM PC. Приложения 3
AX BX CX DX ES DI
Мнемокоды
AAA DIV JLE JS OR SBB AAD ESC JMP JZ OUT SCAS AAM HLT JNA LAHF POP SHL AAS IDIV JNAE LDS POPF SHR ADC IMUL JNB LEA PUSH STC ADD IN JNBE LES PUSHF STD AND INC JNE LOCK RCL STI CALL INT JNG LODS RCR STOS CBW INTO JNGE LOOP REP SUB CLC IRET JNL LOOPE REPE TEST CLD JA JNLE LOOPNE REPNE WAIT CLI JAE JNO LOOPNZ REPNZ XCHG CMC JB JNP LOOPZ REPZ XLAT CMP JBE JNS MOV RET XOR CMPS JCXZ JNZ MOVS ROL CWD JE JO MUL ROR DAA JG JP NEG SAHF DAS JGE JPE NOP SAL DEC JL JPO NOT SAR


Директивы ассемблера
ASSUME END EXTRN IFNB LOCAL PURGE COMMENT ENDIF GROUP IFNDEF MACRO RECORD DB ENDM IF IF1 NAME REPT DD ENDP IFB IF2 ORG SEGMENT DQ ENDS IFDEF INCLUDE OUT STRUC DT EQU IFDIF IRP PAGE SUBTTL DW EVEN IFE IRPC PROC TITLE ELSE EXITM IFIDN LABEL PUBLIC
Прочие элементы языка
BYTE FAR LENGTH MOD PRT THIS COMMENT GE LINE NE SEG TYPE CON GT LT NEAR SHORT WIDTH DUP HIGH LOW NOTHING SIZE WORD EQ LE MASK OFFSET STACK
Ассемблер для IBM PC. Программы. 9
Двоич. Дес. Шест. Двоич. Дес. Шест.
0000 0 0 1000 8 8 0001 1 1 1001 9 9 0010 2 2 1010 10 A 0011 3 3 1011 11 B 0100 4 4 1100 12 C 0101 5 5 1101 13 D 0110 6 6 1110 14 E 0111 7 7 1111 15 F
+======================+ I D O S I I I +---------+ г - - - - - - - - - - -¶ + SS | Адрес +------->I Сегмент стека I | + - - - - + I I | DS | Адрес +----+ г - - - - - - - - - - -¶ | Переме- + - - - - + +-->I Сегмент данных I | щаемые CS | Адрес +---+ I I | в +---------+ | г - - - - - - - - - - -¶ | памяти +--->I Сегмент кода I | Сегментные I I | регистры г - - - - - - - - - - -¶ + I I I I I I I I +======================+ Память
Ассемблер для IBM PC. Программы. 10
| ОУ: Операционное | ШИ: Шинный интерфейс устройство | | +--------+--------+ | | AH | AL | | +--------+--------+ | | BH | BL | | +--------+--------+ | | CH | CL | | +--------+--------+ | Управление | DH | DL | | программами +--------+--------+ | +-----------------+ | SP | | | CS | +-----------------+ | +-----------------+ | BP | | | DS | +-----------------+ | +-----------------+ | SI | | | SS | +-----------------+ | +-----------------+ | DI | | | ES | +-----------------+ | +-------+---------+ Л | | | | | +-------+ V | V | Управ-| Шина ======================ь==============>| ление |<==> 8088 Л | Л | шиной | | | | +-------+ V | | +-----------------+ | +---+---+ | АЛУ: Арифметико-| | +---+ 1 | Очередь | логическое | | | +-------+ команд | устройство | | | | 2 | (Четыре байта) +->+ - - - - - - - - + | | +-------+ | | УУ: Устройство | | | | 3 | | | управления | | | +-------+ | + - - - - - - - - + | | | 4 | | | Флаговый регистр| | | +-------+ | +-----------------+ | | | | | | +-----------------+ | | +--+ Командный |<--+--+ | указатель | | +-----------------+ | |


Ассемблер для IBM PC. Программы. 11
Начальный адрес Память Дес. Шест. +-----------------------------+ 0K 00000 | RAM 256K основная оператив- | | ная память | +-----------------------------+ 256K 40000 | RAM 384K расширение опера- | | тивной памяти в канале I/O | +-----------------------------+ 640K A0000 | RAM 128K графический/экран- | | ный видео буфер | +-----------------------------+ 768K C0000 | ROM 192K дополнительная | | постоянная память | +-----------------------------+ 960K F0000 | ROM 64K основная системная | | постоянная память | +-----------------------------+
Ассемблер для IBM PC. Программы. 12
D>DEBUG -E CS:100 B8 23 01 05 25 00 -E CS:106 8B D8 03 D8 8B CB -E CS:10C 2B C8 2B C0 90 CB -R AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=13C6 ES=13C6 SS=13C6 CS=13C6 IP=0100 NV UP EI PL NZ NA PO NC 13C6:0100 B8230 MOV AX,0123 -T
AX=0123 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=13C6 ES=13C6 SS=13C6 CS=13C6 IP=0103 NV UP EI PL NZ NA PO NC 13C6:0103 052500 ADD AX,0025 -T
AX=0148 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=13C6 ES=13C6 SS=13C6 CS=13C6 IP=0106 NV UP EI PL NZ NA PE NC 13C6:0106 8BD8 MOV BX,AX -T
AX=0148 BX=0148 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=13C6 ES=13C6 SS=13C6 CS=13C6 IP=0108 NV UP EI PL NZ NA PO NC 13C6:0108 03D8 ADD BX,AX -T
AX=0148 BX=0290 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=13C6 ES=13C6 SS=13C6 CS=13C6 IP=010A NV UP EI PL NZ AC PO NC 13C6:010A 8BCB MOV CX,BX -T
AX=0148 BX=0290 CX=0290 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=13C6 ES=13C6 SS=13C6 CS=13C6 IP=010C NV UP EI PL NZ AC PO NC 13C6:010C 2BC8 SUB CX,AX -T
AX=0148 BX=0290 CX=0148 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=13C6 ES=13C6 SS=13C6 CS=13C6 IP=0100 NV UP EI PL NZ AC PO NC 13C6:010E 2BC0 SUB AX,AX -T
AX=0000 BX=0290 CX=0148 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=13C6 ES=13C6 SS=13C6 CS=13C6 IP=0110 NV UP EI PL ZR NA PO NC 13C6:0110 90 NOP -T
AX=0000 BX=0290 CX=0148 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=13C6 ES=13C6 SS=13C6 CS=13C6 IP=0111 NV UP EI PL ZR NA PO NC 13C6:0111 CB RETF -


Ассемблер для IBM PC. Программы. 13
-D CS:100 13C6:0100 B8 23 01 05 25 00 8B D8-03 D8 8B CB 2B C8 2B C0 .#..%.......+.+. 13C6:0110 90 CB 8D 46 14 50 51 52-FF 76 28 E8 74 00 8B E5 ...F.PQR.v(.t... 13C6:0120 B8 01 00 50 FF 76 32 FF-76 30 FF 76 2E FF 76 28 ...P.v2.v0.v..v( 13C6:0130 E8 88 15 8B E5 BF 36 18-12 FF 36 16 12 8B 76 28 ......6...6...v( 13C6:0140 FF 74 3A 89 46 06 E8 22-CE 8B E5 30 E4 3D 0A 00 .t:.F.."...0.=.. 13C6:0150 75 32 A1 16 12 2D 01 00-8B 1E 18 12 83 DB 00 53 u2...-.........S 13C6:0160 50 8B 76 28 FF 74 3A A3-16 12 89 1E 18 12 E8 FA P.v(.t:......... 13C6:0170 CD 8B E5 30 E4 3D 0D 00-74 0A 83 06 16 12 01 83 ...0.=..t....... -Q
Ассемблер для IBM PC. Программы. 14
D>DEBUG -E DS:23 01 25 00 00 -E DS:2A 2A 2A -E CS:100 A1 00 00 03 06 02 00 -E CS:107 A3 04 00 CB -D DS:0 13C6:0000 23 01 25 00 00 9A 2A 2A-2A F0 F5 02 2C 10 2E 03 #.%...***...,... 13C6:0010 2C 10 BD 02 2C 10 B1 0D-01 03 01 00 02 FF FF FF ,...,........... 13C6:0020 FF FF FF FF FF FF FF FF-FF FF FF FF EF 0F 64 00 ..............d. 13C6:0030 61 13 14 00 18 00 C7 13-FF FF FF FF 00 00 00 00 a............... 13C6:0040 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 13C6:0050 CD 21 CB 00 00 00 00 00-00 00 00 00 00 20 20 20 .!........... 13C6:0060 20 20 20 20 20 20 20 20 00 00 00 00 00 20 20 20 ..... 13C6:0070 20 20 20 20 20 20 20 20-00 00 00 00 00 00 00 00 ........ -R AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=13C6 ES=13C6 SS=13C6 CS=13C6 IP=0100 NV UP EI PL NZ NA PO NC 13C6:0100 A10000 MOV AX,[0000] DS:0000=0123 -T
AX=0123 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=13C6 ES=13C6 SS=13C6 CS=13C6 IP=0103 NV UP EI PL NZ NA PO NC 13C6:0103 03060200 ADD AX,[0002] DS:0002=0025 -T
AX=0148 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=13C6 ES=13C6 SS=13C6 CS=13C6 IP=0107 NV UP EI PL NZ NA PE NC 13C6:0107 A30400 MOV [0004],AX DS:0004=9A00 -T
AX=0148 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=13C6 ES=13C6 SS=13C6 CS=13C6 IP=0108 NV UP EI PL NZ NA PO NC 13C6:010A CB RETF -D DS:0 13C6:0000 23 01 25 00 00 9A 2A 2A-2A F0 F5 02 2C 10 2E 03 #.%...***...,... 13C6:0010 2C 10 BD 02 2C 10 B1 0D-01 03 01 00 02 FF FF FF ,...,........... 13C6:0020 FF FF FF FF FF FF FF FF-FF FF FF FF EF 0F 64 00 ..............d. 13C6:0030 61 13 14 00 18 00 C7 13-FF FF FF FF 00 00 00 00 a............... 13C6:0040 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 13C6:0050 CD 21 CB 00 00 00 00 00-00 00 00 00 00 20 20 20 .!........... 13C6:0060 20 20 20 20 20 20 20 20 00 00 00 00 00 20 20 20 ..... 13C6:0070 20 20 20 20 20 20 20 20-00 00 00 00 00 00 00 00 ........ -Q


CODESG SEGMENT PARA 'CODE' BEGIN PROC FAR 1. ASSUME CS:CODESG,DS:DATASG,SS:STACKG 2. PUSH DS ;Записать DS в стек 3. SUB AX,AX ;Установить ноль в AX PUSH AX ;Записать ноль в стек
Ассемблер для IBM PC. Программы. 15
4. MOV AX,DATASG ;Занести адрес MOV DS,AX ; DATASG в DS . . . 5. RET ;Возврат в DOS BEGIN ENDP CODESG ENDS END BEGIN
page 60,132 TITLE EXASM1 (EXE) Пример регистровых операций ;------------------------------------------------ STACKSG SEGMENT PARA SACK 'Stack' DB 12 DUP('STACKSEG') STACKSG ENDS ;------------------------------------------------ CODESG SEGMENT PARA 'Code' BEGIN PROC FAR ASSUME SS:STACKSG,CS:CODESG,DS:NOTHING PUSH DS ;Записать DS в стек SUB AX,AX ;Записать ноль PUSH AX ; в стек
MOV AX,0123H ;Записать шест.0123 в AX ADD AX,0025H ;Прибавить шест.25 к AX MOV BX,AX ;Переслать AX в BX ADD BX,AX ;Прибавить BX к AX MOV CX,BX ;Переслать BX в CX SUB CX,AX ;Вычесть AX из CX SUB AX,AX ;Очистить AX NOP RET ;Возврат в DOS BEGIN ENDP ;Конец процедуры
CODESG ENDS ;Конец сегмента END BEGIN ;Конец программы
Ассемблер для IBM PC. Программы. 16
1 page 60,132 2 TITLE EXASM1 (EXE) Пример регистровых операций 3 ;------------------------------------------------ 4 0000 STACKSG SEGMENT PARA SACK 'Stack' 5 0000 0C [ DB 12 DUP('STACKSEG') 6 53 54 41 43 7 4B 53 45 47 8 ] 9 10 0060 STACKSG ENDS 11 ;------------------------------------------------- 12 0000 CODESG SEGMENT PARA 'Code' 13 0000 BEGIN PROC FAR 14 ASSUME SS:STACKSG,CS:CODESG,DS:NOTHING 15 0000 1E PUSH DS ;Записать DS в стек 16 0001 2B C0 SUB AX,AX ;Записать ноль 17 0003 50 PUSH AX ; в стек 18 19 0004 B8 0123 MOV AX,0123H ;Записать шест.0123 в AX 20 0007 05 0025 ADD AX,0025H ;Прибавить шест.25 к AX 21 000A 8B D8 MOV BX,AX ;Переслать AX в BX 22 000C 03 D8 ADD BX,AX ;Прибавить BX к AX 23 000E 8B CB MOV CX,BX ;Переслать BX в CX 24 0010 2B C8 SUB CX,AX ;Вычесть AX из CX 25 0012 2B C0 SUB AX,AX ;Очистить AX 26 0014 90 NOP 27 0015 CB RET ;Возврат в DOS 28 0016 BEGIN ENDP ;Конец процедуры 29 30 0016 CODESG ENDS ;Конец сегмента 31 END BEGIN ;Конец программы -------------------------------------------------------------------------- Segments and Groups: N a m e Size Align Combine Class CODESG . . . . . . . . . . . . 0016 PARA NONE 'CODE' STACKSG. . . . . . . . . . . . 0060 PARA STACK 'STACK'


Symbols: N a m e Type Value Attr BEGIN. . . . . . . . . . . . . F PROC 0000 CODESG Length=0016 --------------------------------------------------------------------------
Ассемблер для IBM PC. Программы. 17
1 page 60,132 2 TITLE EXASM2 (EXE) Операции пересылки и сложения 3 ;--------------------------------------------------- 4 0000 STACKSG SEGMENT PARA SACK 'Stack' 5 0000 20 [ DB 32 DUP(?) 6 ???? 7 ] 8 9 0040 STACKSG ENDS 10 ;--------------------------------------------------- 11 0000 DATASG SEGMENT PARA 'Data' 12 0000 00FA FLDA DW 250 13 0002 007D FLDB DW 125 14 0004 ???? FLDC DW ? 15 0006 DATASG ENDS 16 ;--------------------------------------------------- 17 0000 CODESG SEGMENT PARA 'Code' 18 0000 BEGIN PROC FAR 19 ASSUME CS:CODESG,DS:DATASG,SS:STACKSG,ES:NOTHING 20 0000 1E PUSH DS ;Записать DS в стек 21 0001 2B C0 SUB AX,AX ;Записать в стек 22 0003 50 PUSH AX ; нулевой адрес 23 0004 B8 ---- R MOV AX,DATASG ;Поместить адрес DATASG 24 0007 8E D8 MOV DS,AX ; в регистр DS 25 26 0009 A1 0000 R MOV AX,FLDA ;Переслать 0250 в AX 27 000C 03 06 0002 R ADD AX,FLDB ;Прибавить 0125 к AX 28 0010 A3 0004 R MOV FLDC,AX ;Записать сумму в FLDC 29 0013 CB RET ;Вернуться в DOS 30 0014 BEGIN ENDP 31 0014 CODESG ENDS END BEGIN
---------------------------------------------------------------------------- Segments and Groups: N a m e Size Align Combine Class CODESG . . . . . . . . . . . . 0014 PARA NONE 'CODE' DATASG . . . . . . . . . . . . 0006 PARA NONE 'DATA' STACKSG. . . . . . . . . . . . 0040 PARA STACK 'STACK'
Symbols: N a m e Type Value Attr BEGIN. . . . . . . . . . . . . F PROC 0000 CODESG Length=0014 FLDA . . . . . . . . . . . . . L WORD 0000 DATASG FLDB . . . . . . . . . . . . . L WORD 0002 DATASG FLDC . . . . . . . . . . . . . L WORD 0004 DATASG ----------------------------------------------------------------------------
Ассемблер для IBM PC. Программы. 18
EXASM2 (EXE) Операции пересылки и сложения
Symbol Cross Reference (# is definition) Cref-1
BEGIN. . . . . . . . . . . . 18# 30 32


CODE . . . . . . . . . . . . 17 CODESG . . . . . . . . . . . 17# 19 31
DATA . . . . . . . . . . . . 11 DATASG . . . . . . . . . . . 11# 15 19 23
FLDA . . . . . . . . . . . . 12# 26 FLDB . . . . . . . . . . . . 13# 27 FLDC . . . . . . . . . . . . 14# 28
STACK. . . . . . . . . . . . 4 STACKSG. . . . . . . . . . . 4# 9 19
10 Symbols
Ассемблер для IBM PC. Программы. 19
page 60,132 TITLE EXDEF (EXE) Определение данных 0000 DATASG SEGMENT PARA 'Data'
; Определение байта - DB: ; ---------------------- 0000 ?? FLD1DB DB ? ;Неинициализирован 0001 50 65 72 73 6F 6E FLD2DB DB 'Personal Computer' ;Сим. строка 61 6C 20 43 6F 6D 70 75 74 65 72 0012 20 FLD3DB DB 32 ;Десятичная константа 0013 20 FLD4DB DB 20H ;Шест. константа 0014 59 FLD5DB DB 01011001B ;Двоичная константа 0015 01 4A 41 4E 02 46 FLD6DB DB 01,'JAN',02,'FEB',03,'MAR' ;Таблица 45 42 03 4D 41 52 0021 33 32 36 35 34 FLD7DB DB '32654' ;Символьные числа 0026 0A [ 00 ] FLD8DB DB 10 DUP(0) ;Десять нулей
; Определение слова - DW: ; ---------------------- 0030 FFF0 FLD1DW DW 0FFF0H ;Шест. константа 0032 0059 FLD2DW DW 01011001B ;Двоичная константа 0034 0021 R FLD3DW DW FLD7DB ;Адресная константа 0036 0003 0004 0007 FLD4DW DW 3,4,7,8,9 ;Пять констант 0008 0009 0040 05 [ 0000 ] FLD5DW DW 5 DUP(0) ;Пять нулей
; Определение двойного слова - DD: ; ------------------------------- 004A ???????? FLD1DD DD ? ;Неинициализировано 004E 43 50 00 00 FLD2DD DD 'PC' ;Символьная строка 0052 3C 7F 00 00 FLD3DD DD 32572 ;Десятичное значение 0056 11 00 00 00 FLD4DD DD FLD3DB - FLD2DB ;Разность адресов 005A 0E 00 00 00 31 00 FLD5DD DD 14,49 ;Две константы 00 00 ; Определение учетверенного слова - DQ: ; ------------------------------------ 0062 ???????????????? FLD1DQ DQ ? ;Неинициализировано 006A 47 4D 00 00 00 00 FLD2DQ DQ 04D47H ;Шест. константа 00 00 0072 3C 7F 00 00 00 00 FLD3DQ DQ 32572 ;Десятич. константа 00 00 ; Определение десяти байт - DT: ; ---------------------------- 007A ?????????????????? FLD1DT DT ? ;Неинициализировано ?? 0084 43 50 00 00 00 00 FLD2DT DT 'PC' ;Символьная строка 00 00 00 00


008E DATASG ENDS END -----------------------------------------------------------------------------
Ассемблер для IBM PC. Программы. 20
Segments and Groups: N a m e Size Align Combine Class DATASG . . . . . . . . . . . . 008E PARA NONE 'DATA'
Symbols: N a m e Type Value Attr FLD1DB . . . . . . . . . . . . L BYTE 0000 DATASG FLD1DD . . . . . . . . . . . . L DWORD 004A DATASG FLD1DQ . . . . . . . . . . . . L QWORD 0062 DATASG FLD1DT . . . . . . . . . . . . L TBYTE 007A DATASG FLD1DW . . . . . . . . . . . . L WORD 0030 DATASG FLD2DB . . . . . . . . . . . . L BYTE 0001 DATASG FLD2DD . . . . . . . . . . . . L DWORD 004E DATASG FLD2DQ . . . . . . . . . . . . L QWORD 006A DATASG FLD2DT . . . . . . . . . . . . L TBYTE 0084 DATASG FLD2DW . . . . . . . . . . . . L WORD 0032 DATASG FLD3DB . . . . . . . . . . . . L BYTE 0012 DATASG FLD3DD . . . . . . . . . . . . L DWORD 0052 DATASG FLD3DQ . . . . . . . . . . . . L QWORD 0072 DATASG FLD3DW . . . . . . . . . . . . L WORD 0034 DATASG FLD4DB . . . . . . . . . . . . L BYTE 0013 DATASG FLD4DD . . . . . . . . . . . . L DWORD 0056 DATASG FLD4DW . . . . . . . . . . . . L WORD 0036 DATASG FLD5DB . . . . . . . . . . . . L BYTE 0014 DATASG FLD5DD . . . . . . . . . . . . L DWORD 005A DATASG FLD5DW . . . . . . . . . . . . L WORD 0040 DATASG Length =0005 FLD6DB . . . . . . . . . . . . L BYTE 0015 DATASG FLD7DB . . . . . . . . . . . . L BYTE 0021 DATASG FLD8DB . . . . . . . . . . . . L BYTE 0026 DATASG Length =000A -------------------------------------------------------------------------------
Ассемблер для IBM PC. Программы. 21
D:\ D>DEBUG D:EXDEF.EXE -D 1421:0000 00 50 65 72 73 6F 6E 61-6C 20 43 6F 6D 70 75 74 .Personal Comput 1421:0010 65 72 20 20 59 01 4A 41-4E 02 46 45 42 03 4D 41 er Y.JAN.FEB.MA 1421:0020 52 33 32 36 35 34 00 00-00 00 00 00 00 00 00 00 R32654.......... 1421:0030 F0 FF 59 00 21 00 03 00-04 00 07 00 08 00 09 00 ..Y.!........... 1421:0040 00 00 00 00 00 00 00 00-00 00 00 00 00 00 43 50 ..............CP 1421:0050 00 00 3C 7F 00 00 11 00-00 00 0E 00 00 00 31 00 ..<...........1. 1421:0060 00 00 00 00 00 00 00 00-00 00 47 4D 00 00 00 00 ..........GM.... 1421:0070 00 00 3C 7F 00 00 00 00-00 00 00 00 00 00 00 00 ..<............. -D 1421:0080 00 00 00 00 43 50 00 00-00 00 00 00 00 00 33 33 ....CP........33 1421:0090 3E 36 33 33 73 00 00 00-0A 0E 00 00 3E 63 63 30 >633s.......>cc0 1421:00A0 1C 06 63 63 3E 00 00 00-0A 0E 00 00 FF DB 99 18 ..cc>........... 1421:00B0 18 18 18 18 3C 00 00 00-0A 0E 00 00 63 63 63 63 ....<.......cccc 1421:00C0 63 63 63 63 3E 00 00 00-0A 0E 00 00 C3 C3 C3 C3 cccc>........... 1421:00D0 C3 C3 66 3C 18 00 00 00-0A 0E 00 00 C3 C3 C3 C3 ..f<............ 1421:00E0 DB DB FF 66 66 00 00 00-0A 0E 00 00 C3 C3 66 3C ...ff.........f< 1421:00F0 18 3C 66 C3 C3 00 00 00-0A 0E 00 00 C3 C3 C3 66 .<f............f -Q


Ассемблер для IBM PC. Программы. 22
page 60,132 TITLE EXIMM (EXE) Пример непосредственных операндов ; (Кодируется для ассемблирования, ; но не для выполнения) 0000 DATASG SEGMENT PARA 'Data' 0000 ?? FLD1 DB ? 0001 ???? FLD2 DW ? 0003 DATASG ENDS
0000 CODESG SEGMENT PARA 'Code' 0000 BEGIN PROC FAR ASSUME CS:CODESG,DS:DATASG
; Операции пересылки и сравнения: ; ------------------------------ 0000 BB 0113 MOV BX,275 ;Пересылка 0003 3C 19 CMP AL,H ;Сравнение
; Арифметические операции: ; ----------------------- 0005 14 05 ADC AL,5 ;Сложение с переносом 0007 80 C7 0C ADD BH,12 ;Сложение 000A 1C 05 SBB AL,5 ;Вычитание с заемом 000C 80 2E 000 R 05 SUB FLD1,5 ;Вычитание
; Ротация и сдвиг (только на 1 бит): ; --------------------------------- 0011 D0 D3 RCL BL,1 ;Ротация влево с переносом 0013 D0 DC RCR AH,1 ;Ротация вправо с переносом 0015 D1 06 0001 R ROL FID2,1 ;Ротация влево 0019 D0 C8 ROR AL,1 ;отация вправо 001B D1 E1 SAL CX,1 ;Сдвиг влево 001D D1 FB SAR BX,1 ;Арифм. сдвиг вправо 001F D0 2E 0000 R SHR FLD1,1 ;Сдвиг вправо
; Логические операции: ; ------------------- 0023 24 2C AND AL,00101100B ;AND (регистр) 0025 80 CF 2A OR BH,2AH ;OR (регистр) 0028 F6 C3 7A TEST BL,7AH ;TEST (регистр) 002B 80 36 0000 R 23 OR FLD1,23H ;XOR (память) 0030 BEGIN ENDP 0030 CODESG ENDS END
Ассемблер для IBM PC. Программы. 23
page 60,132 TITLE XCOM1 COM-программа для пересылки и сложения 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
page 60,132 TITLE EXJUMP (COM) Организация цикла с помощью JMP 0000 CODESG SEGMENT PARA 'Code' ASSUME CS:CODESG,DS:CODESG,SS: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 JMP A20 ;Переход на A20 0112 MAIN ENDP 0112 CODESG ENDS END MAIN
Ассемблер для IBM PC. Программы. 24
page 60,132 TITLE EXLOOP (COM) Организация цикла командой LOOP 0000 CODESG SEGMENT PARA 'Code' ASSUME CS:CODESG,DS:CODESG,SS:CODESG 0100 ORG 100H
0100 BEGIN PROC NEAR 0100 B8 0001 MOV AX,01 ;Инициализация AX, 0103 BB 0001 MOV BX,01 ; BX, 0106 BA 0001 MOV DX,01 ; и DX 0109 B9 000A MOV CX,10 ;Число циклов 010C A20: 010C 40 INC AX ;Прибавить 01 к AX 010D 03 D8 ADD BX,AX ;Прибавить AX к BX 010F D1 E2 SHL DX,1 ;Удвоить DX 0111 E2 F9 LOOP A20 ;Уменьшить CX и повторить ; цикл, если ненуль 0113 C3 RET ;Завершить работу 0114 BEGIN ENDP 0114 CODESG ENDS END BEGIN
+-------------------------+ | CODESG SEGMENT PARA | +-------------------------+ | BEGIN PROC FAR | | . | | . | | CALL B10 | | CALL C10 | | RET | | BEGIN ENDP | +-------------------------+ | B10 PROC NEAR | | . | | . | | RET | | B10 ENDP | +-------------------------+ | C10 PROC NEAR | | . | | . | | RET | | C10 ENDP | +-------------------------+ | CODESG ENDS | | END BEGIN | +-------------------------+
Ассемблер для IBM PC. Программы. 25
TITLE CALLPROC (EXE) Вызов процедур 0000 STACKSG SEGMENT PARA STACK 'Stack' 0000 20 [ ???? ] DW 32 DUP(?) 0040 STACKG ENDS
0000 CODESG SEGMENT PARA 'Code' 0000 BEGIN PROC FAR ASSUME CS:CODESG,SS:STACKSG 0000 1E PUSH DS 0001 2B C0 SUB AX,AX 0003 50 PUSH AX 0004 E8 0008 R CALL B10 ;Вызвать B10 ; ... 0007 CB RET ;Завершить программу 0008 BEGIN ENDP ;-------------------------------------- 0008 B10 PROC 0008 E8 000C R CALL C10 ;Вызвать C10 ; ... 000B C3 RET ;Вернуться в 000C B10 ENDP ; вызывающую программу ;---------------------------------------------- 000C C10 PROC ; ... 000C C3 RET ;Вернуться в 000D C10 ENDP ; вызывающую программу ;---------------------------------------------- 000D CODESG ENDS END BEGIN


Ассемблер для IBM PC. Программы. 26
page 65,132 TITLE EXMOVE (EXE) Операции расширенной пересылки ;------------------------------------------------------ STACKSG SEGMENT PARA STACK 'Stack' DW 32 DUP(?) STACKSG ENDS ;------------------------------------------------------ DATASG SEGMENT PARA 'Data' NAME1 DB 'ABCDEFGHI' NAME2 DB 'JKLMNOPQR' NAME3 DB 'STUVWXYZ*' DATASG ENDS ;------------------------------------------------------- CODESG SEGMENT PARA 'Code' BEGIN PROC FAR ASSUME CS:CODESG,DS:DATASG,SS:STACKSG,ES:DATASG PUSH DS SUB AX,AX PUSH AX MOV AX,DATASG MOV DS,AX MOV ES,AX CALL B10MOVE ;Вызвать JUMP подпрограмму CALL C10MOVE ;Вызвать CALL подпрограмму RET ;Завершить программу BEGIN ENDP
; Расширенная пересылка (JUMP-подпрограмма), ; использующая переход по условию: ; ----------------------------------------- B10MOVE PROC LEA SI,NAME1 ;Инициализация адресов LEA DI,NAME2 ; NAME1 и NAME2 MOV CX,09 ;Переслать 9 символов B20: MOV AL,[SI] ;Переслать из NAME1 MOV [DI],AL ;Переслать в NAME2 INC SI ;Следующий символ в NAME1 INC DI ;Следующая позиция в NAME2 DEC CX ;Уменьшить счетчик цикла JNZ B20 ;Счетчик > 0? Да - цикл RET ;Если счетчик = 0, то B10MOVE ENDP ; вернуться
; Расширенная пересылка (LOOP-подпрограмма), ; использующая команду LOOP: ; -----------------------------------------; C10MOVE PROC LEA SI,NAME2 ;Инициализация адресов LEA DI,NAME3 ; NAME2 и NAME3 MOV CX,09 ;Переслать 9 символов C20
Ассемблер для IBM PC. Программы. 27
MOV AL,[SI] ;Переслать из NAME2 MOV [DI],AL ;Переслать в NAME3 INC DI ;Следующий символ в NAME2 INC SI ;Следующая позиция в NAME3 LOOP C20 ;Уменьшить счетчик, ; если не ноль, то цикл RET ;Если счетчик = 0, то C10MOVE ENDP ; вернуться CODESG ENDS END BEGIN
TITLE CASE (COM) Перекодировка в заглавные буквы 0000 CODESG SEGMENT PARA 'CODE' ASSUME CS:CODESG,DS:CODESG,SS:CODESG 0001 ORG 100H 0001 EB 1C 90 BEGIN: JMP MAIN ; ------------------------------------------- 0003 43 68 61 6E 67 65 TITLEX DB 'Change to uppercase letters' 20 74 6F 20 75 70 70 65 72 63 61 73 65 20 6C 65 74 74 65 72 73 ; ------------------------------------------- 011E MAIN PROC NEAR 011E 8D 1E 0104 R LEA BX,TITLEX+1 ;Адрес первого символа 0122 B9 001F MOV CX,31 ;Число символов 0125 B20: 0125 8A 27 MOV AH,[BX] ;Символ из TITLEX 0127 80 FC 61 CMP AH,61H ;Это 012A 72 0A JB B30 ; прописная 012C 80 FC 7A CMP AH,7AH ; буква 012F 77 05 JA B30 ; ? 0131 80 E4 DF AND AH,11011111B ;Да - преобразовать 0134 88 27 MOV [BX],AH ;Записать в TITLEX 0136 B30: 0136 43 INC BX ;Следующий символ 0137 E2 EC LOOP B20 ;Повторить цикл 31 раз 0139 C3 RET 013A MAIN ENDP 013A CODESG ENDS END BEGIN


Ассемблер для IBM PC. Программы. 28
page 60,132 TITLE ALLASC (COM) Вывод на экран ASCII-символов 00-FF CODESC SEGMENT PARA 'Code' ASSUME CS:CODESG,DS:CODESG,SS:CODESG,ES:NOTHING ORG 100H BEGIN: JMP SHORT MAIN CTR DB 00,'S'
; Основная процедура: ; ------------------ MAIN PROC NEAR CALL B10CDR ;Очистить экран CALL C10SET ;Установить курсор CALL D10DISP ;Вывести символ на экран RET MAIN ENDP ; Очистка экрана: ; -------------- B10CLR PROC MOV AX,0600H MOV BH,07 MOV CX,0000 ;Левая верхняя позиция MOV DX,184FH ;Правая нижняя позиция INT 10H RET B10CLR ENDP ; Установка курсора в 00,00: ; ------------------------- C10SET PROC MOV AN,02 MOV BN,00 MOV DX,0000 INT 10H RET C10SET ENDP ; Вывод на экран ASCII символов: ; ----------------------------- D10DISP PROC MOV CX,256 ;256 итераций LEA DX,CTR ;Адрес счетчика D20 MOV AH,09 ;Функция вывода символа INT 21H INC CTR ;Увеличить счетчик LOOP D20 ;Уменьшить CX, ; цикл, если не ноль RET ;Вернуться D10DISP ENDP
CODESG ENDS END BEGIN
Ассемблер для IBM PC. Программы. 29
page 60,132 TITLE CTRNAME (EXE) Ввод имен и вывод в центр экрана ;-------------------------------------------------------- STSCKSG SEGMENT PARA STACK 'Stack' DW 32 DUP(?) STACKSG ENDS ;-------------------------------------------------------- DATASG SEGMENT PARA 'Data' NAMEPAR LABEL BYTE ;Имя списка параметров: MAXNLEN DB 20 ; макс.длина имени NAMELEN DB ? ; число введенных символов NAMEFLD DB 20 DUP(' '),'$' ; имя и ограничитель ; для вывода на экран PRIMPT DB 'Name? ', '$' DATASG ENDS ;-------------------------------------------------------- CODESG SEGMENT PARA 'Code" BEGIN PROC FAR ASSUME CS:CODESG,DS:DATASG,SS:STACKSG,ES:DATASC PUSH DS SUB AX,AX PUCH AX MOV AX,DATASC MOV DS,AX MOV ES,AX CALL Q10CLR ;Очистить экран A20LOOP: MOV DX,0000 ;Установить курсор в 00,00 CALL Q20CURS CALL B10PRMP ;Выдать текст запроса CALL D10INPT ;Ввести имя CALL Q10CLR ;Очистить экран CMP NAMELEN,00 ;Имя введено? JE A30 ; нет - выйти CALL E10CODE ;Установить звуковой сигнал ; и ограничитель '$' CALL F10CENT ;Центрирование и вывод JMP A20LOOP A30: RET ;Вернуться в DOS BEGIN ENDP ; Вывод текста запроса: ; -------------------- B10PRMP PROC NEAR MUV AN,09 ;Функция вывода на экран LEA DX,PROMPT INT 21H RET B10PRMP ENDP ; Ввод имени с клавиатуры: ; ----------------------- D10INPT PROC NEAR


Ассемблер для IBM PC. Программы. 30
MOV AN,0AN ;Функция ввода LEA DX,NAMEPAR INT 21H RET D10INPT ENDP ; Установка сигнала и ограничителя '$': ; ------------------------------------ E10CODE PROC NEAR MOV BN,00 ;Замена символа Return (0D) MOV BL,NAMELEN ; на зв.сигнал (07) MOV NAMEFLD[BX],07 MOV NAMEFLD[BX+1],'$' ;Установить ограничитель RET E10CODE ENDP ; Центрирование и вывод имени на экран: ; ------------------------------------ F10CENT PROC NEAR MOV DL,NAMELEN ;Определение столбца: SHR DL,1 ; разделить длину на 2, NEG DL ; поменять знак, ADD DL,40 ; прибавить 40 MOV DH,12 ;Центральная строка CALL Q20CURS ;Установить курсор MOV AN,09 LEA DX,NAMEFLD ;Вывести имя на экран INT 21H RET F10CENT ENDP ; Очистить экран: ; -------------- Q10CLR PROC NEAR MOV AX,0600H ;Функция прокрутки экрана MOV BH,30 ;Цвет (07 для ч/б) MOV CX,0000 ;От 00,00 MOV DX,184FH ;До 24,79 INT 10H ;Вызов BIOS RET Q10CLR ; Установка курсора (строка/столбец): ; ---------------------------------- Q20CURS PROC NEAR ;DX уже установлен MOV AH,02 ;Функция установки курсора MOV BH,00 ;Страница #0 INT 10H ;Вызов BIOS RET Q20CURS ENDP
CODESG ENDS END BEGIN
Ассемблер для IBM PC. Программы. 31
page 60,132 TITLE NMSCROLL (EXE) Инвертирование, мигание, прокрутка ; ------------------------------------------------------- STACKSG SEGMENT PARA STACK 'Stack' DW 32 DUP(?) STACKSG SEGMENT PARA STACK 'Stack' DW 32 DUP(?) STACKG ENDS ; ------------------------------------------------------- DATASG SEGMENT PARA 'Data' NAMEPAR LABEL BYTE ;Имя списка параметров: MAXNLEN DB 20 ; макс.длина имени ACTNLEN DB ? ; число введенных символов NAMEFLD DB 20 DUP(' ') ; имя
COL DB 00 COUNT DB ? PROMPT DB 'Name? ' ROW DB 00 DATASG ENDS ; ------------------------------------------------------- CODESG SEGMENT PARA 'Code' BEGIN PROC FAR ASSUME CS:CODESG,DS:DATASG,SS:STACKSG,ES:DATASG PUSH DS SUB AX,AX PUSH DS MOV AX,DATASG MOV ES,AX MOV AX,0600H CALL Q10CLR ;Очистить экран A20LOOP: MOV COL,00 ;Установить столбец 0 CALL Q20CURS CALL B10PRMP ;Выдать текст запроса CALL D10INPT ;Ввести имя с клавиатуры CMP ACTNLEN,00 ;Нет имени? (т.е. конец) JNE A30 MOV AX,0600H CALL Q10CLR ;Если да, то очистить экран, RET ; и завершить программу A30: CALL E10NAME ;Вывести имя на экран JMP A20LOOP BEGIN ENDP ; Вывод текста запроса: ; -------------------- B10PRMP PROC NEAR LEA SI,PROMPT ;Адрес текста MOV COUNT,05 B20: MOV BL,70H ;Видеоинверсия


Ассемблер для IBM PC. Программы. 32
CALL F10DISP ;Подпрограмма вывода INC SI ;Следующий символ в имени INC COL ;Следующий столбец CALL Q20CURS DEC COUNT ;Уменьшение счетчика JNZ B20 ;Повторить n раз RET B10PRMP ENDP ; вод имени с клавиатуры: ; ---------------------- D10INPT PROC NEAR MOV AN,0AH LEA DX,NAMEPAR INT 21H RET D10INPT ENDP ; Вывод имени с миганием и инверсией: ; ---------------------------------- E10NAME PROC NEAR LEA SI,NAMEFLD ;Адрес имени MOV COL,40 ;Установить столбец E20: CALL Q20CURS ;Установить курсор MOV BL,0FOH ;Мигание и инверсия CALL F10DISP ;Подпрограмма вывода INS SI ;Следующий символ в имени INS COL ;Следующий столбец на экране DES ACTNLEN ;Уменьшить счетчик длины JNZ E20 ;Циклить n раз CMP ROW,20 ;Последняя строка экрана? JAE E30 ; нет INC ROW RET E30: MOV AX,0601H ; да -- CALL Q10CLR ; очистить экран RET E10NAME ENDP ; Вывод символа на экран: ; ---------------------- F10DISP PROC NEAR ;BL (атрибут) уже установлен MOV AN,09 ;Функция вывода на экран MOV AL,[SI] ;Получить символ из имени MOV BH,00 ;Номер страницы MOV CX,01 ;Один символ INT 10H ;Вызов BIOS RET F10DISP ENDP ; Очистка экрана: ; -------------- Q10CLR PROC NEAR ;AX установлен при вызове MOV BH,07 ;Нормальный ч/б MOV CX 0000 MOV DX,184FH
Ассемблер для IBM PC. Программы. 33
INT 10H ;Вызов BIOS RET Q10CLR ENDP ; Установить курсор (строка/столбец): ; ---------------------------------- Q20CURS PROC NEAR MOV AN,02 MOV BH,00 MOV DH,ROW MOV DL,COL INT 10H RET Q20CURS ENDP CODESG ENDS END BEGIN
Расширенная функция Скэн-код
Alt/A до Alt/Z 1E - 2C F1 до F10 3B - 44 Home 47 Стрелка вверх 48 PgUp 49 Стрелка влево 4B Стрелка вправо 4D End 4F Стрелка вниз 50 PgDn 51 Ins 52 Del 53
Ассемблер для IBM PC. Программы. 34
TITLE GRAPHIX (COM) Пример цвета и графики CODESG SEGMENT PARA 'Code' ASSUME CS:CODESG,DS:CODESG,SS:CODESG ORG 100H
MAIN PROC NEAR MOV AN,00 ;Установка режима графики MOV AL,0DH ; для EGA (CGA=04)
MOV AH,0BH ;Установить палитру MOV BH,00 ;Фон MOV BL,02 ;Зеленый INT 10H
MOV BX,00 ;Начальные цвет, MOV CX,00 ; столбец MOV DX,00 ; и строка A50: MOV AH,0CH ;Функция вывода точки MOV AL,BL ;Установить цвет INT 10H ;BX, CX, и DX сохраняются INC CX ;Увеличить столбец CMP CX,320 ;Столбец 320? JNE A50 ; нет - цикл, MOV CX,00 ; да - сбросить столбец INS BL ;Изменить цвет INS DX ;Увеличить строку CMP DX,40 ;Строка 40? JNE A50 ; нет - цикл, RET ; да - завершить MAIN ENDP CODESG ENDS END MAIN


Ассемблер для IBM PC. Программы. 35
page 60,132 TITLE STRING (EXE) Проверка строковых операций ; --------------------------------------------------- STACKSG SEGMENT PARA STACK 'Stack' DW 32 DUP(?) STACKG ENDS ; --------------------------------------------------- DATASG SEGMENT PARA 'Data' NAME1 DB 'Assemblers' ;Элементы данных NAME2 DB 10 DUP(' ') NAME3 DB 10 DUP(' ') DATASG ENDS ; --------------------------------------------------- CODESG SEGMENT PARA 'Code' BEGIN PROC FAR ;Основная процедура ASSUME CS:CODESG,DS:DATASG,SS:STACKSG,ES:DATASG PUSH DS SUB AX,AX PUSH AX MOV AX,DATASG MOV DS,AX MOV ES,AX CALL C10MVSB ;Подпрограмма MVSB CALL D10MVSW ;Подпрограмма LODS CALL E10LODS ;Подпрограмма LODS CALL F10STOS ;Подпрограмма CMPS CALL H10SCAS ;Подпрограмма SCAS RET BEGIN ENDP ; Использование MOVSB: ; ------------------- C10MVSB PROC NEAR CLD LEA SI,NAME1 LEA D1,NAME2 MOV CX,10 ;Переслать 10 байтов REP MOVSB ; из NAME1 в NAME2 RET C10MVSB ENDP ; Использование MOVSW: ; ------------------- D10MVSW PROC NEAR CLD LEA SI,NAME2 LEA DI,NAME3 MOV CX,05 ;Переслать 5 слов REP MOVSW ; из NAME2 в NAME3 RET D10MVSW ENDP ; Использование LODSW: ; ------------------- E10LODS PROC NEAR
Ассемблер для IBM PC. Программы. 36
CLD LEA SI,NAME1 ;Загрузить первое слово LODSW ; из NAME1 в AX RET E10LODS ENDP ; Использование STOSW: ; ------------------- F10STOS PROC NEAR CLD LEA D1,NAME3 MOV CX,05 MOV AX,2020H ;Переслать пробелы REP STOSW ; в NAME3 RET F10STOS ENDP ; Использование CMPSB: ; ------------------- G10CMPS PROC NEAR CLD MOV CX,10 LEA SI,NAME1 LEA DI,NAME2 REPE CMPSB ;Сравнить NAME1 и NAME2 JNE G20 ;Не равны? MOV BH,01
G20: MOV CX,10 LEA SI,NAME2 LEA DI,NAME3 REPE CMPSB ;Сравнить NAME2 и NAME3 JE G30 ;Если равны, то выйти MOV BL,02 G30: RET G10CMPS ENDP
; Использование SCASB: ; ------------------- H10SCAS PROC NEAR CLD MOV CX,10 LEA DI,NAME1 MOV AL,'m' ;Поиск символа 'm' REPNE SCASB ; в NAME1 JNE H20 ;Если не найден - выйти MOV AH,03 H20: RET H10SCAS ENDP
CODES ENDS END BEGIN
Ассемблер для IBM PC. Программы. 37


page 60,132 TITLE EXRING (COM) Вывод имен, выровненных справа CODESG SEGMENT PARA 'Code' ASSUME CS:CODESG,DS:CODESG,SS:CODESG,ES:CODESG ORG 100H BEGIN: JMP SHORT MAIN ;-------------------------------------------------------- NAMEPAR LABEL BYTE ;Имя списка параметров MAXNLEN DB 31 ;Макс. длина ACTNLEN DB ? ;Число введенных символов NAMEFLD DB 31 DUP(' ') ;Имя
PROMPT DB 'Name?', '$' NAMEDSP DB 31 DUP(' '), 13, 10, '$' ROW DB 00 ;-------------------------------------------------------- MAIN PROC NEAR ;Основная процедура MOV AX,0600H CALL Q10SCR ;Очистить экран SUB DX,DX ;Установить курсор в 00,00 CALL Q20CURS A10LOOP: CALL B10INPT ;Ввести имя с клавиатуры TEST ACTNLEN,0FFH ;Нет имени? (т.е. конец) JZ A90 ; да - выйти CALL D10SCAS ;Найти звездочку CMP AL,'*' ;Найдена? JE A10LOOP ; да - обойти CALL E10RGHT ;Выровнять имя справа CALL A10LOOP A90: RET MAIN ENDP ; Вывод запроса для ввода имени: ; ----------------------------- B10INPT PROC MOV AH,09 LEA DX,PROMPT ;Выдать текст запроса INT 21H RET B10INPT ENDP ; Поиск звездочки в имени: ; ----------------------- D10SCAS PROC CLD MOV AL,'*' MOV CX,30 ;Длина сканирования - 30 LEA DI,NAMEFLD REPNE SCASB ;Звездочка найдена? JE D20 ; да - выйти, MOV AL,20H ; нет стереть * в AL D20: RET D10SCAS ENDP
Ассемблер для IBM PC. Программы. 38
; Выравнивание справа и вывод на экран: ; ------------------------------------ E10RGHT PROC STD SUB CH,CH MOV CL,ACTNLEN ;Длина в CX для REP LEA SI,NAMEFLD ;Вычислить самую правую ADD SI,CX ; позицию DEC SI ; введенного имени LEA DI,NAMEDSP+30 ;Правая поз. поля имени REP MOVSB ;Переслать справа налево MOV DH,ROW MOV DL,48 CALL Q20CURS ;Установить курсор MOV AH,09 LEA DX,NAMEDSP ;Выдать имя на экран INT 21H CMP ROW,20 ;Последняя строка экрана? JAE E20 ; нет - INC ROW ; увеличить строку, JMP E90 E20: MOV AX,0601H ; да - CALL Q10SCR ; прокрутить и MOV DH,ROW ; установить курсор MOV DL,00 CALL Q20CURS E90: RET E10RGHT ENDP ; Очистить область имени: ; ---------------------- F10CLNM PROC CLD MOV AX,2020H MOV CX,15 ;Очистить 15 слов LEA DI,NAMEDSP REP STOSW RET F10CLNM ENDP ; Прокрутка экрана: ; ---------------- Q10SCR PROC ;AX установлен при вызове MOV BH,30 ;Цвет ( 07 для ч/б) MOV CX,00 MOV DX,184FH INT 10H RET Q10SCR ENDP ; Установить курсор (строка/столбец): ; ---------------------------------- Q20CURS PROC ;DX установлен при вызове MOV AH,02 SUB BH,BH


Ассемблер для IBM PC. Программы. 39
INT 10H RET Q20CURS ENDP CODESG ENDS END BEGIN
Ассемблер для IBM PC. Программы. 84
TITLE EXDWMUL - Умножение двойных слов 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 ;Записать произведение 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 ;Сложить с предыдущим
Ассемблер для IBM PC. Программы. 85
ADC PRODUCT+6,DX ADC PRODUCT,00 ;Прибавить перенос MOV AX,MULTCND ;Слово-1 множимого MUL MULTPLR ; * слово-1 множителя ADD PRODUCT+2,AX ;Сложить с предыдущим ADC PRODUCT,DX RET F10XMUL ENDP ; Очистка области результата: ; ---------------------------------------- Z10XMUL PROC MOV PRODUCT,0000 MOV PRODUCT+2,0000 MOV PRODUCT+4,0000 MOV PRODUCT+6,0000 RET Z10XMUL ENDP
CODESG ENDS END BEGIN
Ассемблер для IBM PC. Программы. 86
page 60,132 TITLE EXDIV (COM) Пример операций DIV и IDIV CODESG SEGMENT PARA 'Code' ORG 100H BEGIN: JMP SHORT MAIN ; --------------------------------------------- BYTE1 DB 80H ;Data items BYTE2 DB 16H WORD1 DW 2000H WORD2 DW 0010H WORD3 DW 1000H ; --------------------------------------------- MAIN PROC NEAR ;Основная процедура CALL D10DIV ;Вызов подпрограммы DIV CALL E10IDIV ;Вызов подпрограммы IDIV MAIN ENDP ; Примеры с командой DIV: ; --------------------------------------------- D10DIV PROC MOV AX,WORD1 ;Слово / байт DIV BYTE1 ; остаток:частное в AH:AL MOV AL,BYTE1 ;Байт / байт SUB AH,AH ; расширить делимое в AH DIV BYTE3 ; остаток:частное в AH:AL


MOV DX,WORD2 ;Двойное слово / слово MOV AX,WORD3 ; делимое в DX:AX DIV WORD1 ; остаток:частное в DX:AX MOV AX,WORD1 ;Слово / слово SUB DX,DX ; расширить делимое в DX DIV WORD3 ; остаток:частное в DX:AX RET D10DIV ENDP ; Примеры с командой IDIV: ; --------------------------------------------- E10IDIV PROC MOV AX,WORD1 ;Слово / байт IDIV BYTE1 ; остаток:частное в AH:AL MOV AL,BYTE1 ;Байт / байт CBW ; расширить делимое в AH IDIV BYTE3 ; остаток:частное в AH:AL
MOV DX,WORD2 ;Двойное слово / слово MOV AX,WORD3 ; делимое в DX:AX IDIV WORD1 ; остаток:частное в DX:AX MOV AX,WORD1 ;Слово / слово CWD ; расширить делимое в DX IDIV WORD3 ; остаток:частное в DX:AX RET E10DIV ENDP
CODESG ENDS
Ассемблер для IBM PC. Программы. 87
END BEGIN
TITLE ASCADD (COM) Сложение чисел в ASCII-формате CODESG SEGMENT PARA 'Code' ASSUME CS:CODESG,DS:CODESG,SS:CODESG ORG 100H BEGIN: JMP SHORT MAIN ; ----------------------------------------------- ASC1 DB '578' ;Элементы данных ASC2 DB '694' ASC3 DB '0000' ; ----------------------------------------------- MAIN PROC NEAR CLC LEA SI,AASC1+2 ;Адреса ASCII-чисел LEA DI,AASC2+2 LEA BX,AASC1+3 MOV CX,03 ;Выполнить 3 цикла A20: MOV AH,00 ;Очистить регистр AH MOV AL,[SI] ;Загрузить ASCII-байт ADC AL,[DI] ;Сложение (с переносом) AAA ;Коррекция для ASCII MOV [BX],AL ;Сохранение суммы DEC SI DEC DI DEC BX LOOP A20 ;Циклиться 3 раза MOV [BX],AH ;Сохранить перенос RET MAIN ENDP CODESG ENDS END BEGIN
Ассемблер для IBM PC. Программы. 88
TITLE ASCMUL (COM) Умножение ASCII-чисел CODESG SEGMENT PARA 'Code' ASSUME CS:CODESG,DS:CODESG,SS:CODESG ORG 100H BEGIN: JMP MAIN ; --------------------------------------------- MULTCND DB '3783' ;Элементы данных MULTPLR DB '5' PRODUCT DB 5 DUP(0) ; --------------------------------------------- MAIN PROC NEAR MOV CX,04 ;4 цикла LEA SI,MULTCND+3 LEA DI,PRODUCT+4 AND MULTPLR,0FH ;Удалить ASCII-тройку A20: MOV AL,[SI] ;Загрузить ASCII-символ ; (можно LODSB) AND AL,OFH ;Удалить ASCII-тройку MUL MULTPLR ;Умножить AAM ;Коррекция для ASCII ADD AL,[DI] ;Сложить с AAA ; записанным MOV [DI],AL ; произведением DEC DI MOV [DI],AH ;Записать перенос DEC SI LOOP A20 ;Циклиться 4 раза RET MAIN ENDP CODESG ENDS END BEGIN


TITLE ASCDIV (COM) Деление ASCII-чисел CODESG SEGMENT PARA 'Code' ASSUME CS:CODESG,DS:CODESG,SS: CODESG ORG 100H BEGIN: JMP SHORT MAIN ; --------------------------------------------- DIVDND DB '3698' ;Элементы данных DIVSOR DB '4' QUOTNT DB 4 DUP(0) ; --------------------------------------------- MAIN PROC NEAR MOV CX,04 ;4 цикла SUB AH,AH ;Стереть левый байт делимого AND DIVSOR,0FH ;Стереть ASCII 3 в делителе LEA SI,DIVDND LEA DI,QUOTNT A20:
Ассемблер для IBM PC. Программы. 89
MOV AL,[SI] ;Загрузить ASCII байт ; (можно LODSB) AND AL,0FH ;Стереть ASCII тройку AAD ;Коррекция для деления DIV DIVSOR ;Деление MOV [DI],AL ;Сохранить частное INC SI INC DI LOOP A20 ;Циклиться 4 раза RET MAIN ENDP CODEGS ENDS END BEGIN
Ассемблер для IBM PC. Программы. 90
TITLE SCREMP (EXE) Ввод времени и расценки, ;вывод величины оплаты ; ---------------------------------------------------- STACKSG SEGMENT PARA STACK 'Stack' DW 32 DUP(?) STACKSG ENDS ; ---------------------------------------------------- DATASG SEGMENT PARA 'Data' HRSPAR LABLE BYTE ;Список параметров для ; ввода времени: MAXHLEN DB 6 ;--------------------- ACTHLEN DB ? HRSFLD DB 6 DUP(?)
RATEPAR LABLE BYTE ;Список параметров для ; ввода расценки: MAXRLEN DB 6 ;--------------------- ACTRLEN DB ? RATEFLN DB 6 DUP(?)
MESSG1 DB 'Hours worked? ','$' MESSG2 DB 'Rate of pay? ','$' MESSG3 DB 'Wage = ' ASCWAGE DB 10 DUP(30H), 13, 10, '$' ADJUST DW ? ASCHRS DB 0 ASCRATE DB 0 BINVAL DW 00 BINHRS DW 00 BINRATE DW 00 COL DB 00 DECIND DB 00 MULT10 DW 01 NODEC DW 00 ROW DB 00 SHIFT DW ? TENWD DW 10 DATASG ENDS ; ---------------------------------------------------- CODESG SEGMENT PARA 'Code' BEGIN PROC FAR ASSUME CS:CODESG,DS:DATASG,SS:STACKSG,ES:DATASG PUSH DS SUB AX,AX PUSH AX MOV AX,DATASG MOV DS,AX MOV ES,AX MOV AX,0600H CALL Q10SCR ;Очистить экран CALL Q20CURS ;Установить курсор A20LOOP:
Ассемблер для IBM PC. Программы. 91
CALL B10INPT ;Ввести время и расценку CMP ACTHLEN,00 ;Завершить работу? JE A30 CALL D10HOUR ;Получить двоичное время CALL E10RATE ;Получить двоичную расценку CALL F10MULT ;Расчитать оплату CALL G10WAGE ;Преобразовать в ASCII CALL K10DISP ;Выдать результат на экран JMP A20LOOP A30: MOV AX,0600H CALL Q10SCR ;Очистить экран RET ;Выйти из программы BEGIN ENDP ; Ввод времени и расценки ; ---------------------------------------------------- B10INPT PROC LEA DX,MESSG1 ;Запрос для ввода времени MOV AH,09 INT 21H LEA DX,HRSPAR ;Ввести время MOV AH,0AH INT 21H CMP ACTHLEN,00 ;Пустой ввод? JNE B20 RET ; да - вернуться A20LOOP B20: MOV COL,25 ;Установить столбец CALL Q20CURS LEA DX,MESSG2 ;Запрос для ввода засценки MOV AH,09 INT 21H LEA DX,RATEPAR ;Ввести расценку MOV AH,0AH INT 21H RET B10INPT ENDP ; Обработка времени: ; ----------------- D10HOUR PROC MOV NODEC,00 MOV CL,ACTHLEN SUB CH,CH LEA SI,HRSFLD-1 ;Установить правую позицию ADD SI,CX ; времени CALL M10ASBI ;Преобразовать в двоичное MOV AX,BINVAL MOV BINHRS,AX RET D10HOUR ENDP ; Обработка расценки: ; ------------------ E10RATE PROC


Ассемблер для IBM PC. Программы. 92
MOV CL,ACTRLEN SUB CH,CH LEA SI,RATEFLD-1 ;Установить правую позицию ADD SI.CX ; расценки CALL M10ASBI ;Преобразовать в двоичное MOV AX,BINVAL MOV BINRATE,AX RET E10RATE ENDP ; Умножение, округление и сдвиг: ; ----------------------------- F10MULT PROC MOV CX,05 LEA DI,ASCWAGE ;Установить формат оплаты MOV AX,3030H ; в код ASCII (30) CLD REP STOSW MOV SHIFT,10 MOV ADJUST,00 MOV CX,NODEC CMP CL,06 ;Если более 6 десятичных JA F40 ; знаков, то ошибка DEC CX DEC CX JLE F30 ;Обойти, если менее 3 знаков MOV NODEC,02 MOV AX,01 F20: MUL TENWD ;Вычислить фактор сдвига LOOP F20 MOV SHIFT,AX SHR AX,1 ;Округлить результат MOV ADJUST,AX F30: MOV AX,BINHRS MUL BINRATE ;Вычислить оплату ADD AX,ADJUST ;Округлить оплату ADC DX,00 CMP DX,SHIFT ;Результат слишком велик JB F50 ; для команды DIV? F40: SUB AX,AX JMP F70 F50: CMP ADJUST,00 ;Сдвиг нее требуется? JZ F80 DIV SHIFT ;Сдвинуть оплату F70: SUB DX,DX ;Стереть остаток F80: RET F10MULT ENDP ; Преобразование в ASCII формат: ; ----------------------------- G10WAGE PROC
Ассемблер для IBM PC. Программы. 93
LEA SI,ASCWAGE+7 ;Установить дес. точку MOV BYTE PTR[SI],'.' ADD SI,NODEC ;Установить правую позицию G30: CMP BYTE PTR[SI],'.' JNE G35 ;Обойти, если дес.поз. DEC SI G35: CMP DX,00 ;Если dx:ax < 10, JNZ G40 CMP AX,0010 ; то операция завершена JB G50 G40: DIV TENWD ;Остаток - ASCII-цифра OR DL,30H MOV [SI],DL ;Записать ASCII символ DEC SI SUB DX,DX ;Стереть остаток JMP G30 G50: OR AL,30H ;Записать последний ASCII MOV [SI],AL ; символ RET G10WAGE ENDP ; Вывод величины оплаты: ; --------------------- K10DISP PROC MOV COL,50 ;Установить столбец CALL Q20CURS MOV CX,09 LEA SI,ASCWAGE K20: ;Стереть лидирующие нули CMP BYTE PTR[SI],30H JNE K30 ; пробелами MOV BYTE PTR[SI],20H INC SI LOOP K20 K30: LEA DX,MESSG3 ;Вывод на экран MOV AH,09 INT 21H CMP ROW,20 ;Последняя строка экрана? JAE K80 INC ROW ; нет - увеличить строку JMP K90 K80: MOV AX,0601H ; да -- CALL Q10SCR ; прокрутить и MOV COL,00 ; установить курсор CALL Q20CURS K90: RET K10DISP ENDP ; Преобразование ASCII-чисел


Ассемблер для IBM PC. Программы. 94
; в двоичное представление: ; -------------------------- M10ASBI PROC MOV MULT10,0001 MOV BINVAL,00 MOV DECIND,00 SUB BX,BX M20: MOV AL,[SI] ;ASCII-символ CMP AL,'.' ;Обойти, если дес.точка JNE M40 MOV DECIND,01 JMP M90 M40: AND AX,000FH MUL MULT10 ;Умножить на фактор ADD BINVAL,AX ;Сложить с дв.значением MOV AX,MULT10 ;Вучислить следующий MUL TENVD ; фактор x 10 MOV MULT10,AX CMP DECIND,00 ;Десятичная точка? JNZ M90 INC BX ; да - обойти точку M90: DEC SI LOOP M20 ;Конец цикла CMP DECIND,00 ;Была дес.точка? JZ M100 ; да -- ADD NODEC,BX ; сложить с итогом M100: RET M10ASBI ENDP ; Прокрутка экрана: ; ---------------- Q10SCR PROC NEAR ;AX установлен при вызове MOV BH,30 ;Цвет (07 для ч/б) SUB CX,CX MOV DX,184FH INT 10H RET Q10SCR ENDP ; Установка курсора: ; ----------------- Q20CURS PROC NEAR MOV AH,02 SUB BH,BH MOV DH,ROW MOV DL,COL INT 10H RET Q20CURS ENDP
CODESG ENDS
Ассемблер для IBM PC. Программы. 95
END BEGIN
Ассемблер для IBM PC. Программы. 96
page 60,132 TITLE DIRECT (COM) Прямой табличный доступ CODESG SEGMENT PARA 'Code' ASSUME CS:CODESG,DS:CODESG,ES:CODESG ORG 100H BEGIN: JMP SHORT MAIN ; ------------------------------------------------ THREE DB 3 MONIN DB '11' ALFMON DB '???','$' MONTAB DB 'JAN','FEB','MAR','APR','MAY','JUN' DB 'JUL','AUG','SEP','OKT','NOV','DEC' ; ------------------------------------------------ MAIN PROC NEAR ;Основная процедура CALL C10CONV ;Получить двоичное значение CALL D10LOC ;Выделить месяц из таблицы CALL F10DISP ;Выдать месяц на экран RET MAIN ENDP ; Перевод ASCII в двоичное представление: ; -------------------------------------- C10CONV PROC MOV AH,MONIN ;Загрузить номер месяца MOV AL,MONIN+1 XOR AX,3030H ;Удалить ASCII тройки CMP AH,00 ;Месяц 01-09? JZ C20 ; да - обойти SUB AH,AH ; нет - очистить AH, ADD AL,10 ; и перевести в двоичное C20 RET C10CONV ENDP ; Выделение месяца из таблицы: ; --------------------------- D10LOC PROC LEA SI,MONTAB DEC AL ;Коррекция для таблицы MUL THREE ;Умножить AL на 3 ADD SI,AX MOV CX,03 ;Трехсимвольная пересылка CLD LEA DI,ALFMON REP MOVSB ;Переслать 3 символа RET D10LOC ENDP ; Вывод на экран симв.месяца: ; -------------------------- F10DISP PROC LEA DX,ALFMON MOV AH,09 INT 21H RET F10DISP ENDP


Ассемблер для IBM PC. Программы. 97
CODESG ENDS END BEGIN
Ассемблер для IBM PC. Программы. 98
page 60,132 TITLE TABSRCH (COM) Табличный поиск CODESG SEGMENT PARA 'Code' ASSUME CS:CODESG,DS:CODESG,ES:CODESG ORG 100H BEGIN: JMP SHORT MAIN ; ----------------------------------------------- STOKNIN DW '23' STOKTAB DB '05','Excavators' DB '08','Lifters ' DB '09','Presses ' DB '12','Valves ' DB '23','Processors' DB '27','Pumps ' DESCRN 10 DUP(?) ; ----------------------------------------------- MAIN PROC NEAR MOV AX,STOKNIN ;Загрузить номер элемента XCHG AL,AH MOV CX,06 ;Число элементов в таблице LEA SI,STOKTAB ;Начальный адрес таблицы A20: CMP AX,[SI] ;Сравнить элементы JE A30 ;Если равны - выйти, ADD SI,12 ; нет - следующий элемент LOOP A20 CALL R10ERR ;Элемент в таблице не найден RET A30: MOV CX,05 ;Длина описания элемента LEA DI,DESCRN ;Адрес описания элемента INC SI INC SI ;Выделить описание REP MOVSW ; из таблицы RET MAIN ENDP ; R10ERR PROC ; <Вывод сообщения об ошибке>
RET R10ERR ENDP
CODESG ENDS END BEGIN
Ассемблер для IBM PC. Программы. 99
page 60,132 TITLE TABSRCH (COM) Табличный поиск, использующий CMPSB CODESG SEGMENT PARA 'Code' ASSUME CS:CODESG,DS:CODESG,ES:CODESG ORG 100H BEGIN: JMP SHORT MAIN ; ---------------------------------------------------- STOKNIN DW '123' STOKTAB DB '035','Excavators' ;Начало таблицы DB '038','Lifters ' DB '049','Presses ' DB '102','Valves ' DB '123','Processors' DB '127','Pumps ' DB '999', 10 DUP(' ') ;Конец таблицы DESCRN 10 DUP(?) ; ---------------------------------------------------- MAIN PROC NEAR CLD LEA SI,STOKTAB ;Начальный адрес таблицы A20: MOV CX,03 ;Сравнивать по 3 байта LEA DI,STOKNIN ;Адрес искомого элемента REPE CMPSB ;Сравнение JE A30 ;Если равно - выйти, JA A40 ;если больше - нет в таблице ADD SI,CX ;Прибавить CX к адресу JMP A20 ;Следующий элемент таблицы A30: MOV CX,05 ;Пересылать 5 слов LEA DI,DESCRN ;Адрес описания REP MOVSV ;Переслать из таблицы RET A40: CALL R10ERR ;элемент в таблице не найден RET MAIN ENDP


R10ERR PROC ; < Вывод на экран сообщения об ошибке>
RET R10ERR ENDP
CODESG ENDS END BEGIN
Ассемблер для IBM PC. Программы. 100
page 60,132 TITLE XLATE (COM) Перевод кода ASCII в код EBCDIC CODESG SEGMENT PARA 'Code' ASSUME CS:CODESG,DS:CODESG,ES:CODESG ORG 100H BEGIN: JMP MAIN ; ---------------------------------------------------- ASCNO DB '-31.5' EBCNO DB 6 DUP(' ') XLTAB DB 45 DUP(40H) DB 60H, 2DH DB 5CH DB 0F0H,0F1H,0F2H,0F3H,0F4H DB 0F5H,0F6H,0F7H,0F8H,0F9H DB 199 DUP(40H) ; ---------------------------------------------------- MAIN PROC NEAR ;Основная процедура LEA SI,ASCNO ;Адрес символов ASCNO LEA DI,EBCNO ;Адрес поля EBCNO MOV CX,06 ;Длина LEA BX,XLTAB ;Адрес таблицы A20: MOV AL,[SI] ;Получить ASCII символ XLAT ;Перекодировка MOV [DI],AL ;Записать в поле EBCNO INC DI INC SI LOOP A20 ;Повторить 6 раз RET MAIN ENDP CODESG ENDS END BEGIN
Ассемблер для IBM PC. Программы. 101
page 60,132 TITLE ASCHEX (COM) Преобразование ASCII в шест. CODESG SEGMENT PARA 'Code' ASSUME CS:CODESG,DS:CODESG,ES:CODESG ORG 100H BEGIN: JMP MAIN ; ----------------------------------------------- DISPROW DB 16 DUP(' '), 13 HEXSTR DB 00 XLATAB DB 30H,31H,32H,33H,34H,35H,36H,37H,38H,39H DB 41H,42H,43H,44H,45H,46H ; ----------------------------------------------- MAIN PROC NEAR ;Основная процедура CALL Q10CLR ;Очистить экран LEA SI,DISPROW A20LOOP: CALL C10HEX ;Перекодировать CALL D10DISP ; и вывести на экран CMP HEXCTR,0FFH ;Последнее значение (FF)? JE A50 ; да - завершить INC HEXCTR ; нет - перейти к следующему JMP A20LOOP A50: RET MAIN ENDP
C10HEX PROC NEAR ;Перекодировка в шест. MOV AH,00 MOV AL,HEXCTR ;Получить шест.пару SHR AX,CL ;Сдвиг правой шест.цифры LEA BX,XLATAB ;Установить адрес таблицы MOV CL,04 ;Установить величину сдвига XLAT ;Перекодировка в шест. MOV [SI],AL ;Записать левый символ
MOV AL,HEXCTR SHL AX,CL ;Сдвиг левой цифры XLAT MOV [SI]+1,AL ;Перекодировка в шест. RET ;Записать правый символ C10HEX ENDP
D10DISP PROC NEAR ;Вывод на экран MOV AL,HEXCTR MOV [SI]+3,AL CMP AL,1AH ;Символ EOF? JE D20 ; да - обойти CMP AL,07H ;Меньше/равно 08? JB D30 ; да - OK CMP AL,10H ;Больше/равно 0F? JAE D30 ; да - OK D20: MOV BYTE PTR [SI]+3,20H


Ассемблер для IBM PC. Программы. 102
D30: ADD SI,05 ;Следующий элемент в строке LEA DI,DISPROW+80 CMP DI,SI JNE D40 MOV AH,40H ;Функция вывода на экран MOV BX,01 ;Номер устройства MOV CX,81 ;Вся строка LEA DX,DISPROW INT 21H LEA SI,DISPROW ;Начальный адрес строки D40: RET D10DISP ENDP
Q10CLR PROC NEAR ;Очистка экрана MOV AX,0600H MOV BH,03 ;Цвет (07 для ч/б) MOV CX,0000 MOV DX,184FH INT 10H RET Q10CLR ENDP
CODESG ENDS END BEGIN
Ассемблер для IBM PC. Программы. 103
page 60,132 TITLE NMSORT (EXE) Ввод и сортировка имен ; ----------------------------------------------- STACK SGMENT PARA STACK 'Stack' DW 32 DUP(?) STACK ENDS ; ----------------------------------------------- DATASG SEGMENT PARA 'Data' NAMEPAR LABEL BYTE ;Имя списка параметров: MAXNLEN DB 21 ; макс. длина NAMELEN DB ? ; число введенных символов NAMEFLD DB 21 DUP(' ') ; имя
CRLF DB 13, 10, '$' ENDADDR DW ? MESSG1 DB 'Name?', '$' NAMECTR DB 00 NAMETAB DB 30 DUP(20 DUP(' ')) ;Таблица имен NAMESAV DB 20 DUP(?), 13, 10, '$' SWAPPED DB 00 DATA ENDS ; ----------------------------------------------- CODESG SEGMENT PARA 'Code' BEGIN PROC FAR ASSUME CS:CODESG,DS:DATDSG,SS:STACK,ES:DATASG PUSH DS SUB AX,AX PUSH AX MOV AX,DATASG MOV DS,AX MOV ES,AX CLD LEA DI,NAMETAB CALL Q10CLR ;Очистить экран CALL Q20CURS ;Установить курсор A20LOOP: CALL B10READ ;Ввести имя с клавиатуры CMP NAMELEN,00 ;Есть ли еще имена? JZ A30 ; нет - идти на сортировку CMP NAMECTR,30 ;Введено 30 имен? JE A30 ; да - идти на сортировку CALL D10STOR ;Записать имя в таблицу JMP A20LOOP A30: ;Конец ввода имен CALL Q10CLR ;Очистить экран CALL Q20CURS ; и установить курсор CMP NAMECTR,01 ;Введено менее 2 имен? JBE A40 ; да - выйти CALL G10SORT ;Сортировать имена CALL K10DISP ;Вывести результат на экран A40: RET ;Завершить программу BEGIN ENDP
Ассемблер для IBM PC. Программы. 104
; Ввод имен с клавиатуры? ; ---------------------- B10READ PROC MOV AH,09 LEA DX,MESSG1 ;Вывести текст запроса INT 21H MOV AH,0AH LEA DX,NAMEPAR ;Ввести имя INT 21H MOV AH,09 LEA DX,CRLF ;Вывести CRLF INT 21H


MOV BH,00 ; Очистить поле после имени MOV BL,NAMELEN ;Получить счетчик символов MOV CX,21 SUB CX,BX ;Вычислить оставшуюся длину B20: MOV NAMEFLD[BX],20H ;Установить символ пробела INC BX LOOP B20 RET B10READ ENDP ; Запись имени в таблицу: ; ---------------------- D10STOR PROC INC NAMECTR ;Число имен в таблице CLD LES SI,NAMEFLD MOV CX,10 REP MOVSV ;Переслать имя в таблицу RET D10STOR ENDP ; Сортировка имен в таблице: ; ------------------------- G10SORT PROC SUB DI,40 ;Установить адреса останова MOV ENDADDR,DI G20: MOV SWAPPED,00 ;Установить начало LEA SI,NAMETAB ; таблицы G30: MOV CX,20 ;Длина сравнения MOV DI,SI ADD DI,20 ;Следующее имя для сравнения MOV AX,DI MOV BX,SI REPE CMPSB ;Сравнить имя со следующим JBE G40 ; нет перестановки CALL H10XCHG ; перестановка G40: MOV SI,AX CMP SI,ENDADDR ;Конец таблицы?
Ассемблер для IBM PC. Программы. 105
JBE G30 ; нет - продолжить CMP SWAPPED,00 ;Есть перестановки? JNZ G20 ; да - продолжить, RET ; нет - конец сортировки G10SORT ENDP ; Перестановка элементов таблицы: ; ------------------------------ H10XCHG PROC MOV CX,10 LEA DI,NAMESAV MOV SI,BX REP MOVSW ;Сохранить меньший элемент
MOV CX,10 MOV DI,BX REP MOVSW ;Переслать больший элемент ; на место меньшего MOV CX,10 LEA SI,NAMESAV REP MOVSW ;Переслать сохраненный ; элемент на место большего MOV SWAPPED,01 ;Признак перестановки RET H10XCHG ENDP ; Вывод на экран отсортированные имена: ; ------------------------------------ K10DISP PROC LEA SI,NAMETAB K20: LEA DI,NAMESAV ;Начальный адрес таблицы MOV CX,10 REP MOVSV MOV AH,09 LEA DX,NAMESAV INT 21H ;Вывести на экран DEC NAMECTR ;Это последний элемент? JNZ K20 ; нет - повторить цикл, RET ; да - выйти K10DISP ENDP ; Очистка экрана: ; -------------- Q10CLR PROC MOV AX,0600H MOV BH,61H ;Цвет (07 для ч/б) SUB CX,CX MOV DX,184FH INT 10H RET Q10CLR ENDP ; Установка курсора: ; ----------------- Q20CURS PROC MOV AH,02
Ассемблер для IBM PC. Программы. 106
SUB BH,BH SUB DX,DX ;Установить курсор в 00,00 INT 10H RET Q20CURS ENDP
CODESG ENDS END BEGIN


Ассемблер для IBM PC. Программы. 107
page 60,132 TITLE FCBCREAT (EXE) Использование FCB для создания файла ;---------------------------------------------------------- STACKSG SEGMENT PARA STACK 'Stack' DW 80 DUP(?) STACKSG ENDS ;---------------------------------------------------------- DATASG SEGMENT PARA 'Data' 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 ; номер текущего блока 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 ***', '$' DATASG ENDS ; --------------------------------------------------------- CODESG SEGMENT PARA 'Code' BEGIN PROC FAR ASSUME CS:CODESG,DS:DATASG,SS:STACKSG,ES:DATASG PUSH DS SUB AX,AX PUSH AX MOV AX,DATASG MOV DS,AX MOV ES,AX MOV AX,0600H CALL Q10SCR ;Очистить экран CALL Q20CURS ;Установить курсор CALL C10OPEN ;Открыть, установить DTA CMP ERRCDE,00 ;Есть место на диске? JZ A20LOOP ; да - продолжить, RET ; нет - вернуться в DOS A20LOOP: CALL D10PROC
Ассемблер для IBM PC. Программы. 108
CMP NAMELEN,00 ;Конец ввода? JNE A20LOOP ; нет - продолжить, CALL G10CLSE ; да - закрыть файл RET ; и вернуться в DOS BEGIN 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 ;Функция вывода на экран 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 ; Прокрутка и установка курсора:
Ассемблер для IBM PC. Программы. 109
; ----------------------------- 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 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
Ассемблер для IBM PC. Программы. 110
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
Ассемблер для IBM PC. Программы. 111
TITLE FCBREAD (EXE) Чтение записей созданных в CREATDSK ; ------------------------------------------------------- STACKSG SEGMENT PARA STACK 'Stack' DW 80 DUP(?) STACKSG ENDS ;-------------------------------------------------------- DATASG SEGMENT PARA 'Data' FCBREC LABEL BYTE ;FCB для файла FCBDRIV DB 04 ; дисковод D FCBNAME DB 'NAMEFILE' ; имя файла FCBEXT DB 'DAT' ; тип файла FCBBLK DW 0000 ; номер текущего блока FCBRCSZ DW 0000 ; длина логической записи 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 DATASG ENDS ;-------------------------------------------------------- CODESG SEGMENT PARA 'Code' BEGIN PROC FAR ASSUME CS:CODESG,DS:DATASG,SS:STACKSG,ES:DATASG PUSH DS SUB AX,AX PUSH AX MOV AX,DATASG MOV DS,AX MOV ES,AX 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
Ассемблер для IBM PC. Программы. 112
; Открытие файла на диске: ; ----------------------- E10OPEN PROC NEAR LEA X,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 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
Ассемблер для IBM PC. Программы. 113
CALL Q10SCR ; прокрутить CALL Q20CURS ; установить курсор G90: RET G10DISP ENDP ; Прокрутка (скроллинг) экрана: ; ---------------------------- Q10SCR PROC NEAR ;AX уже установлен MOV BH,1EH ;Установить цвет MOV CX,0000 MOV DX,184FH ;Функция прокрутки INT 10H RET Q1OSCR ENDP ; Установка курсора: ; ----------------- Q20CURS PROC NEAR MOV AH,02 MOV BH,00 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
page 60,132 TITLE RANREAD (COM) Прямое чтение записей, ; созданных в FCBCREAT CODESG SEGMENT PARA 'Code' ASSUME CS:CODESG,DS:CODESG,SS:CODESG,ES:CODESG ORG 100H BEGIN: JMP MAIN ;----------------------------------------------------- FCBREC LABEL BYTE ;FCB для дискового файла FCBDRIV DB 04 ; дисковод D FCBNAME DB 'MAMEFILE' ; имя файла FCBEXT DB 'DAT' ; тип файла FCBBLK DW 0000 ; номер текущего блока FCBRCSZ DW 0000 ; длина логической записи DD ? ; размер файла (DOS) DW ? ; дата (DOS) DT ? ; зарезервировано (DOS)
Ассемблер для IBM PC. Программы. 114
DB 00 ; номер текущей записи FCBRNRC DD 000000000 ; относительный номер
RECLEN EQU 32 ;Длина записи RECDPAR LABEL BYTE ;Список параметров: MAXLEN DB 3 ; ACTLEN DB ? ; RECDNO DB 3 DUP(' ') ;
NAMEFLD DB RECLEN DUP(' '),13,10,'$' ;DTA
OPENMSG DB '*** Open error ***',13,10,'$' READMSG DB '*** Read error ***',13,10,'$' COL DB 00 PROMPT DB 'Record number? $' ROW DB 00 ENDCDE DB 00 ;----------------------------------------------------- MAIN PROC NEAR CALL Q10CLR ;Очистить экран CALL Q20CURS ;Установить курсор CALL C10OPEN ;Открыть файл, ; установить DTA CMP ENDCDE,00 ;Открытие без ошибок? JZ A20LOOP ; да - продолжить, RET ; нет - завершить A20LOOP: CALL D10RECN ;Получить номер записи CMP ACTLEN,00 ;Есть запрос? JE A40 ; нет - выйти CALL F10READ ;Чтение (прямой доступ) CMP ENDCDE,00 ;Есть ошибки чтения? JNZ A30 ; да - обойти CALL G10DISP ;Вывести на экран A30: JMP A20LOOP A40: RET ;Завершить программу MAIN ENDP ; Подпрограмма открытия файла на диске: ; ------------------------------------ C10OPEN PROC NEAR MOV AH,0FH ;Функция открытия LEA DX,FCBREC INT 21H CMP AL,00 ;Открытие нормальное? JNZ C20 ; нет - ошибка MOV FCBRCSZ,RECLEN ;Длина записи (EQU) MOV AH,1AH LEA DX,NAMEFLD ;Установить адрес DTA INT 21H RET C20: LEA DX,OPENMSG
Ассемблер для IBM PC. Программы. 115
CALL X10ERR RET C10OPEN ENDP ; Ввод с клавиатуры номера записи: ; ------------------------------- D10RECN PROC NEAR MOV AH,09H ;Функция вывода на экран LEA DX,PROMPT INT 21H MOV AH,0AH ;Функция ввода с клавиатуры LEA DX,RECDPAR INT 21H CMP ACTLEN,01 ;Проверить длину (0,1,2) JB D40 ;Длина 0, завершить JA D20 SUB AH,AH ;Длина 1 MOV AL,RECDNO JMP D30 D20: MOV AH,RECDNO ;Длина 2 MOV AL,RECDNO+1 D30: AND AX,0F0FH ;Удалить ASCII тройки AAD Преобразовать в двоичное MOV WORD PTR FCBRNRC,AX D40: MOV COL,20 CALL Q20CURS ;Установить курсор RET D10RECN ENDP ; Чтение дисковой записи: ; ---------------------- F10READ PROC NEAR MOV ENDCDE,00 ;Очистить код завершения MOV AH,21H ;Функция прямого чтения LEA DX,FCBREC INT 21H CMP AL,00 ;Чтение без ошибок? JZ F20 ; да - выйти LEA DX,READMSG ; нет - выдать CALL X10ERR ; сообщение об ошибке F20: RET F10READ ENDP ; Вывод имени на экран: ; -------------------- G10DISP PROC NEAR MOV AH,09 ;Функция вывода на экран LEA DX,NAMEFLD INC 21H INC ROW MOV COL,00 RET G10DISP ENDP


Ассемблер для IBM PC. Программы. 116
; Очистка экрана: ; -------------- Q10CLR PROC NEAR MOV AX,0600H ;Функция прокрутки MOV BH,41H ;Цвет (07 для ч/б) MOV CX,0000 MOV DX,184FH INT 10H RET Q10CLR ENDP ; Установка курсора: ; ----------------- Q20CURS PROC NEAR MOV AH,02 ;Функция установки MOV BH,00 ; курсора MOV DH,ROW MOV DL,COL INT 10H RET Q20CURS ENDP ; Вывод сообщения об ошибке на диске: ; ---------------------------------- X10ERR PROC NEAR MOV AH,09 ;DX содержит адрес INT 21H ; сообщения INC ROW MOV ENDCDE,01 RET X10ERR ENDP CODESG ENDS END BEGIN
Ассемблер для IBM PC. Программы. 117
TITLE RANBLOK (COM) Прямое блочное чтение файла CODESG SEGMENT PARA 'Code' ASSUME CS:CODESG,DS:CODESG,SS:CODESG,ES:CODESG ORG 100H BEGIN: JMP MAIN ;---------------------------------------------------- FCBREC LABEL BYTE ;FCB для дискового файла FCBDRIV DB 04 ; дисковод D FCBNAME DB 'NAMEFILE' ; имя файла FCBEXT DB 'DAT' ; тип файла FCBBLK DW 0000 ; номер текущего блока FCBRCSZ DW 0000 ; логическая длина записи FCBFLZ DD ? ; DOS размер файла DW ? ; DOS дата DT ? ; DOS зарезервировано DB 00 ; номер текущей записи FCBRNRC DD 00000000 ; относительный номер
DSKRECS DB 1024 DUP(?),'$' ;DTA для блока записей
ENDCODE DB 00 NORECS DW 25 ;Число записей OPENMSG DB '*** Open error ***',13,10,'$' READMSG DB '*** Open error ***',13,10,'$' ROWCTR DB 00 ; --------------------------------------------------- MAIN PROC NEAR CALL Q10CLR ;Очистить экран CALL Q20CURS ;Установить курсор CALL E10OPEN ;Открыть файл, ; установить DTA CMP ENDCODE,00 ;Успешное открытие? JNZ A30 ; нет - выйти CALL F10READ ;Читать записи CALL G10DISP ;Вывод блока на экран A30: RET ;Завершить программу MAIN ENDP ; Открыть дисковый файл: ; --------------------- E10OPEN PROC NEAR MOV AH,0FH ;Функция открытия файла LEA DX,FCBREC INT 21H CMP AL,00 ;Успешное открытие? JNZ A30 ; нет - ошибка
MOV FCBRCSZ,0020H ;Размер записи MOV AH,1AH LEA DX,DSKRECS ;Установить адрес DTA INT 21H RET E20:
Ассемблер для IBM PC. Программы. 118
LEA DX,OPENMSG ;Ошибка открытия файла CALL X10ERR RET E10OPEN ENDP ; Чтение блока: ; ------------ F10READ PROC NEAR MOV AH,27H ;Прямое чтение блока MOV CX,NORECS ;Число записей LEA DX,FCBREC INT 21H MOV ENDCODE,AL ;Сохранить код возврата RET F10READ ENDP ; Вывод блока на экран: ; -------------------- G10DISP PROC NEAR MOV AH,09 ;Функция вывода на экран LEA DX,DSKRECS INT 21H RET G10DISP ENDP ; Подпрограмма очистки экрана: Q10CLR PROC NEAR MOV AX,0600H ;Функция скрол MOV BH,41H ;Цвет (07 для ч/б) MOV CX,0000 MOV DX,184FH INT 10H RET Q10CLR ENDP ; Подпрограмма установки курсора: ; ------------------------------ Q20CURS PROC NEAR MOV AH,02 ;Функция установки курсора MOV BH,00 MOV DH,ROWCTR MOV DL,00 INT 10H INC ROWCTR RET Q20CURS ENDP ; Подпрограмма сообщения об ошибке диска: ; -------------------------------------- X10ERR PROC NEAR MOV AH,09 ;DX содержит адрес INT 21H ; сообщения MOV ENDCODE,01 RET X10ERR ENDP


CODESG ENDS END BEGIN
Ассемблер для IBM PC. Программы. 119
TITLE SELDEL (COM) Выборочное удаление файлов ; Предполагается текущий дисковод; ; Примеры параметров: *.*, *.BAK, и т.д. CODESG SEGMENT PARA 'Code' ASSUME CS:CODESG,DS:CODESG,SS:CODESG ORG 100H BEGIN JMP MAIN ; ---------------------------------------------------------- TAB EQU 09 LF EQU 10 CR EQU 13 CRLF DB CR,LF,'$' DELMSG DB TAB,'Erase','$' ENDMSG DB CR,LF,'No more directory entries',CR,LF,'$' ERRMSG DB 'Write protected disk','$' PROMPT DB 'y = Erase, N = Keep, Ret = Exit',CR,LF,'$' ; ---------------------------------------------------------- MAIN PROC NEAR ;Главная процедура MOV AH,11H ;Найти первый элемент CALL D10DISK CMP AL,0FFH ;Если нет элементов, JE A90 ; то выйти LEA DX,PROMPT ;Текст запроса CALL B10DISP A20: LEA DX,DELMSG ;Выдать сообщение CALL B10DISP ; об удалении файла MOV CX,11 ;11 символов MOV SI,81H ;Начало имени файла A30: MOV DL,[SI] ;Текущий символ CALL C10CHAR ; для вывода на экран INC SI ;Следующий символ LOOP A30 MOV DL,'?' CALL C10CHAR MOV AH,01 ;Получить односимвольный INT 21H ; ответ CMP AL,ODH ;Символ Return? JE A90 ; да - выйти OR AL,00100000B ;Перекодировать ; в прописную букву CMP AL,'y' ;Запрошено удаление? JNE A50 ; нет - обойти, MOV AH,13H ; да - удалить файл MOV DX,80H INT 21H CMP AL,0 ;Успешное удаление? JZ A50 ; да - обойти LEA DX,ERRMSG ; нет - выдать CALL B10DISP ; предупреждение JMP A90
Ассемблер для IBM PC. Программы. 120
A50: LEA DX,CRLF ;Перевести строку на экране CALL B10DISP MOV AH,12H CALL B10DISK ;Получить следующий элемент CMP AL,0FFH ;Есть еще? JNE A20 ; да - повторить A90: RET ;Выход в DOS MAIN ENDP ; Вывод строки на экран; ; --------------------- B10DISP PROC NEAR ;в DX находится адрес MOV AH,09 ; строки INT 21H RET B10DISP ENDP ; Вывод символа на экран; ; ---------------------- C10CHAR PROC NEAR ;в DL находится символ MOV AH,02 INT 21H RET C10CHAR ENDP ; Чтение элемента каталога: ; ------------------------ D10DISK PROC NEAR MOV DX,5CH ;Установить FCB INT 21H CMP AL,0FFH ;Есть еще элементы? JNE D90 PUSH AX ;Сохранить AL LEA DX,ENDMSG CALL B10DISP POP AX ;Восстановить AL D90: RET D10DISK ENDP


CODESG ENDS END BEGIN
Ассемблер для IBM PC. Программы. 121
page 60,132 TTILE HANCREAT (EXE) Создание файла на диске ; ----------------------------------------------------- STACKSG SEGMENT PARA STACK 'Stack' DW 80 DUP(?) STACKSG ENDS ; ----------------------------------------------------- DATASG SEGMENT PARA 'Data' NAMEPAR LABEL BYTE ;Список параметров: MAXLEN DB 30 ; NAMELEN DB ? ; NAMEREC DB 30 DUP(' '), 0DH, 0AH ; введенное имя, ; CR/LF для записи ERRCDE DB 00 HANDLE DW ? PATHNAM DB 'D:\NAMEFILE.DAT',0 PROMPT DB 'Name? ' ROW DB 01 OPNMSG DB '*** Open error ***', 0DH, 0AH WRTMSG DB '*** Write error ***', 0DH, 0AH DATASG ENDS ; ------------------------------------------------------- CODESG SEGMENT PARA 'Code' BEGIN PROC FAR ASSUME CS:CODESG,DS:DATASG,SS:STACKSG,ES:DATASG PUSH DS SUB AX,AX PUSH AX MOV AX,DATASG MOV DS,AX MOV ES,AX MOV AX,0600H CALL Q10SCR ;Очистка экрана CALL Q20CURS ;Установка курсора CALL C10CREA ;Создание файла, ; установка DTA CMP ERRCDE,00 ;Ошибка при создании? JZ A20LOOP ; да - продолжить, RET ; нет - вернуться в DOS A20LOOP: CALL D10PROC CMP NAMELEN,00 ;Конец ввода? JNE A20LOOP ; нет - продолжить, CALL G10CLSE ; да - закрыть файл RET ; и выйти в DOS BEGIN ENDP ; Создание файла на диске: ; ----------------------- C10CREA PROC NEAR MOV AH,3CH ;Функция создания файла MOV CX,00 ;Нормальный атрибут LEA CX,PATHNAM
Ассемблер для IBM PC. Программы. 122
INT 21H JC C20 ;Есть ошибка? MOV HANDLE,AX ; нет - запомнить номер, RET C20: ; да - LEA DX,OPNMSG ; выдать сообщение CALL X10ERR ; об ошибке RET C10CREA ENDP ; Ввод с клавиатуры: ; ----------------- D10PROC PROC NEAR MOV AH,40H ;Функция вывода на экран MOV BX,01 ;Номер (Handle) MOV CX,06 ;Длина текста запроса LEA DX,PROMPT ;Выдать запрос INT 21H
MOV AH,0AH ;Функция ввода с клавиатуры LEA DX,NAMEPAR ;Список параметров INT 21H CMP NAMELEN,00 ;Имя введено? JNE D20 ; да - обойти RET ; нет - выйти D20: MOV AL,20H ;Пробел для заполнения SUB CH,CH MOV CL,NAMELEN ;Длина LEA DI,NAMEREC ; ADD DI,CX ;Адрес + длина NEG CX ;Вычислить ADD CX,30 ; оставшуюся длину REP STOSB ;Заполнить пробелом D90: CALL F10WRIT ;Запись на диск CALL E10SCRL ;Проверка на скролинг RET D10PROC ENDP ; Проверка на скролинг: ; -------------------- E10SCRL PROC NEAR CMP ROW,18 ;Последняя строка экрана JAE E10 ; да - обойти, INC ROW ; нет - увеличить строку JMP E10 E10: MOV AX,0601H ;Продвинуть на одну строку CALL Q10SCR E90: CALL Q20CURS ;Установка курсора RET E10SCRL ENDP ; Запись на диск: ; --------------


Ассемблер для IBM PC. Программы. 123
F10WRIT PROC NEAR MOV AH,40H ;Функция записи на диск MOV BX,HANDLE MOV CX,32 ;30 для имени + 2 для CR/LF LEA DX,NAMEREC INT 21H JNC F20 ;Ошибка записи? LEA DX,WRTMSG ; да - CALL X10ERR ; выдать предупреждение MOV NAMELEN,00 F20: RET F10WRIT ENDP ; Закрытие файла на диске: ; ----------------------- G10CLSE PROC NEAR MOV NAMEREC,1AH ;Маркер конца записи (EOF) CALL F10WRIT MOV AH,3EH ;Функция закрытия MOV BX,HANDLE 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 DH,ROW ;Установить курсор MOV DL,00 INT 10H RET Q20CURS ENDP ; Вывод сообщения об ошибке: ; ------------------------- X10ERR PROC NEAR ;DX содержит MOV AH,40H ; адрес сообщения MOV BX,01 MOV CX,21 ;Длина сообщения INT 21H MOV ERRCDE,01 ;Установить код ошибки RET X10ERR ENDP
Ассемблер для IBM PC. Программы. 124
CODESG ENDS END BEGIN
Ассемблер для IBM PC. Программы. 125
page 60,132 TITLE HANREAD (EXE) Чтение записей, созданных в HANCREAT ; ----------------------------------------------------- STACKSG SEGMENT PARA STACK 'Stack' DW 80 DUP(?) STACKSG ENDS ; ----------------------------------------------------- DATASG SEGMENT PARA 'Data' ENDCDE DB 00 HANDLE DW ? IOAREA DB 32 DUP(' ') PATHNAM DB 'D:\NAMEFILE.SRT',0 OPENMSG DB '*** Open error ***', 0DH, 0AH READMSG DB '*** Read error ***', 0DH, 0AH ROW DB 00 DATASG ENDS ; ------------------------------------------------------ CODESG SEGMENT PARA 'Code' BEGIN PROC FAR ASSUME CS:CODESG,DS:DATASG,SS:STACKSG,ES:DATASG PUSH DS SUB AX,AX PUSH AX MOV AX,DATASG MOV DS,AX MOV ES,AX MOV AX,0600H CALL Q10SCR ;Очистить экран CALL Q20CURS ;Установить курсор CALL E100PEN ;Открыть файл, ; ; установить DTA CMP ENDCDE,00 ;Ошибка открытия? JNZ A90 ; да - завершить программу A20LOOP: CALL F10READ ;Чтение записи с диска CMP ENDCDE,00 ;Ошибка чтения? JNZ A90 ; да - выйти, CALL G10DISP ; нет - выдать имя, JMP A20LOOP ; и продолжить A90: RET BEGIN ENDP ; Открытие файла: ; -------------- E100PEN PROC NEAR MOV AH,3DH ;Функция открытия MOV CX,00 ;Нормальные атрибуты LEA DX,PATHNAM INT 21H JC E20 ;Ошибка открытия? MOV HANDLE,AX ; нет - сохранить RET ; файловый номер E20:


Ассемблер для IBM PC. Программы. 126
MOV ENDCDE,01 ; да - выдать LEA DX,OPENMSG ; сообщение об ошибке CALL X10ERR RET E100PEN ENDP ; Чтение дисковой записи: ; ---------------------- F10READ PROC NEAR MOV AX,3FH ;Функция чтения MOV BX,HANDLE MOV CX,32 ;30 для имени, 2 для CR/LF LEA DX,IOAREA INT 21H JC F20 ;Ошибка при чтении? CMP AX,00 ;Конец файла? JE F30 CMP IOAREA,1AH ;Маркер конца файла (EOF)? JE F30 ; да - выйти RET F20: LEA DX,READMSG ; нет - выдать CALL X10ERR ; сообщение об ошибке F30: MOV ENDCDE,01 ;Код завершения F90: RET F10READ ENDP ; Вывод имени на экран: ; -------------------- G10DISP PROC NEAR MOV AH,40H ;Функция вывода на экран MOV BX,01 ;Установить номер MOV CX,32 ; и длину LEA DX,IOAREA INT 21H CMP ROW,20 ;Последняя строка экрана? JEA G90 ; да - обойти INC ROW RET G90: MOV AX,0601H CALL Q10SCR ;Прокрутка (скроллинг) CALL Q20CURS ;Установить курсор RET G10DISP ENDP ; Прокрутка (скроллинг) экрана: ; ---------------------------- Q10SCR PROC NEAR ;в AX - адрес элемента MOV BH,1EH ;Установить цвет MOV CX,0000 MOV DXX,184FH ;Функция прокрутки INT 10H RET Q10SCR ENDP
Ассемблер для IBM PC. Программы. 127
; Установка курсора: ; ----------------- Q20CURS PROC NEAR MOV AH,02 ;Функция установки курсора MOV BH,00 ; курсор MOV DH,ROW ; строка MOV DL,00 ; столбец INT 10H RET Q20CURS ENDP ; Вывод сообщения об ошибке: ; ------------------------- X10ERR PROC NEAR MOV AH,40H ;в DX - адрес сообщения MOV BX,01 ;Номер MOV CX,20 ;Длина сообщения INT 21H RET X10ERR ENDP
CODESG ENDS END BEGIN
Ассемблер для IBM PC. Программы. 128
page 60,132 TITLE ASCREAD (COM) Чтение ASCII файла CODESG SEGMENT PARA 'Code' ASSUME CS:CODESG,DS:CODESG,SS:CODESG,ES:CODESG ORG 100H BEGIN: JMP MAIN ; ------------------------------------------------- SECTOR DB 512 DUP(' ') ;Область ввода DISAREA DB 120 DUP(' ') ;Область вывода на экран ENDCDE DW 00 HANDLE DW 0 OPENMSG DB '*** Open error ***' PATHNAM DB 'D:\HANREAD.ASM', 0 ROW DB 00 ; ------------------------------------------------- MAIN PROC NEAR ;Основная программя MOV AX,0600H CALL Q10SCR ;Очистить экран CALL Q20CURS ;Установить курсор CALL E10OPEN ;Открыть файл, ; установить DTA CMP ENDCDE,00 ;Ошибка при открытии? JNE A90 ; да - выйти, A20LOOP: ; нет - продолжить CALL R10READ ;Чтение первого сектора CMP ENDCDE,00 ;Конец файла, нет данных? JE A90 ; да - выйти CALL G10XPER ;Выдать на экран A90: RET ;Завершить программу MAIN ENDP ; Открыть файл на диске: ; --------------------- E10OPEN PROC NEAR MOV AH,3DH ;Функция открытия MOV AL,00 ;Только чтение LEA DX,PATHNAM INT 21H JNC E20 ;Проверить флаг CF CALL X10ERR ; ошибка, если установлен RET E20: MOV HANDLE,AX ;Запомниить номер файла RET E10OPEN ENDP ; Построчный вывод данных на экран: ; -------------------------------- G10XPER PROC NEAR CLD ;Направление слева-направо LEA SI,SECTOR G20: LEA DI,DISAREA G30:


Ассемблер для IBM PC. Программы. 129
LEA DX,SECTOR+512 CMP SI,DX ;Конец сектора? JNE G40 ; нет - обойти, CALL R10READ ; да - читать следующий CMP ENDCDE,00 ;Конец файла? JE G80 ; да - выйти LEA SI,SECTOR G40: LEA DX,DISAREA+80 CMP DI,DX ;Конец DISAREA? JB G50 ; нет - обойти, MOV [DI],0D0AH ; да - установить CR/LF CALL H10DISP ; и выдать на экран LEA DI,DISAREA G50: LODSB ;Загрузить [SI] в AL ; и увеличить SI STOSB ;Записать AL в [DI] ; и увеличить DI CMP AL,1AH ;Конец файла? JE G80 ; да - выйти CMP AL,0AH ;Конец строки? JNE G30 ; нет - повторить цикл, CALL H10DISP ; да - вывести на экран JMP G20 G80: CALL H10DISP ;Вывести последнюю строку G90: RET G10XPER ENDP ; Вывод строки на экран: ; --------------------- H10DISP PROC NEAR MOV AH,40H ;Функция вывода на экран MOV BX,01 ;Номер (Handle) LEA CX,DISAREA ;Вычислить NEG CX ; длину ADD CX,DI ; строки LEA DX,DISAREA INT 21H CMP ROW,22 ;Последняя строка экрана? JAE H20 ; нет - выйти INC ROW JMP H90 H20: MOV AX,0601H ;Прокрутка (скроллинг) CALL Q10SCR CALL Q20CURS H90: RET H10DISP ENDP ; Чтени дискового сектора: ; ----------------------- R10READ PROC NEAR MOV AH,3FH ;Функция чтения
Ассемблер для IBM PC. Программы. 130
MOV BX,HANDLE ;Устройство MOV CX,512 ;Длина LEA DX,SECTOR ;Буфер INT 21H MOV ENDCDE,AX RET R10READ 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 DH,ROW MOV DL,00 INT 10H RET Q20CURS ENDP ; Вывод сообщения об ошибке на диске: ; ---------------------------------- X10ERR PROC NEAR MOV AH,40H ;Функция вывода на экран MOV BX,01 ;Номер устройства MOV CX,18 ;Длина LEA DX,OPENMSG INT 21H MOV ENDCDE,O1 ;Индикатор ошибки RET X10ERR ENDP
CODESG ENDS END BEGIN
Ассемблер для IBM PC. Программы. 131
TITLE GETPATH (COM) Получить текущий каталог CODESG SEGMENT PARA 'Code' ASSUME CS:CODESG,DS:CODESG,ES:CODESG ORG 100H BEGIN: JMP SHORT MAIN ; ----------------------------------------------- PATHNAM DB 65 DUP(' ') ;Имя текущего пути доступа ; ----------------------------------------------- MAIN PROC NEAR MOV AH,19H ;Определить текущий диск INT 21H ADD AL,41H ;Заменить шест.номер MOV DL,AL ; на букву: 0=A, 1=B ... CAL B10DISP ;Выдать номер дисковода, MOV DL,':' CAL B10DISP ; двоеточие, MOV DL,'\' CAL B10DISP ; обратную косую


MOV AH,47H ;Получить текущий каталог MOV DL,00 LEA SI, PATHNAM INT 21H A10LOOP: CMP BYTE PTR [SI],0 ;Конец имени пути доступа JE A20 ; да - выйти MOV AL,[SI] ;Выдать на экран MOV DL,AL ; имя пути доступа CALL B10DISP ; побайтно INC SI JMP A10LOOP A20: RET ;Выход в DOS MAIN ENDP
B10DISP PROC NEAR MOV AH,02 ;в DL - адрес элемента INT 21H ;Функция вывода на экран RET B10DISP ENDP
CODESG ENDS END BEGIN
Ассемблер для IBM PC. Программы. 132
TITLE BIOREAD (COM) Чтение дискового сектора через BIOS CODESG SEGMENT PARA 'Code' ASSUME CS:CODESG,DS:CODESG,SS:CODESG,ES:CODESG ORG 100H BEGIN JMP MAIN ; --------------------------------------------------------- RECDIN DB 512 DUP(' ') ;Область ввода ENDCDE DB 00 CURADR DW 0304H ;Начало (дорожка/сектор) ENDADR DW 0501H ;Конец (дорожка/сектор) READMSG DB '*** Read error ***$' SIDE DB 00 ; --------------------------------------------------------- MAIN PROC NEAR MOV AX,0600H ;Функция прокрутки экрана A20LOOP: CALL Q10SCR ;Очистить экран CALL Q20CURS ;Установить курсор CALL C10ADDR ;Определить адрес на диске MOV CX,CURADR MOV DX,ENDADR CMP CX,DX ;Последний сектор? JE A90 ; да - выйти CALL F10READ ;Получить дисковую запись CMP ENDCDE,00 ;Ошибка чтения? JNZ A90 ; да - выйти CALL G10DISP ;Вывести сектор на экран JMP A20LOOP ;Повторить A90 RET ;Завершить программу MAIN ENDP ; Вычислить следующий адрес на диске: ; ---------------------------------- C10ADDR PROC NEAR MOV CX,CURADR ;Последняя дорожка/сектор CMP CL,10 ;Последний сектор? JNE C90 ; нет - выйти CMP SIDE,00 ;Обойти, если сторона = 0 JE C20 INC CH ;Увеличить номер дорожки C20: XOR SIDE,01 ;Сменить сторону MOV CL,01 ;Установить сектор = 1 MOV CURADR,CX C90: RET C10ADDR ENDP ; Чтение дискового сектора: ; ------------------------ F10READ PROC NEAR MOV AL,01 ;Число секторов MOV AH,02 ;Функция чтения LEA BX,RECDIN ;Адрес буфера MOV CX,CURADR ;Дорожка/сектор
Ассемблер для IBM PC. Программы. 133
MOV DH,SIDE ;Сторона MOV DL,01 ;Дисковод B INT 13H ;Выполнить ввод CMP AH,00 ;Ошибка чтения? JZ F90 ; нет - выйти MOV ENDCDE,01 ; да: CALL X10ERR ; ошибка чтения F90: INC CURADR ;Увеличить номер сектора RET F10READ ENDP ; Вывод сектора на экран: ; ---------------------- G10DISP PROC NEAR MOV AH,40H ;Функция вывода на экран MOV BX,01 ;Номер устройства MOV CX,512 ;Длина LEA DX,RECDIN INT 21H RET G10DISP ENDP ; Очистка экрана: ; -------------- Q10SCR PROC NEAR MOV AX,0600H ;Полный экран MOV BH,1EH ;Установить цвет MOV CX,0000 ;Функция прокрутки MOV DX,184FH INT 10H RET Q10SCR ENDP ; Установка курсора: ; ----------------- Q20CURS PROC NEAR MOV AH,02 ;Функция установки MOV BH,00 ; курсора MOV DX,0000 INT 10H RET Q20CURS ENDP ; Вывод сообщения об ошибке на диске: ; ---------------------------------- X10ERR PROC NEAR MOV AH,40H ;Функция вывода на экран MOV BH,01 ;Номер устройства MOV CX,18 ;Длина сообщения LEA DX,READMSG INT 21H RET X10ERR ENDP CODESG ENDS END BEGIN


Ассемблер для IBM PC. Программы. 134
TITLE PRTNAME (COM) Ввод и печать имен CODESG SEGMENT PARA PUBLIC 'CODE' ASSUME CS:CODESG,DS:CODESG,SS:CODESG,ES:CODESG ORG 100H BEGIN: JMP SHORT MAIN ; ----------------------------------------------------- NAMEPAR LABEL BYTE ;Список параметров MAXNLEN DB 20 ; максимальная длина имени NAMELEN DB ? ; длина введенного имени NAMEFLD DB 20 DUP(' ') ; введенное имя ;Строка заголовка: HEADG DB 'List of Employee Names Page ' PAGECTR DB '01',0AH,0AH FFEED DB 0CH ;Перевод страницы LFEED DB 0AH ;Перевод строки LINECTR DB 01 PROMPT DB 'Name? ' ; ----------------------------------------------------- MAIN PROC NEAR CALL Q10CLR ;Очистить экран CALL M10PAGE ;Установка номера страницы A2LOOP: MOV DX,0000 ;Установить курсор в 00,00 CALL Q20CURS CALL D10INPT ;Ввести имя CALL Q10CLR CMP NAMELEN,00 ;Имя введено? JE A30 ; если нет - выйти, CALL E10PRNT ; если да - подготовить ; печать JMP A20LOOP A30: MOV CX,01 ;Конец работы: LEA DX,FFEED ; один символ CALL P10OUT ; для прогона страницы, RET ; возврат в DOS MAIN ENDP ; Ввод имени с клавиатуры: ; ----------------------- D10INPT PROC NEAR MOV AH,40H ;Функция MOV BX,01 ; вывода на экран MOV CX,05 ; 5 символов LEA DX,PROMPT INT 21H ;Вызов DOS MOV AH,0AH ;Функция ввода с клавиатуры LEA DX,NAMEPAR INT 21H ;Вызов DOS RET D10INPT ENDP ; Подготовка для печати: ; ----------------------
Ассемблер для IBM PC. Программы. 135
E10PRNT PROC NEAR CMP LINECTR,60 ;Конец страницы? JB E20 ; нет - обойти CALL M10PAGE ; да - печатать заголовок E20: MOV CH,00 MOV CL,NAMELEN ;Число символов в имени LEA DX,NAMEFLD ;Адрес имени CALL P10OUT ;Печатать имя MOV CX,01 ;Один LEA DX,LFEED ; перевод строки CALL P10OUT INC LINECTR ;Увеличить счетчик строк E10PRNT ENDP ; Подпрограмма печати заголовка: ; ----------------------------- M10PAGE PROC NEAR CMP WORD PTR PAGECTR,3130H ;Первая страница? JE M30 ; да - обойти MOV CX,01 ; LEA DX,FFEED ; нет -- CALL P10OUT ; перевести страницу, MOV LINECTR,03 ; установить счетчик строк M30: MOV CX,36 ;Длина заголовка LEA DX,HEADG ;Адрес заголовка M40: CALL P10OUT INC PAGECTR+1 ;Увеличить счетчик страниц CMP PAGECTR+1,3AH ;Номер страницы = шест.xx3A? JNE M50 ; нет - обойти, MOV PAGECTR+1,30H ; да - перевести в ASCII INC PAGECTR M50: RET M10PAGE ENDP ; Подпрограмма печати: ; ------------------- P10OUT PROC NEAR ;CX и DX установлены MOV AH,40H ;Функция печати MOV BX,04 ;Номер устройства INT 21H ;Вызов DOS RET P10OUT ENDP ; Очистка экрана: ; -------------- Q10CLR PROC NEAR MOV AX,0600H ;Функция прокрутки MOV BH,60H ;Цвет (07 для ч/б) MOV CX,0000 ;От 00,00 MOV DX,184FH ; до 24,79 INT 10H ;Вызов BIOS RET Q10CLR ENDP ; Установка курсора (строка/столбец):


Ассемблер для IBM PC. Программы. 136
; ---------------------------------- Q20CURS PROC NEAR ;DX уже установлен MOV AH,02 ;Функция установки курсора MOV BH,00 ;Страница Э 0 INT 10H ;Вызов BIOS RET Q20CURS ENDP CODESG ENDS END BEGIN
Ассемблер для IBM PC. Программы. 137
TITLE PRINASK (COM) Чтение и печать дисковых записей CODESG SEGMENT PARA 'Code' ASSUME CS:CODESG,DS:CODESG,SS:CODESG,ES:CODESG ORG 100H BEGIN JMP MAIN ; --------------------------------------------------------- PATHPAR LABEL BYTE ;Список параметров для MAXLEN DB 32 ; ввода NAMELEN DB ? ; имени файла FILENAM DB 32 DUP(' ') SECTOR DB 512 DUP(' ') ;Область ввода для файла DISAREA DB 120 DUP(' ') ;Область вывода COUNT DW 00 ENDCDE DW 00 FFEED DB 0CH HANDLE DW 0 OPENMSG DB '*** Open error ***' PROMPT DB 'Name of file? ' ; ---------------------------------------------------------- MAIN PROC NEAR ;Основная программа CALL Q10SCR ;Очистить экран CALL Q20CURS ;Установить курсор A10LOOP: MOV ENDCDE,00 ;Начальная установка CALL C10PRMP ;Получить имя файла CMP NAMELEN,00 ;Есть запрос? JE A90 ; нет - выйти CALL E10OPEN ;Открыть файл, ; установить DTA CMP ENDCDE,00 ;Ошибка при открытии? JNE A80 ; да - повторить запрос CALL R10READ ;Прочитать первый сектор CMP ENDCDE,00 ;Конец файла, нет данных? JE A80 ; да - повторить запрос CALL G10XPER ;Распечатать сектор A80: JMP A10LOOP A90: RET MAIN ENDP ; Подпрограмма запроса имени файла: ; -------------------------------- C10PRMP PROC NEAR MOV AH,40H ;Функция вывода на экран MOV BX,01 MOV CX,13 LEA DX,PROMPT INT 21H MOV AH,0AH ;Функция ввода с клавиатуры LEA DX,PATHPAR INT 21H MOV BL,NAMELEN ;Записать MOV BH,00 ; 00 в конец
Ассемблер для IBM PC. Программы. 138
MOV FILENAM[BX],0 ; имени файла C90 RET C10PRMP ENDP ; Открытие дискового файла: ; ------------------------ E10OPEN PROC NEAR MOV AH,3DH ;Функция открытия MOV AL,00 ;Только чтение LEA DX,FILENAM INT 21H JNC E20 ;Проверить флаг CF CALL X10ERR ; ошибка, если установлен RET E20: MOV HANDLE,AX ;Сохранить номер файла MOV AX,2020H MOV CX,256 ;Очистить пробелами REP STOSW ; область сектора RET E100PEN ENDP ; Подготовка и печать данных: ; -------------------------- G10XFER PROC NEAR CLD ;Направление слева-направо LEA SI,SECTOR ;Начальная установка G20: LEA DI,DISAREA MOV COUNT,00 G30: LEA DX,SECTOR+512 CMP SI,DX ;Конец сектора? JNE G40 CALL R10READ ; да - читать следующий CMP ENDCDE,00 ;Конец файла? JE G80 ; да - выйти LEA SI,SECTOR G40: MOV BX,COUNT CMP BX,80 ;Конец области вывода? JB G50 ; нет - обойти MOV [DI+BX],0D0AH ; да - записать CR/LF CALL P10PRNT LEA DI,DISAREA ;Начало области вывода G50: LODSB ;Записать [SI] в AL, ; увеличить SI MOV BX,COUNT MOV [DI+BX],AL ;Записать символ INC BX CMP AL,1AH ;Конец файла? JE G80 ; да - выйти CMP AL,0AH ;Конец строки? JNE G60 ; нет - обойти,


Ассемблер для IBM PC. Программы. 139
CALL P10PRNT ; да - печатать JMP G20 G60: CMP AL,09H ;Символ табуляции? JNE G70 DEC BX ; да - установить BX: MOV BYTE PTR [DI+BX],20H ;Заменит TAB на пробел AND BX,0FFF8H ;Обнулить правые 8 бит ADD BX,08 ; и прибавить 8 G70: MOV COUNT,BX JMP G30 G80: MOV BX,COUNT ;Конец файла MOV BYTE PTR [DI+BX],0CH ;Прогон страницы CALL P10PRNT ;Печатать последнюю строку G90: RET G10XFER ENDP ; Подпрограммы печати: ; ------------------- P10PRNT PROC NEAR MOV AH,40H ;Функция печати MOV BX,04 MOV CX,COUNT ;Длина INC CX LEA DX,DISAREA INT 21H MOV AX,2020H ;Очистить область вывода MOV CX,60 LEA DI,DISAREA REP STOSW RET P10PRNT ENDP ; Подпрограмма чтения сектора: ; --------------------------- R10READ PROC NEAR MOV AH,3FH ;Функция чтения MOV BX,HANDLE ;Номер файла MOV CX,512 ;Длина MOV DX,SECTOR ;Буфер INT 21H MOV ENDCDE,AX RET R10READ ENDP ; Прокрутка экрана: ; ---------------- Q10SCR PROC NEAR MOV AX,0600H MOV BH,1EH ;Установить цвет MOV CX,0000 ;Прокрутка (сскроллинг) MOV DX,184FH INT 10H RET Q10SCR ENDP
Ассемблер для IBM PC. Программы. 140
; Подпрограмма установки курсора: ; ------------------------------ Q20CURS PROC NEAR MOV AH,02 ;Функция установки MOV BH,00 ; курсора MOV DX,00 INT 10H RET Q20CURS ENDP ; Вывод сообщения об ошибке: ; ------------------------- X10ERR PROC NEAR MOV AH,40H ;Функция вывода на экран MOV BX,01 ;Номер MOV CX,18 ;Длина LEA DX,OPENMSG ;Адрес сообщения INT 1H MOV NDCDE,01 ;Признак ошибки RET X10ERR ENDP CODESG ENDS END BEGIN
Ассемблер для IBM PC. Программы. 141
TITLE MACRO1 (EXE) Макрос для инициализации ; -------------------------------------------- INIT1 MACRO ASSUME CS:CSEG,DS:DSEG,SS:STACK,ES:DSEG PUSH DS SUB AX,AX PUSH AX MOV AX,DSEG MOV DS,AX MOV ES,AX ENDM ;Конец макрокоманды ; -------------------------------------------- 0000 STACK SEGMENT PARA STACK 'Stack' 0000 20 [ ???? ] DW 32 DUP(?) 0040 STACK ENDS ; -------------------------------------------- 0000 DSEG SEGMENT PARA 'Data' 0000 54 65 73 74 20 6F MESSGE DB 'Test of macro-instruction', 13 66 20 6D 61 63 72 6F 2D 69 6E 73 74 72 65 73 74 69 6F 6E 0D 001A DSEG ENDS ; -------------------------------------------- 0000 CSEG SEGMENT PARA 'Code' 0000 BEGIN PROC FAR INIT1 ;Макрокоманда 0000 1E + PUSH DS 0001 2B C0 + SUB AX,AX 0003 50 + PUSH AX 0004 B8 ---- R + MOV AX,DSEG 0007 8E D8 + MOV DS,AX 0009 8E C0 + MOV ES,AX 000B B4 40 MOV AH,40H ;Вывод на экран 000D BB 0001 MOV BX,01 ;Номер 0010 B9 001A MOV CX,26 ;Длина 0013 8D 16 0000 R LEA DX,MESSGE ;Сообщение 0017 CD 21 INT 21H 0019 CB RET 001A BEGIN ENDP 001A CSEG ENDS END BEGIN


Macros: N a m e Length INIT1. . . . . . . . . . . . . . . . 0004
Segments and Groups: N a m e Size Align Combine Class CSEG . . . . . . . . . . . . . . . . 001A PARA NONE 'CODE' DSEG . . . . . . . . . . . . . . . . 001A PARA NONE 'DATA' STACK. . . . . . . . . . . . . . . . 0040 PARA STACK 'STACK'
Ассемблер для IBM PC. Программы. 142
Symbols: N a m e Type Value Attr BEGIN. . . . . . . . . . . . . . . . F PROC 0000 CSEG Length=001A MESSAGE. . . . . . . . . . . . . . . L BYTE 0000 DSEG
Ассемблер для IBM PC. Программы. 143
TITLE MACRO2 (EXE) Использование параметров ; ------------------------------------------------ INIT2 MACRO CSNAME,DSNAME,SSNAME ASSUME CS:CSNAME,DS:DSNAME,SS:SSNAME,ES:DSNAME PUSH DS SUB AX,AX PUSH AX MOV AX,DSNAME MOV DS,AX MOV ES,AX ENDM ;Конец макрокоманды ; ------------------------------------------------ 0000 STACK SEGMENT PARA STACK 'Stack' 0000 20 [ ???? ] DW 32 DUP(?) 0040 STACK ENDS ; ------------------------------------------------ 0000 DSEG SEGMENT PARA 'Data' 0000 54 65 73 74 20 6F MESSAGE DB 'Test of macro', '$' 66 20 6D 61 63 72 6F 24 000E DSEG ENDS ; ------------------------------------------------ 0000 CSEG SEGMENT PARA 'Code' 0000 BEGIN PROC FAR INIT2 CSEG,DSEG,STACK 0000 1E + PUSH DS 0001 2B C0 + SUB AX,AX 0003 50 + PUSH AX 0004 B8 ---- R + MOV AX,DSEG 0007 8E D8 + MOV DS,AX 0009 8E C0 + MOV ES,AX 000B B4 09 MOV AH,09 ;Вывод на экран 000D 8D 16 0000 R LEA DX,MESSGE ;Сообщение 0011 CD 21 INT 21H 0013 CB RET 0014 BEGIN ENDP 0014 CSEG ENDS END BEGIN
Ассемблер для IBM PC. Программы. 144
TITLE MACRO3 (EXE) Директивы .LALL и .SALL ; ------------------------------------------------ INIT2 MACRO CSNAME,DSNAME,SSNAME ASSUME CS:CSNAME,DS:DSNAME,SS:SSNAME,ES:DSNAME PUSH DS SUB AX,AX PUSH AX MOV AX,DSNAME MOV DS,AX MOV ES,AX ENDM ; ------------------------------------------------ PROMPT MACRO MESSAGE ; Макрокоманда выводит на экран любые сообщения ;; Генерирует команды вызова DOS MOV AH,09 ;Вывод на экран LEA DX,MESSAGE INT 21H ENDM ; ------------------------------------------------ 0000 STACK SEGMENT PARA STACK 'Stack' 0000 20 [ ???? ] DW 32 DUP (?) 0040 STACK ENDS ; ------------------------------------------------ 0000 DATA SEGMENT PARA 'Data' 0000 43 75 73 74 6F 6D MESSG1 DB 'Customer name?', '$' 65 72 20 6E 61 6D 65 3F 24 000F 43 75 73 74 6F 6D MESSG2 DB 'Customer address?', '$' 65 72 20 61 64 64 72 65 73 73 3F 24 0021 DATA ENDS ; ------------------------------------------------ 0000 CSEG SEGMENT PARA 'Code' 0000 BEGIN PROC FAR .SALL INIT2 CSEG,DATA,STACK PROMPT MESSG1 .LALL PROMPT MESSG2 + ; Макрокоманда выводит на экран любые сообщения 0013 B4 09 + MOV AH,09 ;Вывод на экран 0015 8D 16 000F R + LEA DX,MESSG2 0019 CD 21 + INT 21H 001B CB RET 001C BEGIN ENDP 001C CSEG ENDS END BEGIN


Ассемблер для IBM PC. Программы. 145
TITLE MACRO4 (COM) Использование директивы LOCAL ; ------------------------------------------------- DIVIDE MACRO DIVIDEND,DIVISOR,QUOTIENT LOCAL COMP LOCAL OUT ; AX=делимое, BX=делитель, CX=частное MOV AX,DIVIDEND ;Загрузить делимое MOV BX,DIVISOR ;Загрузить делитель SUB CX,CX ;Регистр для частного COMP: CMP AX,BX ;Делимое < делителя? JB OUT ; да - выйти SUB AX,BX ;Делимое - делитель INC CX ;Частное + 1 JMP COMP OUT: MOV QUOTIENT,CX ;Записать результат ENDM ; ------------------------------------------------ 0000 CSEG SEGMENT PARA 'Code' ASSUME CS:CSEG,DS:CSEG,SS:CSEG,ES:CSEG 0100 ORG 100H 0100 EB 06 BEGIN: JMP SHORT MAIN ; ------------------------------------------------ 0102 0096 DIVDND DW 150 ;Делимое 0104 001B DIVSOR DW 27 ;Делитель 0106 ???? QUOTNT DW ? ;Частное ; ------------------------------------------------ 0108 MAIN PROC NEAR .LALL DIVIDE DIVDND,DIVSOR,QUOTNT + ; AX=делимое, BX=делитель, CX=частное 0108 A1 0102 R + MOV AX,DIVDND ;Загрузить делимое 010B 8B 1E 0104 R + MOV BX,DIVSOR ;Загрузить делитель 010F 2B C9 + SUB CX,CX ;Регистр для частного 0111 + ??0000: 0111 3B C3 + CMP AX,BX ;Делимое < делителя? 0113 72 05 + JB ??0001 ; да - выйти 0115 2B C3 + SUB AX,BX ;Делимое - делитель 0117 41 + INC CX ;Частное + 1 0118 EB F7 + JMP ??0000 011A + ??0001: 011A 89 0E 0106 R + MOV QUOTNT,CX ;Записать результат 011E C3 RET 011F MAIN ENDP 011F CSEG ENDS END BEGIN
Ассемблер для IBM PC. Программы. 146
TITLE MACRO5 (EXE) Проверка директивы INCLUDE EDIF ; ------------------------------------------------ 0000 STACK SEGMENT PARA STACK 'Stack' 0000 20 [????] DW 32 DUP(?) 0040 STACK ENDS ; ------------------------------------------------ 0000 DATA SEGMENT PARA 'Data' 0000 54 65 73 74 20 6F MESSGE DB 'Test of macro','$' 66 20 6D 61 63 72 6F 24 000E DATA ENDS ; ------------------------------------------------ 0000 CSEG SEGMENT PARA 'Code' 0000 BEGIN PROC FAR INIT CSEG,DATA,STACK 0000 1E + PUSH DS 0001 3B C0 + SUB AX,AX 0003 50 + PUSH AX 0004 B8 ---- R + MOV AX,DATA 0007 8E D8 + MOV DS,AX 0009 8E C0 + MOV ES,AX PROMPT MESSGE 000B B4 09 + MOV AH,09 ;Вывод на экран 000D 8D 16 0000 R + LEA DX,MESSGE 0011 CD 21 + INT 21H 0013 CB RET 0014 BEGIN ENDP 0014 CSEG ENDS END BEGIN


Ассемблер для IBM PC. Программы. 147
TITLE MACRO6 (COM) Проверка дирктив IF и IFNDEF ; ------------------------------------------------ DIVIDE MACRO DIVIDEND,DIVISOR,QUOTIENT LOCAL COMP LOCAL OUT CNTR = 0 ; AX-делимое, BX-делитель, CX-частное IFNDEF DIVIDEND ; Делитель не определен CNTR = CNTR +1 ENDIF IFNDEF DIVISOR ; Делимое не определено CNTR = CNTR +1 ENDIF IFNDEF QUOTIENT ; Частное не определено CNTR = CNTR +1 ENDIF IF CNTR ; Макрорасширение отменено EXITM ENDIF MOV AX,DIVIDEND ;Загрузка делимого MOV BX,DIVISOR ;Загрузка делителя SUB CX,CX ;Регистр для частного COMP: CMP AX,BX ;Делимое < делителя? JB OUT ; да - выйти SUB AX,BX ;Делимое - делитель INC CX ;Частное + 1 JMP COMP OUT: MOV QUOTIENT,CX ;Запись результата ENDM ; ------------------------------------------------ 0000 CSEG SEGMENT PARA 'Code' ASSUME CS:CSEG,DS:CSEG,SS:CSEG,ES:CSEG 0100 ORG 100H 0100 EB 06 BEGIN: JMP SHORT MAIN ; ------------------------------------------------ 0102 0096 DIVDND DW 150 0104 001B DIVSOR DW 27 0106 ???? QUOTNT DW ? ; ------------------------------------------------ 0108 MAIN PROC NEAR .LALL DIVIDE DIVDND,DIVSOR,QUOTNT = 0000 + CNTR = 0 + ; AX-делимое, BX-делитель, CX-частное + ENDIF + ENDIF
Ассемблер для IBM PC. Программы. 148
+ ENDIF + ENDIF 0108 A1 0102 R + MOV AX,DIVDND ;Загрузка делимого 0108 8B 1E 0104 R + MOV BX,DIVSOR ;Загрузка делителя 010F 2B C9 + SUB CX,CX ;Регистр для частного 0111 + ??0000: 0111 3B C3 + CMP AX,BX ;Делимое < делителя? 0113 72 05 + JB ??0001 ; да - выйти 0115 2B C3 + SUB AX,BX ;Делимое - делитель 0117 41 + INC CX 0118 EB F7 + JMP ??0000 011A + ??0001: 011A 89 0E 0106 R + MOV QUOTNT,CX ;Запись результата DIVIDE DIDND,DIVSOR,QUOT = 0000 + CNTR = 0 + ; AX-делимое, BX-делитель, CX-частное + IFNDEF DIDND + ; Делитель не определен = 0001 + CNTR = CNTR +1 + ENDIF + ENDIF + IFNDEF QUOT + ; Частное не определено = 0002 + CNTR = CNTR +1 + ENDIF + IF CNTR + ; Макрорасширение отменено + EXITM 011E C3 RET 011F MAIN ENDP 011F CSEG ENDS END BEGIN
Ассемблер для IBM PC. Программы. 149


TITLE MACRO7 (COM) Проверка директивы IFIDN ; -------------------------------------------- MOVIF MACRO TAG IFIDN <&TAG>,<B>
REP MOVSB EXITM ENDIF IFIDN <&TAG>,<W>
REP MOVSW ELSE ; Не указан параметр B или W, ; по умолчанию принято B REP MOVSB ENDIF ENDM ; -------------------------------------------- 0000 CSIG SEGMENT PARA 'Code' ASSUME CS:CSEG,DS:CSEG,SS:CSEG,ES:CSEG 0100 ORG 100H 0100 EB 00 BEGIN: JMP SHORT MAIN ; ... 0102 MAIN PROC NEAR .LALL MOVIF B + IFIDN <B>,<B>
0102 F3/A4 + REP MOVSB + EXITM MOVIF W + ENDIF + IFIDN <W>, <W>
0104 F3/A5 + REP MOVSW + ENDIF MOVIF + ENDIF + ELSE + ; Не указан параметр B или W, + ; по умолчанию принято B 0106 F3/A4 + REP MOVSB + ENDIF 0108 C3 RET 0109 MAIN ENDP 0109 CSEG ENDS END BEGIN
Ассемблер для IBM PC. Программы. 150
+-----------+ +-----------+ | Основная | | Основная | | программа | | программа | +-----+-----+ +-----+-----+ | | | | +------------+------------+ +------+------+ | | | | | | | | | | +--------+ +--------+ +--------+ +--------+ +--------+ | П/П 1 | | П/П 2 | | П/П 3 | | П/П 1 | | П/П 2 | +---------+ +---------+ +---------+ +----+----+ +---------+ | | +--------+ | П/П 3 | +---------+
Ассемблер для IBM PC. Программы. 151
+---------------------------------------+ | EXTRN SUBPROG:FAR | | MAINPROG: . | | . | | CALL SUBPROG | | . | | . | +---------------------------------------+ | PUBLIC SUBPROG | | SUBPROG: . | | . | | . | | RET | +---------------------------------------+
Ассемблер для IBM PC. Программы. 152
page 60,132 TITLE CALLMULL1 (EXE) Вызов подпрограммы умножения EXTRN SUBMUL:FAR ;----------------------------------------------- 0000 STACKSG SEGMENT PARA STACK 'Stack' 0000 40 [ ???? ] DW 64 DUP(?) 0080 STACKSG ENDS ;----------------------------------------------- 0000 DATASG SEGMENT PARA 'Data' 0000 0140 QTY DW 0140H 0002 2500 PRICE DW 2500H 0004 DATASG ENDS ;----------------------------------------------- 0000 CODESG SEGMENT PARA 'Code' 0000 BEGIN PROC FAR ASSUME CS:CODESG,DS:DATASG,SS:STACKSG 0000 1E PUSH DS 0001 2B C0 SUB AX,AX 0003 50 PUSH AX 0004 B8 ---- R MOV AX,DATASG 0007 8E D8 MOV DS,AX 0009 A1 0002 R MOV AX,PRICE ;Загрузить стоимость 000C 8B 1E 0000 R MOV BX,QTY ; и количество 0010 9A 0000 ---- E CALL SUBMUL ;Вызвать подпрограмму 0015 CB RET 0016 BEGIN ENDP 0016 CODESG ENDS END BEGIN


Segments and Groups: N a m e Size Align Combine Class CODESG . . . . . . . . . . . . 0016 PARA NONE 'CODE' DATASG . . . . . . . . . . . . 0004 PARA NONE 'DATA' STACKSG. . . . . . . . . . . . 0080 PARA STACK 'STACK'
Symbols: N a m e Type Value Attr BEGIN. . . . . . . . . . . . . F PROC 0000 CODESG Length=0016 PRICE. . . . . . . . . . . . . L WORD 0002 DATASG QTY. . . . . . . . . . . . . . L WORD 0000 DATASG SUBMUL . . . . . . . . . . . . L FAR 0000 External
page 60,132 TITLE SUBMUL Подпрограмма для умножения ;----------------------------------------------- 0000 CODESG SEGMENT PARA 'Code' 0000 SUBMUL PROC FAR ASSUME CS:CODESG PUBLIC SUBMUL 0000 F7 E3 MUL BX ;AX-стоимость, BX-количество 0002 CB RET ;Произведение в DX:AX
Ассемблер для IBM PC. Программы. 153
0003 SUBMUL ENDP 0003 CODESG ENDS END SUBMUL
Segments and groups: N a m e Size Align Combine Class CODESG . . . . . . . . . . . . 0003 PARA NONE 'CODE'
Symbols: N a m e Type Value Attr SUBMUL . . . . . . . . . . . . F PROC 0000 CODESG Clobal Length=0003
LINK IBM Personal Computer Linker Version 2.30 (C) Copyright IBM Corp 1981, 1985 Object Modules: B:CALLMUL1+B:SUBMUL1 Run File: [B:CALLMUL1.EXE]: <return>
List File:[NUL.MAP]: CON Libraries [.LIB]: <return>
Start Stop Length Name Class
00000H 00015H 0016H CODESG CODE <--Примечание: 2 кодовых 00020H 00022H 0003H CODESG CODE <-- сегмента 00030H 00033H 0004H DATASG DATA 00040H 000BFH 0080H STACKSG STACK
Program entry point at 0000:0000
Ассемблер для IBM PC. Программы. 154
page 60,132 TITLE CALLMUL2 (EXE) Вызов подпрограммы умножения EXTERN SUBMUL:FAR ;---------------------------------------------- 0000 STACKSG SEGMENT PARA STACK 'Stack' 0000 40 [????] DW 64 DUP(?) 0080 STACKSG ENDS ;---------------------------------------------- 0000 DATASG SEGMENT PARA 'Data' 0000 0140 QTY DW 0140H 0002 2500 PRICE DW 2500H 0004 DATASG ENDS ;---------------------------------------------- 0000 CODESG SEGMENT PARA PUBLIC 'Code' 0000 BEGIN PROC FAR ASSUME CS:CODESG,DS:DATASG,SS:STACKSG 0000 1E PUSH DS 0001 2B C0 SUB AX,AX 0003 50 PUSH AX 0004 B8 ---- R MOV AX,DATASG 0007 8E D8 MOV DS,AX 0009 A1 0002 R MOV AX,PRICE ;Загрузить стоимость 000C 8B 1E 0000 R MOV BX,QTY ; и количество 0010 9A 0000 ---- E CALL SUBMUL ;Вызвать подпрограмму 0015 CB RET 0016 BEGIN ENDP


0016 CODESG ENDS END BEGIN
Segments and Group: N a m e Size Align Combine Class CODESG . . . . . . . . . . . . .0016 PARA PUBLIC 'CODE' DATASG . . . . . . . . . . . . .0004 PARA NONE 'DATA' STACKSG. . . . . . . . . . . . .0080 PARA STACK 'STACK'
Symbols: N a m e Type Value Attr BEGIN. . . . . . . . . . . . . F PROC 0000 CODESG Lenght=0016 PRICE. . . . . . . . . . . . . L WORD 0002 DATASG QTY. . . . . . . . . . . . . . L WORD 0000 DATASG SUBMUL . . . . . . . . . . . . L FAR 0000 External
page 60,132 TITLE SUBMUL2 Вызываемая подпрограмма умножения ;---------------------------------------------- 0000 CODESG SEGMENT PARA PUBLIC 'CODE' 0000 SUBMUL PROC FAR ASSUME CS:CODESG PUBLIC SUBMUL 0000 F7 E3 MUL BX ;AX-стоимость, BX-количество
Ассемблер для IBM PC. Программы. 155
0002 CB RET ;Произведение в DX:AX 0003 SUBMUL ENDP 0003 CODESG ENDS END SUBMUL
Segments and Groups: N a m e Size Align Combine Class CODESG. . . . . . . . . . . . . 0003 PARA PUBLIC 'CODE'
Symbols: N a m e Type Value Attr SUBMUL. . . . . . . . . . . . .F PROC 0000 CODESG Global Length=0003
LINK IBM Personal Computer Linker Version 2.30 (C) Copyright IBM Corp 1981, 1985 Object Modules: B:CALLMUL2+B:SUBMUL2 Run File: [B:CALLMUL2.EXE]: <return>
List File: [NUL.MAP]: CON Libraries [.LIB]: <return>
Start Stop Length Name Class 00000H 00022H 0023H CODESG CODE <-- Примечание: 1 сегмент кода 00030H 00033H 0004H DATASG DATA 00040H 000BFH 0080H STACKSG STACK
Program entry point at 0000:0000
Ассемблер для IBM PC. Программы. 156
page 60,132 TITLE CALLMUL3 (EXE) Вызов подпрограммы ; для умножения EXTRN SUBMUL:FAR PUBLIC QTY,PRICE ;------------------------------------------------- 0000 STACKSG SEGMENT PARA STACK 'Stack' 0000 40 [????] DW 64 DUP(?) 0080 STACKSD ENDS ;------------------------------------------------- 0000 DATASG SEGMENT PARA PUBLIC 'Data' 0000 0140 QTY DW 0140H 0002 2500 PRICE DW 2500H 0004 DATASG ENDS ;------------------------------------------------- 0000 CODESG SEGMENT PARA PUBLIC 'Code' 0000 BEGIN PROC FAR ASSUME CS:CODESG,DS:DATASG,SS:STACKSG 0000 1E PUSH DS 0001 2B C0 SUB AX,AX 0003 50 PUSH AX 0004 B8 ---- R MOV AX,DATASG 0007 8E D8 MOV DS,AX 0009 9A 0000 ---- E CALL SUBMUL ;Вызвать подпрограмму 000E CB RET 000F BEGIN ENDP


000F CODESG ENDS END BEGIN
Segments and Groups: N a m e Size Align Combine Class CODESG . . . . . . . . . . . . 000F PARA PUBLIC 'CODE' DATASG . . . . . . . . . . . . 0004 PARA PUBLIC 'DATA' STACKSG. . . . . . . . . . . . 0080 PARA STACK 'STACK'
Symbols: N a m e Type Value Attr BEGIN. . . . . . . . . . . . . F PROC 0000 CODESG Length=000F PRICE. . . . . . . . . . . . . L WORD 0002 DATASG Global QTY. . . . . . . . . . . . . . L WORD 0000 DATASG Global SUBMUL . . . . . . . . . . . . L FAR 0000 External
page 60,132 TITLE SUBMUL Подпрограмма для умножения EXTRN QTY:WORD,PRICE:WORD ;------------------------------------------------- 0000 CODESG SEGMENT PARA PUBLIC 'CODE' 0000 SUBMUL PROC FAR ASSUME CS:CODESG PUBLIC SUBMUL
Ассемблер для IBM PC. Программы. 157
0000 A1 0000 E MOV AX,PRICE 0003 8B 1E 0000 E MOV BX,QTY 0007 F7 E3 MUL BX ;Произведение в DX:AX 0009 CB RET 000A SUBMUL ENDP 000A CODESG ENDS END SUBMUL
Segments and Groups: N a m e Size Align Combine Class CODESG . . . . . . . . . . . . 000A PARA PUBLIC 'CODE'
Symbols: N a m e Type Value Attr PRICE. . . . . . . . . . . . . V WORD 0000 External QTY. . . . . . . . . . . . . . V WORD 0000 External SUBMUL . . . . . . . . . . . . F PROC 0000 CODESG Global Length=000A
LINK IBM Personal Computer Linker Version 2.30 (C) Copyright IBM Corp 1981, 1985 Object Modules: B:CALLMUL3+B:SUBMUL3 Run File: [B:CALLMUL3.EXE]: <return>
List File: [NUL.MAP]: CON Libraries [.LIB]: <return>
Start Stop Length Name Class
00000H 00019H 001AH CODESG CODE 00030H 00033H 0004H DATASG DATA 00040H 000BFH 0080H STACKSG STACK
PROGRAM entry point at 0000:0000
Ассемблер для IBM PC. Программы. 158
page 60,132 TITLE CALLMULL4 (EXE) Передача параметров ; в подпрограмму EXTRN SUBMUL:FAR ;------------------------------------------------- 0000 STACKSG SEGMENT PARA STACK 'Stack' 0000 40 [ ???? ] DW 64 DUP(?) 0080 STACKSG ENDS ;------------------------------------------------- 0000 DATASG SEGMENT PARA 'Data' 0000 0140 QTY DW 0140H 0002 2500 PRICE DW 2500H 0004 DATASG ENDS ;------------------------------------------------- 0000 CODESG SEGMENT PARA PUBLIC 'Code' 0000 BEGIN PROC FAR ASSUME CS:CODESG,DS:DATASG,SS:STACKSG 0000 1E PUSH DS 0001 2B C0 SUB AX,AX 0003 50 PUSH AX 0004 B8 ---- R MOV A,DATASG 0007 8E D8 MOV DS,AX 0009 FF 36 0002 R PUSH PRICE 000D FF 36 0000 R PUSH QTY 0011 9A 0000 ---- E CALL SUBMUL ;Вызвать подпрограмму 0016 CB RET 0017 BEGIN ENDP 0017 CODESG ENDS END BEGIN


Segments and Groups: N a m e Sise Align Combine Class CODESG . . . . . . . . . . . . 0017 PARA NONE 'CODE' DATASG . . . . . . . . . . . . 0004 PARA NONE 'DATA' STACKSG. . . . . . . . . . . . 0080 PARA STACK 'STACK'
Symbols: N a m e Type Value Attr BEGIN. . . . . . . . . . . . . F PROC 0000 CODESG Length=0017 PRICE. . . . . . . . . . . . . L WORD 0002 DATASG QTY. . . . . . . . . . . . . . L WORD 0000 DATASG SUBMUL . . . . . . . . . . . . L FAR 0000 External
page 60,132 TITLE SUBMUL Вызываемая подпрограмма умножения 0000 CODESG SEGMENT PARA PUBLIC 'Code' 0000 SUBMUL PROC FAR ASSUME CS:CODESG PUBLIC SUMBUL 0000 55 PUSH BP 0001 8P EC MOV BP,SP
Ассемблер для IBM PC. Программы. 159
0003 8B 46 08 MOV AX,[BP+8] ;Стоимость 0006 8B 5E 06 MOV BX,[BP+6] ;Количество 0009 F7 E3 MUL BX ;Произведение в DX:AX 000B 5D POP BP 000F SUMBUL ENDP 000F CODESG ENDS END
Segments and Groups: N a m e Size Align Combine Class CODESG . . . . . . . . . . . . 000F PARA PUBLIC 'CODE'
Symbols: N a m e Type Value Attr SUBMUL . . . . . . . . . . . . F PROC 0000 CODESG Global Length=000F
LINK IBM Personal Computer Linker Version 2.30 (C) Copyright IBM Corp 1981, 1985 Object Modules: B:CALLMUL4+B:SUBMUL4 Run File: [B:CALLMUL4.EXE]: <return>
List File: [NUL.MAP]: CON Libraries [.LIB]: <return>
Start Stop Length Name Class
00000H 00019H 001AH CODESG CODE 00030H 00033H 0004H DATASG DATA 00040H 000BFH 0080H STACKSG STACK
PROGRAM entry point at 0000:0000
Ассемблер для IBM PC. Программы. 160
LOAD"D:BASTEST.BAS
LIST 010 CLEAR ,32768! 020 ' для BLOAD 030 ' для DEFSEG 040 ' для точки входа в CALL 050 ' для вызова ASM-модуля 060 FOR N = 1 TO 5 070 INPUT "Hours "; H 080 INPUT "Rate "; R 090 W = H * R 100 PRINT "Wage = " W 110 NEXT N 120 END
TITLE LINKBAS Ассемблерная подпрограмма, вызываемая из BASIC CODESG SEGMENT PARA 'CODE' ASSUME CS:CODESG CLRSCRN PROC FAR PUSH BP ;Сохранить BP MOV BP,SP ;База списка параметров MOV AX,0600H ;Функция прокрутки MOV BH,07 ; всего MOV CX,0000 ; экрана MOV DX,184FH INT 10H POP BP RET ;Завершить подпрограмму CLRSCRN ENDP CODESG ENDS END


Ассемблер для IBM PC. Программы. 161
D>LINK
IBM Personal Computer Linker Version 2.30 (C) Copyright IBM Corp. 1981, 1985
Object Modules [.OBJ]: LINKBAS Run File [LINKBAS.EXE]: LINKBAS/HIGH List File [NUL.MAP]: CON Libraries [.LIB]: Warning: no stack segment
Start Stop Length Name Class 00000H 00011H 00012H CODESG CODE D>DEBUG BASIC.COM -R AX=0000 BX=0000 CX=0012 DX=0000 SP=FFFF BP=0000 SI=0000 DI=0000 DS=1410 ES=1410 SS=1410 CS=1410 IP=0100 NV UP EI PL NZ NA PO NC 1410:0100 E9E03E JMP 3FE3 -N D:LINKBAS.EXE -L -R AX=FFA3 BX=0000 CX=0012 DX=0000 SP=0000 BP=0000 SI=0000 DI=0000 DS=1410 ES=1410 SS=9FE0 CS=9FE0 IP=0000 NV UP EI PL NZ NA PO NC 9FE0:0000 55 -R SS SS 9FE0 :1410 -R CS CS 9FE0 :1410 -R IP IP 0000 :0100 -G Ok DEF SEG = &H9EF0 Ok BSAVE "D:CLRSCREEN.MOD",0,&H12 Ok SYSTEM Program terminated normally -Q D>BASIC IBM Personal Computer Basic Ver4sion D3.10 Copyright IBM Corp. 1981, 1985 61310 Bytes free Ok LOAD"D:BASTEST.BAS Ok 20 BLOAD "D:CLRSCREEN.MOD" 30 DEF SEG = &H9FE0 40 CLRSCRN = 0
Ассемблер для IBM PC. Программы. 162
50 CALL CLRSCRN LIST
10 CLEAR ,32768! 20 BLOAD "D:CLRSCRN.MOD" 30 DEF SEG = &H9FE0 40 CLRSCRN = 0 50 CALL CLRSCRN 60 FOR N = 1 TO 5 70 INPUT "HOURS"; H 80 INPUT "rATE"; R 90 W = H * R 100 PRINT "WAGE = " W 110 NEXT N 120 END Ok
program pascall ( input, output );
procedure move_cursor( const row: integer; const col: integer ); extern; var temp_row: integer; temp_col: integer;
begin write( 'Enter cursor row: ' ); readln( temp_row );
write( 'Enter cursor column:' ); readln( temp_col );
move_cursor( temprow, temp_col ); write( 'New cursor location' ); end.
TITLE MOVCUR Подпрограмма на ассемблере, ; вызываемая из программы на Паскале PUBLIC MOVE_CURSOR ;---------------------------------------------------------- ; MOVE_CURSOR: Устанавливает курсор ; по переданным параметрам ; Параметры: const row Строка и столбец ; const col для установки курсора ; Возвращаемое значение: Отсутствует ;---------------------------------------------------------- CODESEG SEGMENT PARA PUBLIC 'CODE'


MOVE_CURSOR PROC FAR ASSUME CS:CODESEG
Ассемблер для IBM PC. Программы. 163
ROWWPAR EQU 8 ;Параметр "строка" COLPAR EQU 6 ;Параметр "столбец"
PUSH BP ;Сохранить регистр BP MOV BP,SP ;Установить BP на параметры
MOV SI,[BP+ROWPAR] ;SI указывает на строку MOV DH,[SI] ;Поместить столбец в DL
MOV AH,02 ;Функция установки курсора SUB BH,BH ;Страница #0 INT 10H
POP BP ;Вернуться RET 4 ; в вызывающую программу MOVE_CURSOR ENDP CODESEG ENDS END
Адрес начала Программа
00000 Таблица векторов прерываний (см. гл. 23)
00400 Область связи с постоянной памятью (ROM)
00500 Область связи с операционной системой (DOS)
00600 IBMBIO.COM Буфер каталога Дисковый буфер Блок параметров дисковода/таблица распределения файлов (FAT, одна для каждого дисковода)
XXXX0 Резидентная часть командного процессора COMMAND.COM
XXXX0 Область памяти для программ (типа COM или EXE)
XXXX0 Пользовательский стек для COM-программ (256 байтов)
XXXX0 Транзитная часть командного процессора COMMAND.COM (записывается в старшие адреса памяти).
TITLE EXDOS (EXE) Функция DOS 4BH для выполнения DIR CSEG GMENT PARA 'Code' ASSUME CS:CSEG,DS:CSEG,ES:CSEG BEGIN: JMP SHORT MAIN ;---------------------------------------------------------- PARAREA DW ? ;Адрес строки вызова
Ассемблер для IBM PC. Программы. 164
DW OFFSET DIRCOM ;Указатель ; на командную строку DW CSEG DW OFFSET FCB1 ;Указатель на FCB2 DW CSEG
DIRCOM DB 17,'/C DIR D:',13,0 FCB1 DB 16 DUP(0) FCB2 DB 16 DUP(0) PROGNAM DB 'D:COMMAND.COM',0 ; --------------------------------------------------------- MAIN PROC FAR MOV AH,4AH ;Получить 64K памяти MOV BH,100H ; в параграфах INT 21H JC E10ERR ;Нет памяти?
MOV DI,2CH ;Получить сегментный адрес MOV AX,[DI] ; строки вызова LEA SI,PARAREA ; и записать его в MOV [SI],AX ; 1 слово блока параметров MOV AX,CS ;Загрузить в DS и ES MOV DS,AX ; адрес CSEG MOV ES,AX
MOV AH,4BH ;Функция загрузки MOV AL,00 ; и выполнения LEA BX,PARAREA ; COMMAND.COM LEA DX,PROGNAM INT 21H ;Вызвать DOS JC E20ERR ;Ошибка выполнения? MOV AL,00 ;Нет кода ошибки JMP X10XIT 0ERR: MOV AL,01 ;Код ошибки 1 JMP X10XIT 0ERR: MOV AL,02 ;Код ошибки 2 JMP X10XIT 0XIT: MOV AH,4CH ;Функция завершения INT 21H ;Вызвать DOS IN ENDP EG ENDS END


Адрес Функция прерывания (шест.) (шест.)
0-3 0 Деление на ноль 4-7 1 Пошаговый режим (трассировка для DEBUG)
Ассемблер для IBM PC. Программы. 165
8-B 2 Немаскируемое прерывание (NMI) C-F 3 Точка останова в потоке команд (для DEBUG) 10-13 4 Переполнение регистров АЛУ 14-17 5 Печать экрана 18-1F Зарезервировано 20-23 8 Сигнал от таймера 24-27 9 Сигнал от клавиатуры 28-37 A,B,C,D Используются для AT 38-3B E Сигнал от дисковода 3C-3F F Обслуживание принтера 40-43 10 Управление экраном (см. гл. 8,9,10) 44-47 11 Запрос списка оборудования (см. гл. 9) 48-4B 12 Запрос размера физической памяти (см. гл. 2) 4C-4F 13 Управление дисковым вводом-выводом (гл. 18) 50-53 14 Управление коммуникационным вводом-выводом 54-57 15 Управление магнитофоном и спец.функции для AT 58-5B 16 Управление вводом с клавиатуры (гл. 9) 5C-5F 17 Вывод на принтер (гл. 19) 60-63 18 Обращение к BASIC в ПЗУ (ROM) 64-67 19 Перезагрузка системы 68-6B 1A Запрос и установка времени и даты 6C-6F 1B Получение управления по прерыванию с клавиатуры 70-73 1C Получение управления по прерыванию от таймера 74-77 1D Адрес таблицы параметров инициализации дисплея 78-7B 1E Адрес таблицы параметров дисковода 7C-7F 1F Адрес таблицы графических символов 80-83 20 DOS Нормальное завершение программы 84-87 21 DOS Обращение к функциям DOS 88-8B 22 DOS Адрес подпрограммы обработки завершения 8C-8F 23 DOS Адрес подпрограммы реакции на Ctrl+Break 90-93 24 DOS Вектор подпрограммы реакции на фатальную ошибку 94-97 25 DOS Абсолютное чтение секторов диска 98-9B 26 DOS Абсолютная запись на сектора диска 9C-9F 27 DOS Завершение программы, оставляющее ее резидентом A0-FF 28-3F DOS Операции DOS 100-1FF 40-7F Зарезервировано 200-217 80-85 Зарезервировано для BASIC 218-3C3 86-F0 Используется BASIC-интерпретатором 3C4-3FF F1-FF Зарезервировано
Примечание: прерывания 00-1F для BIOS, 20-FF для DOS и BASIC
TITLE RESIDENT (COM) Резидентная программа для очистки ; экрана и установки цвета при нажатии ; Alt+Left Shift ;----------------------------------------------------------


INTTAB SEGMENT AT 0H ;Таблица векторов прерываний: ORG 9H*4 ; адрес для Int 9H, KBADDR LABEL DWORD ; двойное слово INTTAB ENDS
Ассемблер для IBM PC. Программы. 166
;----------------------------------------------------------
ROMAREA SEGMENT AT 400H ;Область параметров BIOS: ORG 17H ; адрес флага клавиатуры, KBFLAG DB ? ; состояние Alt + Shift ROMAREA ENDS ;----------------------------------------------------------
CSEG SEGMENT PARA ;Сегмент кода ASSUME CS:CS ORG 100H BEGIN: JMP INITZ ;Выполняется только один раз
KBSAVE DD ? ;Для адреса INT 9 BIOS ; Очистка экрана и установка цветов: ; --------------------------------- COLORS PROC NEAR ;Процедура выполняется PUSH AX ; при нажатии Alt+Left Shift PUSH BX PUSH CX ;Сохранить регистры PUSH DX PUSH SI PUSH DI PUSH DS PUSH ES PUSHF CALL KBSAV ;Обработать прерывание ASSUME DS:ROMAREA MOV AX,ROMAREA ;Установить DS для MOV DS,AX ; доступа к состоянию MOV AL,KB AG ; Alt+Left Shift CMP AL,00001010B ;Alt+Left Shift нажаты? JNE EXIT ; нет - выйти MOV AX,0600H ;Функция прокрутки MOV BH,61H ;Установить цвет MOV CX,00 MOV DX,18 FH INT 10H EXIT: POP ES ;Восстановить регистры POP DS POP DI POP SI POP DX POP CX POP BX POP AX IRET ;Вернуться COLORS ENDP
; Подпрограмма инициализации: ; -------------------------- INITZE PROC NEAR ;Выполнять только один раз
Ассемблер для IBM PC. Программы. 167
ASSUME DS:INTTAB PUSH DS ;Обеспечить возврат в DOS MOV AX,INTTAB ;Установить сегмент данных MOV DS,AX CLI ;Запретить прерывания ;Замена адреса обработчика: MOV AX,WORD PTR KBADDR ;Сохранить адрес MOV WORD PTR KBSAVE,AX ; BIOS MOV AX,WORD PTR BADDR+2 MOV WORD PTR KBSAVE+2,AX MOV WORD PTR KBADDR,OFFSET COLORS ;Заменить MOV WORD PTR KBADDR+2,CS ; адрес BIOS STI ;Разрешить прерывания MOV DX,OFFSET INITZE ;Размер программы INT 27H ;Завершить и остаться INITZE ENDP ; резидентом
CSEG ENDS END BEGIN
TITLE SOUND (COM) Процедура для генерации звука SOUNSG SEGMENT PARA 'Code' ASSUME CS:SOUNG,DS:SOUNG,SS:SOUNG ORG 100H BEGIN: JMP SHORT MAIN ; ------------------------------------------------------- DURTION DW 1000 ;Время звучания TONE DW 256H ;Высота (частота) звука ; ------------------------------------------------------- MAIN PROC NEAR IN AL,61H ;Получить и сохранить PUSH AX ; данные порта CLI ;Запретить прерывания CALL B10SPKR ;Произвести звук POP AX ;Восстановить значение OUT 61H,AL ; порта STI ;Разрешить прерывания RET MAIN ENDP


B10SPKR PROC NEAR B20: MOV DX,DURTION ;Установить время звучания B30: AND AL,11111100B ;Очистить биты 0 и 1 OUT 61H,AL ;Передать на динамик MOV CX,TONE ;Установить частоту B40: LOOP B40 ;Задержка времени OR AL,00000010B ;Установить бит 1 OUT 61H,AL ;Передать на динамик MOV CX,TONE ;становить частоту
Ассемблер для IBM PC. Программы. 168
B50: LOOP B50 ;Задержка времени DEC DX ;Уменьшить время звучания JNZ B30 ;Продолжать? SHL DURTION,1 ; нет - увеличить время, SHR TONE,1 ; сократить частоту JNZ B20 ;Нулевая частота? RET ; да - выйти B10SPKR ENDP
SOUNSG ENDS END BEGIN
Ассемблер для IBM PC 98
TITLE RECORD (COM) Проверка директивы RECORD 0000 CODESG SEGMENT PARA 'Code' ASSUME CS:CODESG,DS:CODESG,SS:CODESG 0100 ORG 100H 0100 EB 02 BEGIN: JMP SHORT MAIN ; ----------------------------------------------------- BITREC RECORD BIT1:3,BIT2:7,BIT3:6 ;Определить запись 0102 9A AD DEFBITS BITREC <101B,0110110B,011010B> ;Инициализировать биты ; ----------------------------------------------------- 0104 MAIN PROC NEAR 0104 A10: ;Ширина: 0104 B7 10 MOV BH,WIDTH BITREC ; записи (16) 0106 B0 07 MOV AL,WIDTH BIT2 ; поля (07) 0108 B10: ;Величина сдвига: 0108 B1 0D MOV CL,BIT1 ; шест.0D 010A B1 06 MOV CL,BIT2 ; 06 010C B1 00 MOV CL,BIT3 ; 00 010E C10: ;Маска: 010E B8 E000 MOV AX,MASK BIT1 ; шест.E000 0111 BB 1FC0 MOV BX,MASK BIT2 ; 1FC0 0114 B9 003F MOV CX,MASK BIT3 ; 003F 0117 D10: ;Выделение BIT2: 0117 A1 0102 R MOV AX,DEFBITS ; получить запись, 011A 25 1FC0 AND AX,MASK BIT2 ; очистить BIT1 и BIT3, 011D B1 06 MOV CL,BIT2 ; получить сдвиг 06, 011F D3 E8 SHR AX,CL ; сдвинуть вправо 0121 E10: ;Выделение BIT1: 0121 A1 0102 R MOV AX,DEFBITS ; получить запись, 0124 B1 0D MOV CL,BIT1 ; получить сдвиг 13, 0126 D3 E8 SHR AX,CL ; сдвинуть вправо 0128 C3 RET 0129 MAIN ENDP 0129 CODESG ENDS END BEGIN
Structures and records: N a m e Widht # fields Shift Widht Mask Initial BITREC . . . . . . . . . . . 0010 0003 BIT1 . . . . . . . . . . . . 000D 0003 E000 0000 BIT2 . . . . . . . . . . . . . 0006 0007 1FC0 0000 BIT3 . . . . . . . . . . . . 0000 0006 003F 0000


Segments and Groups: N a m e Size Align Combine Class CODESG . . . . . . . . . . . . 0129 PARA NONE 'CODE'
Symbols: N a m e Type Value Attr A10. . . . . . . . . . . . . . L NEAR 0104 CODESG B10. . . . . . . . . . . . . . L NEAR 0108 CODESG
Ассемблер для IBM PC 99
BEGIN. . . . . . . . . . . . . L NEAR 0100 CODESG C10. . . . . . . . . . . . . . L NEAR 010E CODESG D10. . . . . . . . . . . . . . L NEAR 0117 CODESG DEFBITS. . . . . . . . . . . . L WORD 0102 CODESG E10. . . . . . . . . . . . . . L NEAR 0121 CODESG MAIN . . . . . . . . . . . . . N PROC 0104 CODESG Length =0025
Ассемблер для IBM PC 100
TITLE DSTRUC (COM) Определение структуры 0000 CODESG SEGMENT PARA 'Code' ASSUME CS:CODESG,DS:CODESG,SS:CODESG 0100 ORG 100H 0100 EB 29 BEGIN: JMP SHORT MAIN ; --------------------------------------------- PARLIST STRUC ;Список параметров 0000 19 MAXLEN DB 25 ; 0001 ?? ACTLEN DB ? ; 0002 19 [ 20 ] NAMEIN DB 25 DUP(' ') ; 001B PARLIST ENDS ; 0102 19 PARAMS PARLIST <> ;Область структуры 0103 ?? 0104 19 [ 20 ] 011D 57 68 61 74 20 69 PROMPT DB 'What is name?', 'S' 73 20 6E 61 6D 65 3F 24 ; --------------------------------------------- 012B MAIN PROC NEAR 012B B4 09 MOV AH,09 ;Выдать запрос 012D 8D 16 011D R LEA DX,PROMPT 0131 CD 21 INT 21H 0133 B4 0A MOV AH,0AH ;Получить ввод 0135 8D 16 0102 R LEA DX,PARAMS 0139 CD 21 INT 21H 013B A0 0103 R MOV AL,PARAMS.ACTLEN ;Длина ввода ; ... 013E C3 RET 013F MAIN ENDP 013F CODESG ENDS END BEGIN
Structures and records: N a m e Width # fields Shift Width Masc Initial PARLIST. . . . . . . . . . . . . 001B 0003 MAXLEN . . . . . . . . . . . . 0000 ACTLEN . . . . . . . . . . . . 0001 NAMEIN . . . . . . . . . . . . 0002
Segments and Groups: N a m e Size Align Combine Class CODESG . . . . . . . . . . . . . 013F PARA NONE 'CODE'
Symbols: N a m e Type Value Attr BEGIN. . . . . . . . . . . . . L NEAR 0100 CODESG MAIN . . . . . . . . . . . . . N PROC 012B CODESG Length =0014 PARAMS . . . . . . . . . . . . L 001B 0102 CODESG PROMPT . . . . . . . . . . . . L BYTE 011D CODESG


Ассемблер для IBM PC 101
Основные, базовые и индексные регистры: Биты: w = 0 w = 1 000 AL AX 001 CL CX 010 DL DX 011 BL BX 100 AH SP 101 CH BP 110 DH SI 111 BH DI
Биты: Сегментный регистр: 00 ES 01 CS 10 SS 11 DS
r/m mod=00 mod=01 mod=10 mod=1.1 mod=11 w=0 w=1 000 BX+SI BX+SI+disp BX+SI+disp AL AX 001 BX+DI BX+DI+disp BX+DI+disp CL CX 010 BP+SI BP+SI+disp BP+SI+disp DL DX 011 BP+DI BP+DI+disp BP+DI+disp BL BX 100 SI SI+disp SI+disp AH SP 101 DI DI+disp DI+disp CH BP 110 Direct BP+disp BP+disp DH SI 111 BX BX+disp BX+disp BH DI
Ассемблер для IBM PC 102
Таблица A-1 Набор ASCII символов
Дес Шест Симв Дес Шест Симв Дес Шест Симв Дес Шест Симв
000 00h Нуль 032 20h sp 064 40h @ 096 60h ` 001 01h Начало заголовка 033 21h ! 065 41h A 097 61h a 002 02h Начало текста 034 22h " 066 42h B 098 62h b 003 03h Конец текста 035 23h # 067 43h C 099 63h c 004 04h Конец передачи 036 24h $ 068 44h D 100 64h d 005 05h КТМ 037 25h % 069 45h E 101 65h e 006 06h Да 038 26h & 070 46h F 102 66h f 007 07h Звонок 039 27h ' 071 47h G 103 67h g 008 08h Возврат на шаг 040 28h ( 072 48h H 104 68h h 009 09h Гориз.табуляция 041 29h ) 073 49h I 105 69h i 010 0Ah Перевод строки 042 2Ah * 074 4Ah J 106 6Ah j 011 0Bh Верт.табуляция 043 2Bh + 075 4Bh K 107 6Bh k 012 0Ch Перевод страницы 044 2Ch , 076 4Ch L 108 6Ch l 013 0Dh Возврат каретки 045 2Dh - 077 4Dh M 109 6Dh m 014 0Eh Shift out 046 2Eh . 078 4Eh N 110 6Eh n 015 0Fh Shift in 047 2Fh / 079 4Fh O 111 6Fh o 016 10h Data line esc 048 30h 0 080 50h P 112 70h p 017 11h Управление 1 049 31h 1 081 51h Q 113 71h q 018 12h Управление 2 050 32h 2 082 52h R 114 72h r 019 13h Управление 3 051 33h 3 083 53h S 115 73h s 020 14h Управление 4 052 34h 4 084 54h T 116 74h t 021 15h Нет 053 35h 5 085 55h U 117 75h u 022 16h Синхронизация 054 36h 6 086 56h V 118 76h v 023 17h Конец блока 055 37h 7 087 57h W 119 77h w 024 18h Анулирование 056 38h 8 088 58h X 120 78h x 025 19h End of medium 057 39h 9 089 59h Y 121 79h y 026 1Ah Замена 058 3Ah : 090 5Ah Z 122 7Ah z 027 1Bh Escape 059 3Bh ; 091 5Bh [ 123 7Bh { 028 1Ch Раздел.файла 060 3Ch < 092 5Ch \ 124 7Ch | 029 1Dh Раздел.группы 061 3Dh = 093 5Dh 125 7Dh } 030 1Eh Раздел.записи 062 3Eh > 094 5Eh ^ 126 7Eh ~ 031 1Fh Раздел.единицы 063 3Fh ? 095 5Fh _ 127 7Fh Забой


Ассемблер для IBM PC 103
Таблица B-1 Шестнадцатерично-десятичные преобразования +------------+-----------+----------+--------+-------+------+------+-----+ |Ш |Ш |Ш |Ш |Ш |Ш |Ш |Ш | |Е |Е |Е |Е |Е |Е |Е |Е | |С |С |С |С |С |С |С |С | |Т ДЕС |Т ДЕС |Т ДЕС |Т ДЕС |Т ДЕС|Т ДЕС|Т ДЕС|Т ДЕС| +------------+-----------+----------+--------+-------+------+------+-----+ |0 0|0 0|0 0|0 0|0 0|0 0|0 0|0 0| |1 268435456|1 16777216|1 1048576|1 65536|1 4096|1 256|1 16|1 1| |2 536870912|2 33554432|2 2097152|2 131072|2 8192|2 512|2 32|2 2| |3 805306368|3 50331648|3 3145728|3 196608|3 12288|3 768|3 48|3 3| |4 1073741824|4 67108864|4 4194304|4 262144|4 16384|4 1024|4 64|4 4| |5 1342177280|5 83886080|5 5242880|5 327680|5 20480|5 1280|5 80|5 5| |6 1610612736|6 100663296|6 6291456|6 393216|6 24576|6 1536|6 96|6 6| |7 1879048192|7 117440512|7 7340032|7 458752|7 28672|7 1792|7 112|7 7| |8 2147483648|8 134217728|8 8388608|8 524288|8 32768|8 2048|8 128|8 8| |9 2415919104|9 150994944|9 9437184|9 589824|9 36864|9 2304|9 144|9 9| |A 2684354560|A 167772160|A 10485760|A 655360|A 40960|A 2560|A 160|A 10| |B 2952790016|B 184549376|B 11534336|B 720896|B 45056|B 2816|B 176|B 11| |C 3221225472|C 201326592|C 12582912|C 786432|C 49152|C 3072|C 192|C 12| |D 3489660928|D 218103808|D 13631488|D 851968|D 53248|D 3328|D 208|D 13| |E 3758096384|E 234881024|E 14680064|E 917504|E 57344|E 3584|E 224|E 14| |F 4026531840|F 251658240|F 15728640|F 983040|F 61440|F 3840|F 240|F 15| Шест+------------+-----------+----------+--------+-------+------+------+-----+ поз.| 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | +------------+-----------+----------+--------+-------+------+------+-----+
Обращений с начала месяца: 183, Last-modified: Sat, 01 Feb 2003 18:56:38 GMT Оцените этот текст:Не читал10987654321

Содержание раздела