
- •О десский национальный морской университет
- •7.080401 "Информационные управляющие системы и технологии",
- •7.080402 "Информационные технологии проектирования"
- •Введение
- •Лабораторная работа №1 структура ехе-программы на ассемблере. Подготовка к выполнению Теоретические сведения
- •Задание
- •Лабораторная работа №2 использование служебных подпрограмм. Циклы. Формирование и вывод на экран строки ascii- символов Теоретические сведения
- •Inc al ; увеличиваем al (код символа) на 1
- •Задание
- •Лабораторная работа №3 управление курсором при выводе. Вложенные циклы. Формирование и вывод на экран таблицы символов ascii Теоретические сведения
- •Задание
- •Лабораторная работа №4 посимвольный ввод с клавиатуры. Анализ нажатия функциональных клавиш и комбинаций Теоретические сведения
- •Задание
- •Лабораторная работа №5 ввод с клавиатуры и обработка символьных строк (пароль) Теоретические сведения
- •Задание
- •Лабораторная работа №6 процедуры. Табличная трансляция. Перевод двоичных данных в символьную форму Теоретические сведения
- •Задание
- •Лабораторная работа №7 работа с файлами Теоретические сведения
- •Задание
Задание
Составить шаблон ЕХЕ-программы под именем FRAME.ASM с определенным набором и порядком описания сегментов, проверить его работоспособность. На основе шаблона создать отдельную программу SURNAME.ASM: определить в сегменте данных ASCII$-строку со своей фамилией и вывести ее на экран функцией 9 DOS. Если в шаблоне по заданию сегмента данных нет, считать, что он совпадает с сегментом команд и описать строку в сегменте команд.
Варианты наборов сегментов:
Команд, данных, стека.
Данных, команд.
Стека, данных, команд.
Команд, стека, данных.
Данных, команд, стека.
Стека, команд, данных.
Команд, данных.
Стека, команд (строка — в начале).
Команд (строка — в конце), стека.
Команд (строка — в начале).
Стека, команд (строка — в конце).
Команд (строка — в начале), стека.
Команд (строка — в конце).
Данных, стека, команд.
Лабораторная работа №2 использование служебных подпрограмм. Циклы. Формирование и вывод на экран строки ascii- символов Теоретические сведения
Использование сервисных подпрограмм. Одним из основных средств, имеющихся в распоряжении системного программиста, является набор служебных подпрограмм базовой системы ввода-вывода (BIOS) и операционной системы (ОС). Их использование избавляет от необходимости настраиваться на работу каждого конкретного устройства, разрабатывать каждый раз заново служебные базовые процедуры и, поскольку эти подпрограммы являются стандартными, повышает совместимость программ.
В DOS доступ к служебным подпрограммам (их называют функциями) осуществляется с помощью программных прерываний, вызываемых по команде INT. В качестве операнда этой команды указывается номер прерывания.
Всего имеется 256 номеров, часть из них не используется. Подпрограмм значительно больше, поэтому их группируют и назначают номер прерывания целой группе. При вызове прерывания уточняют, к какой подпрограмме нужно обратиться. Чаще всего для этого используют регистр AH — в него заносят непосредственно перед вызовом прерывания номер функции. Пример вызова 1-й функции прерывания 21h:
mov ah, 1
int 21h
В результате выполнения команды INT управление передается программе обработки соответствующего прерывания (в данном случае 21h); по окончании работы управление возвращается в прерванную программу.
Многие функции нуждаются в определенных входных данных, определяющих результат ее работы. Регистры, через которые эти данные передаются, называются входными. Также функция может возвращать определенный результат — в выходных регистрах. Таким образом, в общем случае процедуру вызова N-й функции прерывания X можно записать так:
;заполнение входных регистров
mov ah, N ;AH = номер функции
int X ;вызов прерывания X
;анализ выходных регистров
По номеру прерывания можно определить, относится ли данная подпрограмма к BIOS, DOS или является пользовательской.
Большинство служебных подпрограмм DOS сведены в прерывание 21h. Среди них — функции для ввода с клавиатуры и вывода на экран, функции работы с файлами, управления памятью и процессами и другие. Информацию о номерах функций и прерываний, входных и выходных регистрах, а также описание действия функций можно найти в справочниках по MS-DOS.
В лабораторной работе 1 нами вызывались две функции: 9 — вывод ASCII$-строки на экран, и 4Ch — завершение работы программы. Функция 4Ch представляет собой исключение из правила: по окончании ее работы управление возвращается не вызвавшей программе, а родительскому процессу, запустившему программу (например, командному интерпретатору).
Вывод на экран. В DOS имеются стандартные функции вывода символьных данных: 2, 6, 9 и 40h. Ниже приводится их описание:
№ в AH |
Описание |
Вход |
Выход |
2h |
Вывод символа в STDOUT |
DL = ASCII-код символа |
- |
6h |
Вывод символа в STDOUT |
DL = ASCII-код символа (кроме 0FFh) |
- |
9h |
Вывод ASCII$-строки в STDOUT |
DS:DX ASCII$-строку |
- |
40h |
Вывод ASCIIZ-строки на устройство или в файл |
DS:DX ASCIIZ-строку; CX = длина строки в байтах; BX = № устройства/файла (1 для STDOUT) |
CF = 0 при отсут-ствии ошибок; AX = число записанных байт |
Стандартным устройством вывода STDOUT в большинстве случаев является экран, однако можно перенаправлять вывод, то есть в качестве STDOUT использовать другое устройство или файл (например, команда tasm > options.lst перенаправит выводимый ассемблером список опций запуска в файл options.lst).
Циклы. Циклы в программах на ассемблере реализуются с помощью команд передачи управления JMP (безусловный переход), Jxx (условный переход) и LOOP ("петля").
С помощью команды JMP можно осуществлять переходы назад (так могут создаваться бесконечные циклы):
metka:
... ; (тело цикла)
jmp metka ; переход назад
или переходы вперед (обход определенного участка программы):
jmp metka ; переход вперед
...
metka:
Часто в тело цикла помещают команду условного перехода для обеспечения возможности выхода из цикла (или предусматривают возможность прерывания выполнения тела цикла по нажатию Ctrl-C или Ctrl-Break).
Команд условного перехода Jxx несколько (вместо xx указывается символ или набор символов, определяющих условие перехода). Как и в команде JMP, в качестве операнда указывается метка перехода, и эта метка может указываться как до команды перехода (переход назад), так и после (переход вперед).
Большинство из команд условных переходов передают управление на указанную метку в зависимости от состояния флагов процессора. Например, команда JZ metka передает управление на метку metka, если установлен флаг нуля (Jump if Zero, ZF = 1), JC — если установлен флаг переноса (Jump if Carry, CF = 1), а JS — если установлен флаг знака (Jump if Sign, SF = 1) и т. д. Если же соответствующий флаг сброшен, управление передается на следующую после Jxx команду. Также имеются команды, передающие управление на указанную метку, если соответствующий флаг сброшен (JNZ — Jump if Not Zero, ZF = 0; JNC — Jump if No Carry, CF = 0 и т. д.).
Чтобы пользоваться такими командами, необходимо знать, в каком состоянии может находиться определенный флаг и какие команды влияют на его состояние. Часто применяют схему использования команд условного перехода, при которой нет необходимости следить за флагами. Вот эта схема в виде фрагмента кода и блок-схемы:
m
etka:
...
cmp операнд1, операнд2
jxx metka
Команда CMP (Compare) производит сравнение операндов (с помощью вычитания второго из первого) и в соответствии с результатом сравнения формирует флаги (так же, как и команда обычного вычитания SUB). При этом в мнемоническом обозначении команд перехода указывается не проверяемый флаг, а результат сравнения. Например, команда JE передает управление на метку, если сравниваемые операнды были равны (Jump if Equal), а команда JNE – если не равны (Jump if Not Equal). (Если сравниваемые командой CMP операнды равны, то результат вычитания одного операнда из первого даст нулевой результат и установится флаг нуля ZF. Команда JE проверит этот флаг и передаст управление на метку точно так же, как и команда JZ. На самом деле JZ и JE — разные обозначения одной машинной команды процессора, созданные для удобства программирования).
Кроме команд JE (JNE) часто приходится пользоваться командами JA (Jump if Above — переход, если выше), JB (Jump if Below — переход, если ниже), JG (Jump if Greater — переход, если больше), JL (Jump if Less — переход, если меньше) и их антиподами JNA, JNB, JNG и JNL соответственно. Понятия "выше" и "ниже" относятся к сравнению беззнаковых операндов, а "больше" и "меньше" — знаковых (в дополнительном коде).
Цикл с предусловием организуется указанием команды Jxx в начале JMP-цикла, с постусловием — в конце (в любом случае до метки начала цикла должна быть проинициализирована переменная цикла).
; Цикл с предусловием
metka:
jxx exit
... ; (тело цикла)
jmp metka
exit:
; Цикл с постусловием
metka:
... ; (тело цикла)
jxx exit
jmp metka
exit:
Цикл, организованный только командой Jxx — всегда цикл с постусловием. Этот вариант цикла проще, чем организованный с помощью двух команд перехода.
Для образования цикла команд условного перехода часто нет необходимости вводить отдельную переменную для счетчика цикла, так как уже имеется какая-либо переменная (или даже несколько), циклически меняющая свое значение. Выход из цикла можно осуществить по достижении этой переменной определенного значения. Иначе обстоит дело с циклами, образованными при помощи команды LOOP. Эта команда специально предназначена для организации циклов и всегда использует регистр CX в качестве счетчика цикла.
В качестве операнда команды LOOP также указывается метка перехода. Команда LOOP уменьшает значение регистра CX на 1 и затем сравнивает его с нулем. Если значение СХ не равно 0, LOOP передает управление на указанную метку, если равно — управление передается на следующую за LOOP команду.
Перед началом цикла необходимо заполнить регистр СХ начальным значением N (пример ниже). При этом тело цикл будет выполнено N раз, а команда LOOP передаст управление на метку (N–1) раз.
; Цикл, повторяющийся N раз
mov cx, N
metka:
... ; (тело цикла)
loop metka
В качестве иллюстрации рассмотрим текст программы вывода на экран строки ASCII-символов с кодами от 32 до 255 (коды 0 - 31 часто используются как управляющие). Для заполнения области памяти используем LOOP-цикл, а для вывода полученной последовательности на экран – функцию вывода 40h int 21h. Использованию функции 9 в данном случае препятствует наличие в строке символа '$' (код 36), который интерпретируется функцией как признак конца строки.
; Листинг 2. Вывод строки ASCII-символов на экран
oursg segment
assume cs:oursg, ds:oursg
symb db 224 dup('*') ; резервируем место (строку) в памяти
begin:
mov ax, oursg ; сегментный адрес данных
mov ds, ax ; засылаем в DS
; Заполнение строки в памяти символами
mov cx, 224 ; число повторений цикла (256-32)
mov al, 32 ; начинаем с пробела (32)
mov si, 0 ; индекс внутри отведенной строки памяти
m: mov [symb+si], al ; пересылаем символ из AL в очередную позицию
; отведенной строки, затирая звездочку