Какое значение вернет функция min h4 h8. Минимальное значение без учёта нулей

21.06.2020

Функция MIN (МИН) в Excel используется для получения минимального значения из заданного диапазона ячеек.

Что возвращает функция

Возвращает наименьшее значение из диапазона данных.

Синтаксис

=MIN(number1, , …) – английская версия

=МИН(число1;[число2];…) – русская версия

Аргументы функции

  • number1 (число1) – первое число диапазона данных, из которого нам нужно получить минимальное значение;
  • , … ([число2]) – (не обязательно) второе число диапазона данных, из которого нам нужно получить минимальное значение. Всего в качестве аргументов функции можно указать 255 числовых значений.

Дополнительная информация

  • Пустые ячейки, логические выражения, текст или ссылки игнорируются;
  • Если в аргументах указаны ячейки с ошибкой или текст, который не возможно перевести в числовое значение – функция выдаст ошибку;
  • Аргументами функции также могут служить имена, массивы или ссылки которые содержат в себе числовые значения;
  • Учитываются логические значения и текстовые значения чисел, которые вы вводите непосредственно в список аргументов;
  • Если аргумент является массивом или ссылкой, то функция учитывает только числа. Пустые ячейки, логические значения или текст в массиве или ссылке игнорируются;
  • Если в аргументах функции не указано ни одного числового значения, функция выдаст значение “0” (ноль).

Функция МИН используется для нахождения минимального числа в исследуемом диапазоне и возвращает соответствующее число.

Функция МИНА предназначена для поиска минимального значения в исследуемом диапазоне данных и возвращает соответствующий результат.

Примеры использования функций МИН и МИНА в Excel

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

Таблица данных:

Для расчетов используем формулу массива (корректный результат только при нажатии комбинации Ctrl+Shift+Enter):


Единственным аргументом является выражение ГОД(СЕГОДНЯ())-ГОД(B3:B10), возвращающее массив числовых значений, равных разнице текущего года и года рождения каждого сотрудника. В результате вычислений получим:


Формула автоматически вычислила, что самому младшему сотруднику 27 лет.



Как вычислить сумму минимальных неотрицательных значений в Excel

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

Исходная таблица:


Для определения минимальных неотрицательных чисел используем формулу массива:

Единственным аргументом является функция ЕСЛИ, выполняющая проверку массива данных на вхождения положительных чисел. Если условие выполняется, функция МИН принимает в качестве аргумента массив, содержащий только положительные числа. Аналогично найдем минимальные значения для остальных столбцов. Полученный результат (Ctrl+Shift+Enter):


Найдем наименьшее число в таблице с помощью формулы:

В качестве аргументов функции являются значения, возвращаемые каждой из функций МИН для указанного вектора данных. Использовать как формулу массива. Результат (Ctrl+Shift+Enter):


Поиск нескольких наименьших значений при условиях в Excel

Некоторая компания ранее работала с одним поставщиком продукции. Однако стало известно, что некоторые другие поставщики предлагают более приемлемые цены. В таблице Excel содержатся коды товаров и скидки, предлагаемые другими поставщиками. Если скидки нет, отображено логическое значение ЛОЖЬ, если число положительное – товар стоит дороже. Найти наибольшую скидку для одних и тех же товаров только по разным ценам разных поставщиков.

Исходная таблица:

Формула для расчета (формула массива):

=0;"Скидки нет";МИНА(ЕСЛИ(A3:A15=D1;B3:B15;"")))" class="formula"/>

Алгоритм вычислений:

  1. Функция ЕСЛИ проверяет условие МИНА(ЕСЛИ(A3:A15=D1;B3:B15;""))>=0, где МИНА возвращает минимальное значение скидки для товара, код которого указан в ячейке D1.
  2. Функция МИНА учитывает логические значения. Возможен случай, когда для какого-либо товара скидки не существует (все значения – ЛОЖЬ), и будет возвращен результат 0 (нуль). В этом случае будет возвращена текстовая строка «Скидки нет». Аналогичное событие произойдет, если все скидки – только положительные числа.
  3. Если условие не выполняется, будет возвращена максимальная скидка (наибольшее отрицательное значение) для указанного кода товара.

Вычислим наибольшие скидки для остальных товаров. В результате получим (Ctrl+Shift+Enter):


Особенности использования функций МИН и МИНА в Excel

Функция МИН имеет следующую синтаксическую запись:

МИН(число1 ;[число2]…)

Описание аргументов:

  • число1 – обязательный аргумент, характеризующий первое число из диапазона, в котором требуется найти минимальное значение;
  • [число2]… - второй и последующие необязательные аргументы, характеризующие второе и последующие числа из исследуемого диапазона.

Функция МИНА имеет следующую синтаксическую запись:

МИНА(значение1; [значение2]…)

Описание аргументов:

  • значение1 – обязательный аргумент, характеризующий первое вхождение в диапазон, в котором требуется найти минимальное значение;
  • [значение2]… - второй и последующие необязательные аргументы, характеризующие второе и последующие вхождения исследуемого диапазона данных.

Примечания 1:

  1. Разница в синтаксисе подчеркивает смысловое различие двух функций: МИН работает только с числовыми значениями, МИНА дополнительно учитывает логический тип данных.
  2. Если в качестве аргументов функций МИН и МИНА были переданы только текстовые строки, не являющиеся текстовыми представлениями чисел, функции вернут значение 0.
  3. Функция МИН, принимающая в качестве аргумента ссылку на диапазон данных, игнорирует не только логические ИСТИНА и ЛОЖЬ, а также текстовые строки и пустые ячейки.
  4. Если в качестве аргумента МИН или МИНА является формула, возвращающая ошибку, результатом выполнения данных функций также будет являться код ошибки. Рекомендуется выполнять проверку данных с помощью функции ЕСЛИОШИБКА.
  5. Функции МИН и МИНА не имеют логических функций-аналогов, как это реализовано, например, у функции СЧЁТ (СЧЁТЕСЛИ), поэтому проверку данных следует выполнять при выполнении МИН и МИНА, передавая им в качестве аргумента логические функции (ЕСЛИ, ЕСЛИОШИБКА и прочие).

Примечания 2:

  1. Функция МИНА возвращает значение 0 (нуль), если в диапазоне, на который была передана ссылка в качестве аргумента, содержатся текстовые значения или текстовые представления чисел.
  2. Обе функции используются для нахождения минимальных величин в переданном в качестве аргумента диапазоне значений, однако между ними есть несколько различий:
  • Если одним из аргументов функции МИН является логическое значение (ИСТИНА или ЛОЖЬ, которые могут быть преобразованы к числовым значениям 1 и 0 соответственно), это значение будет учитываться в расчетах. Например, функция =МИН(100;ИСТИНА;ЛОЖЬ;10) вернет значение 0.
  • Если в качестве аргумента функции МИН была передана ссылка на диапазон, содержащий данные логического типа, последние учитываться не будут. Например, функция =МИН(A1:A4) вернет значение 10, если диапазон ячеек A1:A4 содержит следующие данные: 100, ИСТИНА, ЛОЖЬ и 10 соответственно.
  • Чтобы при расчетах учитывались также данные логического типа, следует использовать функцию МИНА. Например, запись =МИНА(A1:A4) вернет значение 0 (логическое ЛОЖЬ эквивалентно числовому 0), если ячейки A1:A4 содержат данные как в предыдущем пункте.
  • 8.12. Установка цветовой палитры (ржимы 4,5,6) - функция 0Bh
  • 8.15. Запись символа в режиме телетайпа - функция 0Eh
  • Подробно описаны все основные функции BIOS, предназначенные для работы с видеоадаптерами. Основные функции BIOS реализуются на всех компьютерах серии IBM PC/XT/AT, PS/2. На каждую группу функций данная глава содержит примеры программ.

    Использование функций BIOS предпочтительней, чем программирование регистров, это безопасней и надежнее, так как существует специальный видео-BIOS, установленный на плате адаптера. Этот BIOS гарантирует корректность работы с регистрами и исключает возможные повреждения адаптера и ЭЛТ.

    8.1. Выбор режима работы - функция 00h

    Функция 00h прерывания 10h позволяет задать любой режим работы видеоадаптера:

    На входе: AH = 00h; AL = номер устанавливаемого режима работы видеоадаптера, если бит D7 = 1, то при установке режима видеопамять не очищается; На выходе: Не используются.

    Приведем пример выбора режима видеоадаптера:

    mov ah,0 ; функция выбора режима работы видеоадаптера mov al,mode ; выбираем режим mode int 10h ;

    8.2. Изменение формы курсора - функция 01h

    Функция 01h позволяет изменить вертикальные размеры курсора путем задания верхней и нижней границ курсора (см. рис 9.1). Горизонтальные размеры курсора всегда одинаковы и равны ширине одного символа.

    На входе: AH = 00h - изменение размеров курсора; CH = верхняя граница курсора: D3-D0 верхняя граница курсора D5-D4 00b - обычный курсор 01b - невидимый курсор 10b - мигающий курсор 11b - быстро мигающий курсор D7-D6 не используются; CL = нижняя граница курсора (0-31). На выходе: Не используются.

    Курсор отображается только в текстовых режимах работы видеоадаптера.

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

    • Для монохромного и улучшенного цветного дисплеев верхняя граница = 11h, а нижняя = 12h.
    • Для цветного дисплея верхняя граница = 6h, а нижняя = 7h.

    Рисунок 9.1 Изменение положения курсора.

    8.3. Изменение положения курсора - функция 02h

    Функция 02h задает текущее положение курсора на экране дисплея.

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

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

    На входе: AH = 02h - установка позиции курсора; BH = номер страницы видеопамяти; DH = номер строки (0-24); DL = номер столбца (0-79). На выходе: Не используются.

    8.4. Определение положения и формы курсора - функция 03h

    Функция 03h позволяет узнать размер и текущие координаты курсора для любой страницы видеопамяти:

    На входе: AH = 03h - опрделение размеров и координат курсора BH = номер страницы видеопамяти. На выходе: CH = верхняя граница курсора; CL = нижняя граница курсора; DH = позиция текущей строки курсора; DL = позиция текущего столбца курсора.

    8.5. Использование светового пера - функция 04h

    Функция 04h позволяет определить подключено ли световое перо или нет. Если подключено, можно определить его координаты. Функция позволяет узнать позицию светового пера и в текстовых, и в графических координатах.

    Заметим, что световое перо EGA программно не полностью совместимо с CGA, в результате чего программы поддерживающие возможность использования светового пера для видеоадаптера CGA будут работать неправильно с видеоадаптером EGA. Видеоадаптер VGA не имеет светового пера.

    На входе: AH = 04h. На выходе: AH = 0 - световое перо не подключено (все остальные регистры не содержат полезной информации); AH = 1 - световое перо подключено; CH = координаты вертикальной позиции курсора в пикселах (графические режимы с низким разрешением); CX = координаты вертикальной позиции курсора в пикселах (графические режимы с высоким разрешением); BX = координаты горизонтальной позиции курсора в пикселах; DH = координаты вертикальной позиции курсора в номерах строк; DL = координаты горизонтальной позиции курсора в номерах колонок.

    Приведем пример использования этой функции:

    mov ah,4 int 10h ; определяем положение светового пера cmp ah,0 ; переходим на метку not_pen, если jz not_pen ; перо не подключено mov light_pen_col,dl ; сохраняем координаты светового пера mov light_pen_row,dh

    8.6. Изменение активной страницы видеопамяти - функция 05h

    Функция 05h позволяет изменить активную страницу видеопамяти. Активная страница видеопамяти отображается на экране.

    На входе: AH = 05h - выбор активной страницы видеопамяти; AL = номер страницы видеопамяти, которая станет активной. На выходе: Не используются.

    8.7. Свертка текстового окна вверх - функция 06h

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

    На входе: AH = 06h - свертка окна вверх; AL = число прокручиваемх линий, если оно равно нулю, то окно прокручивается целиком; BH = атрибут, используемый для строк, возникающих снизу окна; CH = номер строки верхнего левого угла окна; CL = номер колонки верхнего левого угла окна; DH = номер строки нижнего правого угла окна; DL = номер колонки нижнего правого угла окна. На выходе: Не используются.

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

    push es ; сохраняем содержимое регистра es xor ax,ax ; устанавливаем регистр es на нулевой mov es,ax ; сегмент памяти mov ah,6 ; функция свертки экрана вверх mov al,0 ; очищаем все окно mov bh,7 ; устанавливаем нормальный атрибут xor cx,cx ; устанавливаем левый верхний угол окна в (0,0) ; Для определения размеров экрана испльзуется содержимое переменных; видеофункций BIOS. Ячейка памяти, расположенная по адресу 0000:0484 ; содержит число, на единицу меньшее, чем количество строк на экране. ; По адресу 0000:044A находится переменная, определяющая число символов; в строке. Более подробно переменные видеофункциий BIOS будут; рассмотрены позже. mov dh,es: ; определяем число строк в данном режиме mov dl,es: ; определяем число символов в строке dec dl int 10h ; вызываем свертку экрана вверх pop es ; восстанавливаем регистр es

    8.8. Свертка текстового окна вниз - функция 07h

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

    На входе: AH = 07h - свертка окна вниз; AL = число прокручиваемх линий, если оно равно нулю, то окно прокручивается целиком; BH = атрибут, используемый для строк, возникающих в верхней части окна; CH = номер строки левого верхнего угла окна; CL = номер колонки левого верхнего угла окна; DH = номер строки правого нижнего угла окна; DL = номер колонки правого нижнего угла окна. На выходе: Не используются.

    Эту функцию можно использовать для очистки окна аналогично функции 06h.

    8.9. Чтение символа и его атрибутов - функция 08h

    На входе: AH = 08h - чтение символа и его атрибутов; BH = номер страницы видеопамяти. На выходе: AL = ASCII-код символа; AH = байт атрибутов символа.

    Следующий пирмер считывает символ и его атрибут из текущей позиции курсора на странице page:

    ... mov ah,8 ; читаем символ и его атрибуты mov bh,page ; выбираем страницу видеопамяти page int 10h ; считываем символ и его атрибут mov char,al ; сохраняем полученный ASCII-код символа mov attr,ah ; и его атрибут...

    8.10. Запись символа с атрибутами в текущей позиции курсора - функция 09h

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

    На входе: AH = 09h - запись символа с атрибутом; AL = ASCII-код записываемого символа; BH = номер страницы видеопамяти; BL = атрибут (для текстового режма) или цвет (для графического режима); CX = число записываемых символов. На выходе: Не используются.

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

    TITLE BIOS_FUNCTION .MODEL tiny DOSSEG .STACK 100h .DATA message DB "INT 10h", 0 video_page DB 2 .CODE .STARTUP ; выбираем режим 0 видеоадаптера xor ah,ah xor al,al int 10h ; изменяем форму курсора mov ah,1 ; начало курсора - линия 0 ; конец курсора - линия 7 mov ch,0 mov cl,7 int 10h ; выбираем страницу видеопамяти - video_page mov ah,5 mov al,video_page int 10h ; прокручиваем окно экрана mov ah,6 xor al,al ; прокручиваем все окно mov bh,0FFh ; используем атрибут 0FFh mov cl,10 ; задаем верхний левый угол окна mov ch,5 mov dl,30 ; задаем правый нижний угол окна mov dh,15 int 10h ; устнанавливаем координаты курсора mov ah,2 mov bh,video_page ; выбираем страницу video_page mov dh,12 ; строка 12 mov dl,20 ; колонка 20 int 10h ;отображаем на активной странице экрана строку message mov si,OFFSET message call WriteString .EXIT 0 ; процедура WriteString выводит на экран строку, имеющую; смещение si в сегменте ds WriteString PROC ; определяем текущую активную страницу экрана mov ah,0Fh int 10h ; номер активной страницы в регистре bh ; получаем в dx координаты курсора mov ah,3 int 10h ; в цикле выводим на экран символы строки next_char: mov ah,9 lodsb cmp al,0 ; находим конец строки je exit_proc ; если конец строки достигнут, то оканчиваем процедуру mov bl,8 ; для отображаемых символов используем атрибут 8 mov cx,1 ; символы строки выводятся без повтора int 10h ; перемещаем курсор в следующую позицию строки mov ah,2 inc dl int 10h jmp next_char exit_proc: ret WriteString ENDP END

    8.11. Запись символа в текущей позиции курсора - функция 0Ah

    Функция позволяет записать символ в текущей позиции курсора на любой странице видеопамяти. Как и в предыдущей функции, можно производить запись сразу нескольких одинаковых символов. Атрибуты символа не задаются, а используются их старые значения из предыдущих операций записи. После операции записи положение курсора не изменяется. Управляющие символы, такие как возврат каретки и перевод строки, не действуют и записываются, как обычные символы.

    На входе: AH = 10h - запись символа без атрибута; AL = ASCII-код записываемого символа; BH = номер страницы видеопамяти; BL = цвет (для графического режима); CX = число записываемых символов. На выходе: Не используются.

    Если запись символа происходит на видеоадаптере EGA в графическом режиме, и бит D7 регистра BL содержит единицу, то новый символ накладывается на текущее содержимое экрана по логике булевой операции ИСКЛЮЧАЮЩЕЕ ИЛИ.

    8.12. Установка цветовой палитры (ржимы 4,5,6) - функция 0Bh

    Данная функция позволяет выбрать одну из двух стандартных цветовых палитр (см. таблицу 9.1). Функция используется для обеспечения совместимости с видеоадаптером CGA.

    Таблица 9.1 Стандартные цветовые палитры в режимах 4,5,6.

    Функция 0Bh имеет следующий формат вызова:

    На входе: AH = 0Bh - установка цветовой палитры; BH = 0, тогда BL = цвет фона и рамки (для графического режима) или цвет рамки (для текстового режима) BH = 1, тогда BL = номер палитры (0 или 1). На выходе: Не используются.

    8.13. Вывод пиксела - функция 0Ch

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

    Функция используется в графических режимах для записи пиксела заданного цвета в любую страницу видеопамяти. Необходимо отметить, что у видеоадаптера CGA в графических режимах определена только одна страница видеопамяти. Значения цветов, которые можно использовать в различных режимах, перечилены в таблице 9.2:

    Цвета, соответствующие номерам цветов в таблице можно посмотреь в главе "Режимы работы видеоадаптеров".

    Таблица 9.2 Возможные значения номеров цветов для различных режимов.

    Формат вызова функции 0Ch представлен ниже:

    На входе: AH = 0Ch - запись пиксела; AL = номер цвета; BH = номер страницы (для CGA не используется); CX = координата X; DX = координата Y. На выходе: Не используются.

    Если бит D7 регистра AL содержит единицу, то новый пиксел накладывается на текущее содержимое экрана по логике булевой операции ИСКЛЮЧАЮЩЕЕ ИЛИ.

    Заметим, что начало системы координат находится в левом верхнем углу экрана, а оси координат направлены следующим образом: ось X - вправо, ось Y - вниз. Далее, если особо не оговарено, мы всегда будем использовать эту систему координат.

    // Демонстрация функций - выбора цветовой палитры и вывода // пиксела. #include #include void main(void); void main(void) { union REGS inregs, outregs; unsigned char i, j; // устанавливаем режим 4 видеоадаптера // (графический - 320х200, 4 цвета) inregs.h.ah = 0x0; inregs.h.al = 0x4; int86(0x10, &inregs, &outregs); // устанавливаем цвет фона inregs.h.ah = 0x0B; inregs.h.bh = 0x0; //устанавливаем цвет фона inregs.h.bl = 0x6; //номер устанавливаемого цвета фона int86(0x10, &inregs, &outregs); for(i = 0; i < 2; i++) { // устанавливаем цветовую палитру inregs.h.ah = 0x0B; inregs.h.bh = 0x1; // установка палитры inregs.h.bl = i; // номер палитры int86(0x10, &inregs, &outregs); // выводим массив точек for(j = 0; j < 64; j++) { // выводим на экран дисплея точку inregs.h.ah = 0x0C; inregs.h.al = (unsigned char)(j / 16);// номер цвета inregs.x.cx = 0x10 + j; // x-координата точки inregs.x.dx = 0x10 + j; // y-координата точки int86(0x10, &inregs, &outregs); } getch(); } }

    8.14. Чтение пиксела - функция 0Dh

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

    На входе: AH = 0Dh - определение цвета пиксела; BH = номер страницы (для CGA не используется); CX = координата X; DX = координата Y; На выходе: AL = номер цвета пиксела.

    Приведем фрагмент программы, который определяет номер цвета пиксела, имеющего координаты x_pos и y_pos:

    mov ah,0Dh mov cx,x_pos mov dx,y_pos int 10h ; сохраняем полученную величину mov color_number

    8.15. Запись символа в режиме телетайпа - функция 0Eh

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

    Данная функция обрабатывает следующие управляющие символы: звуковой сигнал (BELL), возврат курсора назад на одну позицию (BACKSPACE), возврат каретки (CARRIAGE RETURN) и перевод строки (LINEFEED).

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

    Ниже приведен формат вызова функции:

    На входе: AH = 0Eh - запись символа в режиме телетайпа; AL = ASCII-код записываемого символа; BH = номер страницы видеопамяти (только в текстовых режимах)?; BL = цвет символа (в графических режимах). На выходе: Не используются.

    Приведем текст процедуры WriteStringT, которая выводит на экран строку, имеющую смещение si в сегменте ds, при помощи функции 0Eh прерывания INT 10h:

    WriteStringT PROC ; определяем текущую активную страницу экрана mov ah,0Fh int 10h ; номер активной страницы в регистре bh ; в цикле выводим на экран символы строки next_char: mov ah,0Eh lodsb ; получаем следующий символ строки cmp al,0 ; находим конец строки je exit_proc ; если конец строки достигнут, то оканчиваем процедуру int 10h jmp next_char exit_proc: ret WriteStringT ENDP

    8.16. Определение текущего режима работы видеоадаптера - функция 0Fh

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

    На входе: AH = 0Fh - определение текущего режима видеоадаптера. На выходе: AH = число символов в строке; AL = номер текущего режима; BH = номер активной страницы видеопамяти.

    ¨ Вывод текста на экран путём непосредственного программирования видеобуфера.

    ¨ Разработка прикладных программ с использованием сервисных функций BIOS для работы с экраном и клавиатурой.

    ¨ Введение задержки для программных операций.

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

    Все возможности видеосистемы компьютера можно реализовать с помощью видеофункций BIOS прерывания int 10h . Прерывание int 10h обеспечи-вает: смену видеорежима (текстовый или графический); вывод символьной и текстовой информации; смену шрифтов, настройку цветовой палитры, работу с графическим изображением. Программирование видеосистемы с помощью средств BIOS более громоздко, однако большие возможности и высокая скорость вывода обуславливают широкое использование этого метода в прикладных программах.

    В данной работе рассматриваются функции BIOS для обслуживания видеосистемы компьютера, а также функции для работы с клавиатурой. Перечислим функции, являющиеся предметом рассмотрения в лабораторной работе.

    Int 10h:

    функция 00h - установка видеорежима;

    функция 02h - установка позиции курсора;

    функция 03h - считывание позиции и размера курсора;

    функция 05h - установка видеостраницы;

    функция 06h (07h) - инициализация или прокрутка окна вверх (вниз);

    функция 08h - чтение символа и атрибута в позиции курсора;

    функция 09h - запись символа и атрибута в позицию курсора;

    функция 0Ah - запись символа в позицию курсора с текущим атрибутом;

    функция 0Eh - запись символа в режиме телетайпа с текущим атрибутом;

    функция 0Fh - получить режим дисплея;

    функция 1003h - переключение назначения старшего бита байта атрибута: мерцание/яркость,

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

    Int 16h:

    функция 00h (10h) - чтение символа с клавиатуры с ожиданием;

    функция 01h (11h) - проверка буфера клавиатуры на наличие в нём символа;

    функция 02h (12h) - получение флагов (расширенной) клавиатуры.

    Int 15h, функция 86h - задержка.

    Int 1 Ah, функция 00h - получение системного времени.

    8.2.2. ПРЯМОЕ ПРОГРАММИРОВАНИЕ ВИДЕОБУФЕРА В ТЕКСТОВОМ РЕЖИМЕ

    Современные видеоконтроллеры поддерживают разнообразные текстовые и графические режимы. Текстовые режимы различаются по разрешению (число отображаемых символов по горизонтали и вертикали) и цветовой палитре (монохромный или 16-цветный режим). Для графических режимов основным признаком классификации является количество одновременно отображаемых цветов и, соответственно, количество бит видеопамяти, отводимое на каждую точку (пиксел) изображения. Различают следующие типы графических режимов:

    Монохромный (1-битное кодирование);

    16-цветный EGA/VGA (4-битное кодирование);

    256-цветный SVGA (8-битное кодирование);

    - HiColor (16-битное кодирование);

    - TrueColor (24-битное / 32-битное кодирование).

    Графические режимы VGA (SVGA) сильно устарели, а текстовые продолжают успешно применяться (см. табл. 3.2 п. 8.2.3).

    Всё, что изображено на мониторе - графика, текст - одновременно присутствует в памяти, встроенной в видеоадаптер. Для того чтобы изображение появилось на мониторе, оно должно быть записано в память видеоадаптера. В текстовом режиме для VGA-совместимых систем для видеопамяти отводится адресное пространство (исключая 7-й видеорежим с монохромным адаптером), начинающееся с логического адреса B800h:0000h и заканчивающееся адресом BF00h:0FFFh. Данная область разбивается на 8 секторов по числу видеостраниц (4 Кбайта на страницу). Таким образом, постраничное деление адресного пространства видеопамяти в текстовом режиме имеет следующий вид:

    B800h:0000h - страница 0, смещение в диапазоне 0000h - 0FFFh

    B900h:0000h - страница 1, смещение в диапазоне 0000h - 0FFFh

    - ...........

    BF00h:0000h - страница 7, смещение в диапазоне 0000h - 0FFFh

    На экране отображается видеобуфер, соответствующий активной странице. В текстовых режимах для изображения каждого символа отводится 2 байта: байт с ASCII- кодом символа и байт с его атрибутом. При этом по адресу B800h:0000h находится байт с кодом символа (левый верхний угол экрана), а в B800h:0001h - атрибут этого символа; B800h:0002h - код второго символа, а в B800h:0003h - атрибут второго символа и т.д. Вообще при формировании изображения непосредственно в видеобуфере, в обход программ DOS и BIOS, все управляющие коды ASCII теряют свои управляющие функции и отображаются в виде соответствующих символов. Структура байта атрибутов приведена на рис. 3.1.

    Рис. 3.1. Структура байта атрибутов

    Из рис. 3.1 следует, что каждый символ может принимать любой из 16 возможных цветов, определяемых сочетанием младших 4-х битов. Биты 4-6 байта атрибутов задают цвет фона под данным символом. Последний бит 7, в зависимости от режима видеоадаптера, определяет либо яркость фона под данным символом (тогда фон также может принимать 16 разных цветов), либо мерцание символа (устанавливается DOS по умолчанию).

    При загрузке машины устанавливается стандартная палитра, коды цветов которой приведены в табл. 3.1. Рассмотрим некоторые примеры. Так, в режиме мерцания значение старшего полубайта атрибута 8h обозначает не серый фон, а чёрный при мерцающем символе, цвет которого по-прежнему определяется младшим полубайтом; значение старшего полубайта 0Ch - красный фон при мерцающем символе. Переключение назначения бита 7 осуществляется подфункцией 03h функции 10h прерывания int 10h .

    Таблица 3.1

    Коды цветов стандартной палитры

    Салатовый

    Бирюзовый

    Светло-бирюзовый

    Фиолетовый

    Светло-фиолетовый

    Коричневый

    Ярко- белый

    Двухбайтовые коды символов записываются в видеобуфер в том порядке, в каком они должны появиться на экране: первые 80*2 байт соответствуют первой строке экрана, вторые 80*2 байт - второй и т.д. При этом переход на следующую строку экрана определяется не управляющими кодами возврата каретки и перевода строки, а размещением кода в другом месте видеобуфера. Для того чтобы из программы получить доступ к видеобуферу, надо занести в один из сегментных регистров данных сегментный адрес видеобуфера. После этого, задавая те или иные смещения, можно выполнить запись в любые места (ячейки) видеобуфера. Вычислить смещение ячейки в координатах "строка-столбец" (row, clm) можно так:

    VidAdd r= (row*160) + (clm*2)

    При большом объёме выводимых данных, информационный кадр формируется заранее в буфере пользователя, располагающегося в сегменте данных программы.

    Листинг 3.1. Запись строки в видеобуфер 0- страницы.

    ;Очистка экрана

    ;Настроим сегментный регистр ES на страницу 0 видеобуфера, а ds на сегмент данных

    ;Перешлём в видеобуфер строку символов, настроив соответствующим образом

    ;регистры si, di и cx

    cld ;Просмотр вперёд

    rep movsb ;)* ;Переслать строку символов с атрибутами в видеобуфер

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

    ;запрос DOS на ввод команды может затереть выведенную информацию)

    ;Поля данных в сегменте данных программы. Символы и атрибуты: 0B0h - cветло-

    ;бирюзовый по чёрному, 0E4h -красный по жёлтому

    msg db ‘*’,0B0h,’T’,0E4h,’E’,0E4,’S’,0E4,’T’,0E4,’*’,0B0h

    В данном фрагменте программы символьные коды выводимого сообщения перемежаются с их атрибутами. Такой способ формирования полей данных, предназначенных для прямой записи в видеопамять, становится громоздким, однако его можно существенно упростить, если выводимые символы имеют одни и те же атрибуты. Так, если мы хотим осуществить вывод символов текста из сегмента данных с единственным атрибутом 0E4h , то нам нужно просто заменить одну командную строку, отмеченную в выше приведённом фрагменте символом "*)" , на три. При этом задание строки данных приобретёт привычный для нас вид.

    mov si,offset msg ;Смещение источника

    mov di,160*12+36*2 ;Смещение приёмника (36 столбец 13 -ой строки),

    mov cx,msglen ;Число пересылаемых байт

    cld ;Просмотр вперёд

    mov ah,0E4h ;Атрибут выводимых символов 0E4h - красный по жёлтому

    stosw ;Выгрузка “символ + атрибут” из ах в видеобуфер (ax→es:di)

    loop cycle ;Повторить msglen раз

    ;Поля данных в сегменте данных программы.

    msg db ‘*TEST*’

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

    Разработка структуры программ, осуществляющих просмотр произвольных видеостраниц, на которые предварительно записана информация способом прямого программирования видеобуфера, удобно производить с применением функции 05 h int 10 h BIOS (п. 8.2.3.2).

    8.2.3. СПРАВОЧНЫЕ ДАННЫЕ ПО ФУНКЦИЯМ BIOS

    8.2.3.1. Прерывание int 10h. Видеофункции BIOS

    ¨ Функция 00h. Установка видеорежима (табл. 3.2) текущей видеостраницы с очисткой экрана (быстрая очистка экрана реализуется функцией 06 h и 07 h).

    Вызов: AH = 00h ,

    Al = видеорежим (код режима задаётся в младших 7 битах, установка в 1 старшего бита запрещает очистку экрана).

    Вызов разрушает регистры AX, BP, SI, и DI .

    Таблица 3.2

    Текстовые видеорежимы и страницы в стандарте VGA , поддерживаемые
    современными видеоконтроллерами

    Режим

    Разрешение

    Цвет

    Размер знака

    Адрес

    Страницы

    полутонов

    полутонов

    3 (Mono)

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

    ¨ Функция 02h. Установка позиции курсора.

    Задаёт положение курсора на экране в текстовых координатах, с которых в дальнейшем будет выводиться текст. Отсчёт номера строки и столбца ведётся от верхнего левого угла. Курсор можно установить как в текстовом, так и в графическом режиме, однако, в графическом режиме курсор не виден. BIOS поддерживает до восьми независимых курсоров - по одному на каждую страницу (см. табл. 3.2) независимо от того, какая страница является активной. Функцию 02 h

    Вызов: AH = 02h ; BH = номер страницы (0,1,...7), обычно 0;

    DH = строка; DL = столбец.

    Вызов разрушает регистры AX, BP, SI и DI .

    ¨ Функция 03h. Считывание позиции и размера курсора.

    Возвращает текущие координаты состояния курсора на выбранной странице. Это даёт возможность временно перейти для работы на другое место экрана, а затем вернуться на старое место. Функцию 03 h BIOS можно использовать в комбинации с функциями DOS для организации вывода на экран.

    Вызов: AH = 03h, BH = номер страницы (0,1,...7), обычно 0 .

    Возврат: DH, DL = строка и столбец текущей позиции курсора,

    CH, CL = первая и последняя строки развёртки курсора.

    Вызов разрушает регистры AX, BP, SI и DI.

    ¨ Функция 05h. Установка видеостраницы.

    Устанавливает активную видеостраницу (как текстовую, так и графическую).

    Вызов: AH= 05h, AL= номер страницы (0,...,7).

    Вызов разрушает регистры AX, BP, SI и DI .

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

    ¨ Функция 06h (07h). Инициализация или прокрутка окна вверх (вниз).

    Инициализирует окно с указанными координатами, пробелами ASCII с заданным атрибутом (AL = 0) , или прокручивает содержимое окна вверх (вниз) на заданное число строк (AL = число строк). При прокрутке появляющиеся снизу (сверху) строки заполняются пробелами ASCII с заданным атрибутом. Функцию удобно использовать для быстрой очистки экрана или некоторого прямоугольного окна.

    Вызов: AH = 06h(07h) ;

    AL = 0 - очистка, AL = N (N >0) - прокрутка на N строк;

    BH = атрибут символов в окне;

    CH, CL = координаты строки и столбца (Y,X) левого верхнего угла;

    DH, DL = координаты строки и столбца (Y,X) правого нижнего угла.

    Вызов разрушает регистры AX, BP, SI, и DI.

    ¨ Функция 08h. Чтение символа и атрибута в текущей позиции курсора на выбранной странице.

    Вызов: AH = 08h , BH = номер страницы (0,...,7), обычно 0.

    Возврат: AH = атрибут символа, AL = ASCII- код символа.

    Вызов разрушает регистры BP, SI и DI.

    ¨ Функция 09h . Запись символа с заданным атрибутом на экран в позицию курсора. Действует как в графическом, так и в текстовом режимах. В графическом режиме символы не должны переходить на следующую строку. Все коды в AL рассматриваются как символьные и не управляют положением курсора. После вывода символа курсор смещается к следующей позиции функцией 02h. Коэффициент повторения позволяет выводить строки одинаковых символов. В текстовом режиме символ выводится с указанным в BL атрибутом. В графическом - содержимое BL влияет только на цвет символа, но не на фон под ним. Графическое изображение под знакоместом затирается.

    Вызов: AH =09h , AL = ASCII -код символа,

    BL = атрибут символа (текстовый режим) или только цвет символа (графический режим),

    BH = номер страницы (0,1,...7), CX = коэффициент повторения.

    Вызов разрушает регистры AX, BP, SI и DI .

    ¨ Функция 0Ah. Запись символа с текущим атрибутом на экран в позицию курсора. Функция действует как в графическом, так и в текстовом режимах. Символ принимает атрибут, установленный ранее для этой позиции. Все ASCII-коды в AL рассматриваются как символьные и не управляют положением курсора (также как и в функции 09h). После вывода символа курсор смещается к следующей позиции функцией 02h.

    Вызов: AH = 0Ah , AL = ASCII -код символа,

    BH = номер страницы (0,1,...7), CX = коэффициент повторения.

    Вызов разрушает регистры AX, BP, SI и DI .

    ¨ Функция 0Eh. Запись символа с текущим атрибутом в режиме телетайпа.

    Записывает символ ASCII в позицию курсора (предварительно установленную функцией 02h ) на активной странице и смещает курсор к следующей позиции. Коды ASCII : 07h - звонок (BEL), 08h - шаг назад(BS), 0Dh - возврат каретки (CR), 0Ah - перевод строки (LF), рассматриваются как управляющие и выполняются соответствующие им действия. Остальные управляющие коды рассматриваются как символы и выводятся на экран. Действует автоматический перевод курсора на следующую строку после завершения предыдущей, а также прокрутка экрана вверх на 1 строку после заполнения самой нижней.

    Вызов: AH = 0Eh, AL = ASCII -код символа,

    BL = цвет символа (только для графического режима),

    BH = номер страницы (0,1,...7), по умолчанию действует активная страница.

    ¨ Функция 0 Fh. Получить режим дисплея и номер текущей страницы.

    Вызов: AH = 0 Fh .

    Возврат: AL = режим дисплея, AH = ширина экрана в текстовом формате

    BH = номер активной страницы.

    Вызов разрушает регистры BP, SI и DI.

    Пример. Процедура установки позиции курсора на текущей странице.

    Вход: dh = строка (0 - 25), dl = столбец (0 - 79)

    .......... ;Восстановить регистры

    ¨ Функция 10h. Подфункция 03h . Переключение бита "мерцание/яркость".

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

    Вызов: A X = 1003h, BL = назначение 7-го бита атрибута:

    0 - повышенная яркость, 1 - мерцание (устанавливается по умолчанию).

    Функция воздействует сразу на все символы экрана, у которых установлен старший бит атрибута фона.

    ¨ Функция 13h. Запись строки символов с заданными атрибутами.

    Записывает строку в текущую страницу видеобуфера, начиная с указанной позиции. Коды ASCII : 07h - звонок, 08h - шаг назад, 0Ah - перевод строки,
    0Dh - возврат каретки, рассматриваются как управляющие, остальные - как символьные.

    Вызов: AH = 13h , AL = режим записи:

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

    1 - отличается от режима 0 тем, что после записи курсор остаётся в конце строки;

    2 - строка содержит попеременно коды символов и атрибутов (т.е. каждый символ описывается 2 байтами - ASCII -кодом и атрибутом), после записи курсор принимает исходное положение;

    3 - отличается от режима 2 тем, что по окончании вывода курсор остаётся в конце строки.

    BH = номер страницы (0,1,...7), BL = атрибут для режимов 0 и 1,

    CX = длина символьной строки (в длину входят только коды символов, но не байты атрибутов),

    DX = DH.DL = координаты курсора (строка, столбец) в исходной точке вывода строки на экране,

    ES:BP = адрес начала строки в памяти.

    Обратите внимание на особенность задания адреса!

    1. Программы (учебный практикум), выполняемые в операционной среде DOS, используют по умолчанию текстовый режим 3, страницу 0.

    2. Программы более широкого назначения должны запрашивать текущий видеорежим и страницу (функция 0Fh, int 10h ) с последующим их применением в используемых функциях BIOS.

    .......

    Mov v_mode, al ;Сохраним режим

    Mov current_page, bh ;Сохраним строку

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

    Установка страницы функцией 05h ;

    Установка позиции курсора функцией 02h ;

    Построчное форматирование текста BIOS или DOS.

    В дальнейшем может быть организован циклический просмотр содержания страниц путём их переключения функцией 05 h, int 10 h . При выходе из программы обязательно восстанавливаем искомую "0"-страницу. Сделать это, к примеру, можно так.

    ..........

    ..........

    ;Анализ буфера клавиатуры функцией DOS 06h int 21h с целью её завершения нажатием;произвольной клавиши

    mov ah,06h ;Функция ввода без ожидания

    mov dl,0FFh ;Ввод

    out_program: ;Восстановим страницу функцией 05h, int 10h

    ..........

    Страницы видеобуфера могут быть последовательно отформатированы и способом непосредственного программирования памяти. Выбор страниц при этом осуществляется соответствующей инициализацией сегментного регистра ES (см. п. 8.2.2). Просмотр содержимого страниц также может быть выполнен путём их последовательного переключения с помощью функции 05h, int 10h .

    4. Структура демонстрационной программы, исследующей функцию "мерцание - яркость фона" (функция 10h , подфункция 03h, int 10h ).

    ;Очистка экрана

    ..........

    ;Инициализация 2-х локальных окон, каждое со своим атрибутом и текстом. При задании

    ;атрибутов цвета старший (7-ой по номеру) бит выбран равным "1".

    .........

    continue: ;Включим мерцание

    mov bl,1 ;Мерцание

    ;Введём задержку на 3 сек

    .........

    ;Включим повышенную яркость

    .........

    ;Введём задержку на 3 сек

    .........

    ;Анализ буфера клавиатуры функцией DOS 06h int 21h с целью её завершения нажатием

    ;произвольной клавиши

    .........

    jnz out_program ;zf=0, есть символ, на выход

    jmp continue ;zf=1, символа нет, продолжим работу

    out_program: ;Восстановим мерцание (по умолчанию)

    ..........

    exit: mov ax,4C00h ;Вызов функции завершения программы

    .........

    5. Если в программе организован бесконечный цикл вывода данных на экран функциями BIOS (09 h, 0 Ah, 0 Eh, 13 h) , то его нельзя будет аварийно прервать с помощью нажатия клавиш Ctrl+C (т.е. выйти из программы, как это можно сделать при использовании соответствующих функций DOS). Чтобы можно было это сделать, включите в тело цикла функцию 0Bh прерывания Int 21h .

    8.2.3.3. Прерывание int 16h

    ¨ Функция 00h (10h). Чтение символа клавиатуры с ожиданием.

    Читает из кольцевого буфера ввода символ и скан-код. После считывания они удаляются из буфера и возвращаются в регистре AX . Если буфер пуст, ожидает ввода. Каждой клавише на клавиатуре соответствует так называемый скан-код, соответствующий только этой клавише. Этот код посылается клавиатурой при каждом нажатии и отпускании клавиши и обрабатывается в BIOS обработчиком прерывания Int 09 h . Функция 00h даёт возможность получить код нажатия, не перехватывая этот обработчик. Если нажатой клавише соответствует ASCII- символ, то:

    AL - ASCII -код символа, AH - скан-код клавиши.

    Если нажатой клавише соответствует расширенный ASCII- код, то:

    AL - 00h , AH - расширенный ASCII- код.

    Вызов: AH = 00 h (83/84-key ).

    Возврат: AL = ASCII -код символа, изображённый на клавише/00h ,

    AH = скан-код/расширенный ASCII -код клавиши.

    Функция 10 h (AH = 10) - 00h для расширенной клавиатуры (101/102-key
    ASCII- коды для клавиш F11, F12 , а также для ряда других комбинаций.
    В качества признака управляющих клавиш или их комбинаций, помимо значения 00 h , используются 0Ah, 0Dh и E0h .

    ¨ Функция 01h (11h). Поверка буфера клавиатуры на наличие в нём символа.

    Определяет, имеются ли в кольцевом буфере ожидающие ввода символы; возвращает флаг ожидания и сам символ при его наличии. Однако символ и его скан-код не извлекаются из буфера и могут быть снова получены при повторном вызове функции 00 h Int 16 h . Данная функция относится к числу асинхронных: определив состояние буфера ввода, она возвращает управление про-
    грамме.

    Вызов: AH = 01h (83/84-key ), 11h (101/102-key ).

    Возврат: ZF = 1, если буфер пуст и ZF = 0, если в буфере имеется ожидающий считывания символ. В этом случае:

    AL = ASCII -код символа/00h , AH = скан-код клавиши/расширенный ASCII- код.

    Функция 11 h (AH = 11 h) - усовершенствованный вариант функции 01 h для расширенной клавиатуры (101/102-key ). Позволяет получить расширенные ASCII -коды для клавиш F11, F12 , а также для ряда других комбинаций. В качестве признака управляющих клавиш или их комбинаций, помимо значения 00 h , используются 0Ah, 0Dh и E0h .

    ¨ Функция 02 h (12 h). Получение флагов клавиатуры.

    Возвращает байт флагов клавиатуры, описывающих состояние управляющих клавиш, записанное в байте (слове) области данных BIOS по адресу 0000 h:0417 h.

    Вызов: AH = 02 h

    Возврат: A L =1-ый байт флагов клавиатуры.

    Биты байта имеют следующие значения:

    0: 1 - правая Shift нажата

    1: 1 - левая Shift нажата

    2: 1 - Ctrl (любая) нажата

    3: 1 - Alt (любая) нажата

    4: 1 - режим Scroll Lock

    5: 1 - режим Num Lock

    6: 1 - режим Caps Lock

    7: 1 - режим Insert активен

    Функция 12 h (AH = 12 h) - усовершенствованный вариант функции 02 h для расширенной клавиатуры (101/102-key ). Выводит такое же значение байта, как и функция 02 h , по адресу 0000 h:0417 h , и, дополнительно, второй байт статуса клавиатуры (адрес 0000h:0418h) со следующими значениями:

    0: 1 - левая Ctrl нажата 4: 1 - нажата Scroll Lock

    1: 1 - левая Alt нажата 5: 1 - нажата Num Lock

    2: 1 - правая Ctrl нажата 6: 1 - нажата Caps Lock

    3: 1 - правая Alt нажата 7: 1 - нажата SysReg

    8.2.3.4. Задержка программных операций

    Программные задержки используются в тех случаях, когда в какой-либо точке программы надо приостановить её выполнение на некоторое время. По виду исполнения программные задержки делятся на два типа: задержки, реализуемые на основе выполнения программой "пустых" вложенных циклов, и задержки, реализуемые на основе системного таймера компьютера. В листинге 3.2 приведён пример реализации задержки первого типа.

    Листинг 3.2. Программная задержка на основе выполнения вложенных циклов с командой Loop .

    Proc delay ;Подпрограмма задержки

    Mov cx, N ;N - счётчик внешнего цикла

    Outer: push cx ;Сохраним содержание счётчик внешнего цикла

    Mov cx,0 ;Обеспечим максимальное число повторений (64К раз)

    ;внутреннего цикла

    Inner: loop Inner ;Внутренний цикл

    Pop cx ;Восстановим содержание счётчик внешнего цикла

    Loop Outer ;Повторим вешний цикл N раз

    В листинге 3.2 параметр N выполняет роль масштабного множителя времени задержки

    t зад = N* t исполнения внутреннего цикла .

    При этом наименьшей единицей времени (т.е. "тиком") является время выполнения внутреннего цикла, состоящего, в свою очередь, из времени исполнения 65535 раз команды Loop . Параметр N подбирается экспериментально для получения t зад (в мсек или сек) с учётом быстродействия конкретного компьютера.

    Из рассмотрения данного примера очевидны недостатки данного подхода, когда требуется обеспечить выполнение временной задержки в программе, независимо от типа используемого компьютера.Поэтому разумно определять время программной задержки непосредственно по таймеру. Выходные сигналы таймера с частотой 18,2 раза в секунду не зависят от производительности компьютера и играют роль счетчика суточного времени. Реализация данного способа использует функцию 00 h прерывания BIOS Int 1 Ah.

    Int 1А h, функция 00 h. Чтение счетчика циклов таймера.

    Обработчик прерывания BIOS от системного таймера (Int 8 ) подсчитывает количество прерываний (каждые 55 мсек или 18,2 раза в секунду) в двойном слове памяти с адресом 0040h:006С h . Данная функция возвращает накопленное значение (двоичный код) и сбрасывает его в 0 . В регистре AL возвращается 0 , если содержимое счетчика не превысило значения, соответствующего 24 часам (при достижении этого значения счетчик сбрасывается), иначе возвращается AL = 1.

    Вызов: АН = 00 h .

    Возврат: СХ:DX - число тактов системного времени от полуночи,

    AL - флаг перехода через сутки.

    Примеры возвращаемых значений в СХ:DX :

    1 сек 12h или 18,

    1 минута 04 44h или 1092,

    1 час 1 00 07h или 65543,

    24 часа 18 00 B0h или 1 573 040.

    Для задержек меньших 14 секунд можно пользоваться только младшим байтом регистра DX

    Листинг 3.3. B данном примере установлена задержка на 5 секунд, что соответствует 91 отсчету таймера

    ..........

    mov ah,0 ;Функция "чтения" циклов таймера

    int 1Ah ;Получаем значение счетчика циклов в cx:dx

    add dx,91 ;Добавляем 5 сек. к младшему слову в dx

    mov bx,dx ;Запоминаем требуемое значение в bx и выполняем

    ;постоянную проверку значений счетчика времени суток

    repeat: int 1Ah ;Вновь получаем значение счетчика

    cmp dx,bx ;Сравниваем с искомым

    jne repeat ;Если не равно, то повторяем снова,

    ;иначе задержка окончена

    Если требуется введение задержки с высокой точностью, то необходимо использовать функцию 86h прерывания BIOS Int 15h. Она позволяет определить время задержки в микросекундах. Во время выполнения задержки разрешены прерывания. Управление программе возвращается после истечения заданного времени.

    Int 15h, функция 86 h

    Вызов: AH = 86 h, С X: DX = время задержки в мксек.

    Возврат: CF = 0 - нормальное исполнение, CF = 1 - функция не поддерживается.

    Пример: CX: DX = 0098h: 9680h = 10 000 000 мксек = 10 сек.

    8.3. ВАРИАНТЫ ИНДИВИДУАЛЬНОГО ЗАДАНИЯ

    1. Инициализировать экран с определённым атрибутом. Наложить на него локальное окно меньшего размера с другим атрибутом цвета. В центральную часть окна вывести текст (несколько строк) из памяти с циклической реализацией скроллинга окна в несколько строк вверх и вниз. Смена типа скроллинга задаётся программной задержкой (2...3 сек.). Предусмотреть выход из программы.

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

    3. На экране инициализировать 2 локальных окна. Каждое окно со своим атрибутом и текстом с несколькими строками. Организовать циклическое переключение атрибутов первого окна на второе и обратно. Цикл переключения задаётся временной задержкой в 2...3 сек. Предусмотреть выход из программы.

    4. На экране инициализировать 2 локальных окна. Каждое окно со своим атрибутом и текстом в несколько строк. Организовать циклическое переключение текста из одного окна в другое с временной задержкой 2...3 сек. Предусмотреть выход из программы.

    5. На экране инициализировать окно_1 с атрибутом и текстом в несколько строк. Спустя время задержки 2...3 сек частично наложить на него окно_2 с другим атрибутом и текстом. Процесс зациклить. Предусмотреть выход из программы.

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

    7. На экране инициализировать локальное окно с атрибутом (и текстом). После нажатия командной клавиши окно начинает изменять свои размеры (пульсировать), увеличиваясь и уменьшаясь с определённым периодом. Временной шаг изменения размера окна должен быть много меньше периода
    пульсации.

    8. Инициализировать экран и локальное окно в нём со своими атрибутами. Организовать режим вывода текста в локальное окно с клавиатуры. Предусмотреть возможность редактирования текста, а также скроллинга окна при его заполнении.

    9. Инициализировать экран и два небольших локальных окна в нём. С помощью клавиши <Tab > организовать переключение курсора из одного окна в другое. Выбранное клавишей <Tab > окно приобретает повышенную яркость. Предусмотреть выход из программы.

    10. Инициализировать экран и два локальных окна в нём. В левое окно вывести первую половину таблицу ASCII , а в правое - вторую половину. Предусмотреть очистку окон и выход из программы.

    11. Инициализировать экран и два локальных окна в нём (каждое со своим атрибутом и текстом). Организовать циклическое переключение бита "яркость фона/мерцание". Выход из программы должен восстанавливать значение бита по умолчанию.

    12. Инициализировать экран и два локальных окна в нём. В левое окно вывести вторую половину таблицы ASCII c символами псевдографики. Используя навигацию курсора, c помощью клавиш (¬,-,®,¯)организовать возможность непрерывного воспроизведения прямых линий во втором окне.

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

    Вход: DS: SI - адрес ASCI- строки, AH - атрибуты;

    CX - число выводимых символов;

    DH/ DL - строка (row )/столбец (clm );

    Indent_ L, Indent_ R - поля отступа (в столбцах) слева и справа.

    Необходимо оптимизировать расчёт адреса видеобуфера ES: DI . Процедура должна возвращать исходное значение регистра ES .

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

    15. Разработать программу рисования прямоугольника, используя графические символы в кодировке ASCII. Координаты верхнего левого угла (строка, столбец) и нижнего правого должны вводиться с клавиатуры после соответствующего приглашения.

    8.4. КОНТРОЛЬНЫЕ ВОПРОСЫ

    1. Краткая характеристика возможностей, предоставляемых программисту базовой системой ввода-вывода BIOS, в сравнении с сервисными функциями DOS.

    2. Назовите объём видеопамяти для изображения одного символа и, соответственно, одной видеостраницы монитора в текстовом режиме.

    3. Дайте характеристику атрибута символа в видеобуфере.

    4. Разработайте макросы для:

    ¨ очистки экрана с установкой курсора в левый верхний угол экрана;

    ¨ позиционирования курсора в произвольную точку экрана с запоминанием его координат в памяти с помощью переменных row и clm ;

    ¨ вывода сообщения mes длиною leng и атрибутом цвета attrib с позиции, определяемой переменными row и clm .

    5. Какая функция BIOS предоставляет пользователю исчерпывающую информацию о нажатой клавише клавиатуры.

    Исходные данные
    Исходными данными может быть любой числовой набор данных, таких как горизонтальный или вертикальный диапазон, двумерный массив или даже не смежные диапазоны или отдельно заполненные ячейки. Для удобства я взял одномерный вертикальный массив А1:А5

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

    1. Решение с дополнительным столбцом

    В В1 напишите формулу

    ЕСЛИ(A1<>0;A1;"")


    и скопируйте её на диапазон В2:В5. Эта промежуточная формула в дополнительном столбце будет "убирать" из исходных данных нули, заменяя их на пустую строку ""

    В С1 напишите формулу

    Она и вернёт искомый результат - число 3

    ЕСЛИ(A1<>0;A1;"")


    надо использовать формулу

    ЕСЛИ(A1>0;A1;"")


    2. Решение формулой массива
    Для решения этой задачи используйте такую формулу массива:

    МИН(ЕСЛИ(A1:A5<>0;A1:A5))



    Как это работает: Вот эта часть формулы A1:A5<>0 формирует массив {ИСТИНА:ИСТИНА:ЛОЖЬ:ЛОЖЬ:ИСТИНА} , после чего применяя функцию ЕСЛИ() мы преобразуем массив в следующий: {5:7:ЛОЖЬ:ЛОЖЬ:3} . Так как функция МИН() игнорирует текстовые и логические значения, то в итоге получаем искомое - число 3

    Если в диапазоне есть отрицательные числа, то вместо формулы

    МИН(ЕСЛИ(A1:A5<>0;A1:A5))


    надо использовать формулу

    МИН(ЕСЛИ(A1:A5>0;A1:A5))


    3. Решение простой формулой
    Используйте такую формулу:

    НАИМЕНЬШИЙ(A1:A5;СЧЁТЕСЛИ(A1:A5;0)+1)



    Как это работает: С помощью функции СЧЁТЕСЛИ мы подсчитываем количество нулей в диапазоне и прибавив к этому количеству единицу мы возвращаем первое наименьшее число более нуля с помощью функции НАИМЕНЬШИЙ

    Если в диапазоне есть отрицательные числа, то вместо формулы

    Похожие статьи