VMSS_Labs
.pdfxor al, 00010100b
4.Перейти на метку LAB, если установлен 4 бит регистра al, в противном случае продолжить выполнение программы.
test al, 00010000b jnz LAB
продолжаем
. . .
LAB:
5.Посчитать число единиц в регистре al, рассматривая байт, как набор
бит.
mov cx, b |
; число сдвигов |
|
xor bl, bl |
; обнуление BL |
|
LL: |
shl al, 1 |
; сдвиг влево на один разряд |
jnc NO |
; переход, если нет переноса |
|
inc bl |
; иначе увеличить BL |
|
NO: |
loop LL |
; возврат, если cx ≠0 |
4.3. Пример выполнения работы
Дан массив из 10 байт. Все байты имеют нулевые старшие биты. Необходимо каждый байт содержащий единицу в нулевом бите дополнить до четного числа единиц установкой седьмого бита.
Текст программы:
data segment
NB db 04h, 07h, 14h, 23h, 04h,38h, 3Fh, 2Ah0Dh, 34h data ends
code segment
assume cs: code. ds:data START: mov ax, data
31
|
mov ds, ax |
; Загрузить сегментный адрес данных |
|
lea bx, NB |
; bx-текущий адрес массива NB |
|
mov cx, 10 |
; cx-счетчик числа интераций |
BEG: |
mov al, [bx] |
; считать очередной байт массива |
|
test al, 1b |
; установлен ли бит 0? |
|
jz BITOCLR |
; нет, бит 0 сброшен |
|
; бит 0 установлен |
|
|
test al, 0ffh |
; четное число единиц? |
|
jp OK |
; да, больше ничего делать не надо |
|
or al, 80h |
; нечетное дополнить до четного? |
jmp short OK |
|
|
; бит 0 сброшен |
|
|
BITOCLR: test al, 0ffh |
; четное число единиц? |
|
|
jnp OK |
; нет, больше ничего делать не нужно |
|
or al,80h |
; нечетное, дополнить до нечетного |
OK: |
mov [bx], al |
; записать измененный байт массива |
|
loop BEG |
|
QUIT: |
mov ax, 4c00h ; Код завершения 0 |
|
|
Int 21h |
; Выход в DOS |
code ends |
|
|
end START |
|
4.4.Варианты заданий
1.Дан массив из 10 байт. Посчитать количество байт, в которых сброшены 6 и 4 биты.
2.Дан массив из 8 байт. Рассматривая его, как массив из 64 бит, посчитать количество единиц.
32
3.Дан массив из 8 байт. Рассматривая его как массив логических значений х0 х1 х2 х3 х4 х5 х6 х7 (true-есть ненулевые биты в байте, false-все биты нулевые), вычислить логическую формулу
f=(x7 & x6 & x1) V (x6 & x4 & x2 & x1 & x0) V (x7 & x6 & x3 & x1).
4.Дан массив из 10 байт. Посчитать количество байт с числом единиц в байте равным три.
5.Рассматривая байт как набор логических значений x7 x6 x5 x4 x3 x1 x0 (true -1, false - 0), вычислить логическую формулу
f=(x7 & x6 & x3 ) V (x6 & x4 & x2 & x1) V (x7 & x6 & x2 & x0)
6.Дан массив из 8 байт. Рассматривая его, как массив из 64 бит посчитать длину самой длинной последовательности единиц.
7.Дан массив из 10 байт. Посчитать количество единиц во всех разря-
дах, кратных трём: 3, 6, 9, …, 75, 78.
8.Дан массив из 5 байт. Рассматривая его как массив из 8 пятиразрядных слов, найти “исключающее или” всех 8 слов для выражения “10101”.
9.Дан массив из 6 байт. Рассматривая его, как массив из 48 бит, посчитать в нём количество нулей.
10.Дан массив из 8 байт. Рассматривая его, как массив из 64 бит, посчитать количество пар единиц в окружении нулей. Конец последовательности рассматривать как нуль.
11.Дан массив из 7 байт. Рассматривая его, как массив из восьми семибитных слов, посчитать количество слов с нечетным числом нулей в слове.
12.Дан массив из 9 байт. Рассматривая его как массив из 72 бит, посчитать число переходов между нулями и единицами.
13.Дан массив из 3 байт. Рассматривая его, как массив из 24 бит, посчитать количество одиночных единиц в окружении нулей. Конец последовательности рассматривать как нуль.
33
14.Дан массив из 6 байт. Посчитать количество байт число единиц, в которых не превышает 3.
15.Дан массив из 11 байт. Посчитать количество байт, в которых нет единиц, стоящих рядом.
16.Дан массив из 4 байт. Рассматривая его, как массив из 32 бит посчитать длину самой длинной последовательности нулей.
17.Дан массив из 6 байт. Посчитать количество единиц во всех разрядах, кратных пяти: 5, 10, …, 45.
18.Дан массив из 3 байт. Рассматривая его как массив из 8 трёхразрядных слов, найти “исключающее или” всех 8 слов для выражения “101”.
19.Дан массив из 7 байт. Рассматривая его, как массив из 56 бит, посчитать в нём количество нулей, стоящих после единицы. Конец последовательности рассматривать как нуль.
20.Дан массив из 8 байт. Рассматривая его, как массив из 64 бит, посчитать количество пар единиц в окружении нулей. Конец последовательности рассматривать как нуль.
21.Дан массив из 5 байт. Рассматривая его, как массив из восьми пятибитных слов, посчитать количество слов с чётным числом единиц в слове.
22.Дан массив из 6 байт. Рассматривая его, как массив из 48 бит, посчитать число двух единиц, стоящих между нулями. Конец и начало последовательности рассматривать как нули.
23.Дан массив из 3 байт. Рассматривая его, как массив из 24 бит, посчитать количество одиночных единиц в окружении нулей. Конец последовательности рассматривать как нуль.
24.Дан массив из 6 байт. Посчитать количество байт, число единиц в которых не превышает 3.
25.Дан массив из 11 байт. Посчитать количество байт, в которых нет единиц, стоящих рядом.
34
4.5.Вопросы по теме
1.В чем отличие команд test и and?
2.Как сбросить 5-й бит переменной байта ВВ?
3.Как установить 5-й бит переменной байта ВВ?
4.Как инвертировать 5-й бит переменной байта ВВ?
5.Как проверить установлен ли 5-й бит переменной байта ВВ?
6.Как проверить четным или нечетным является количество установленных бит в байте?
7.Какие флаги условий модифицируются после выполнения команд and, or, xor ?
8.В чем основное отличие команд логических и арифметических сдви-
гов?
9.Укажите максимальное число двоичных разрядов, на которые можно сдвинуть операнд с помощью одной команды сдвига?
35
5. Обработка символьной информации с помощью функций DOS
Прерыванием (interrupt),подробнее см. раздел 7, называется способ общения центрального процессора с периферийными устройствами. Периферийное устройство (клавиатура, дисковод и др.) посылает запрос на установление сеанса передачи, процессор прерывает выполнение основной программы и переходит на выполнение программы обработки запроса от периферийного устройства. Эта программа, драйвер устройства, предварительно загружена в память (резидентная программа) и её адрес известен процессору. Такая обработка запросов называется аппаратными прерываниями.
5.1. Программные прерывания и системные вызовы
Операционная система MS_DOS, как известно, является однозадачной операционной системой, т.е. одновременно может исполнять только одну задачу. Вместе с тем имеется необходимость во время выполнения основной задачи производить некоторые вспомогательные действия. Подход, основанный на предварительной загрузке резидентных программ, использованный в аппаратных прерываниях, которые можно вызывать в момент выполнения основной программы, например, переключение раскладки клавиатуры или обращение к дисководу, оказался очень продуктивным, так как делает MS-DOS псевдомногозадачной системой.
Вызовы резидентных программ, адрес которых заранее известен процессору, стали называть, по аналогии с аппаратными прерываниями, программными прерываниями, хотя никаких
36
прерываний на самом деле не происходит. В систему команд процессора ввели команду вызова программного прерывания, которая вызывает соответствующую резидентную программу.
Команда вызова программного прерывания имеет вид int <номер прерывания>
<номер прерывания> - число, обычно в шестнадцатеричное, в диапазоне 00h – 0FFh, определяет адрес вызываемой резидентной программы.
Некоторые резидентные программы, выполняющие низкоуровневое общение с периферийными устройствами записаны в ROM BIOS (Read Only Memory Base Input/Output System) и поставляются вместе с системной платой, например, учёт системного времени, форматирование секторов на дорожке диска и т.д., и не зависят от применяемой операционной системы.
Резидентные программы, использующие низкоуровневую систему резидентов BIOS и выполняющие более сложные задачи, например, файловые операции с диском, подгружаются в память при загрузке операционной системы. Их принято называть функциями операционной системы или системными вызовами.
Наибольшее число различных системных функций в MS-DOS сосредоточено в резидентной программе с номером прерывания 21h – диспетчер функций MS-DOS. В зависимости от значения, содержащегося при вызове прерывания в регистре ah, MS-DOS выполняет одну из нескольких десятков функций MS-DOS.
Все функции BIOS и DOS описаны в специальных справочниках с указанием для каждой функции набора входных и выходных параметров, передаваемых через регистры, а также перечнем возможных ошибок. В данной главе будут описаны функции прерывания 21h относящиеся к работе с клавиатурой и экраном ПЭВМ.
37
5.2. Описание функций работы с клавиатурой и дисплеем диспетчера функ-
ций MS-DOS
Для вызова функции прерывания DOS 21h необходимо проделать следующие действия:
•выбрать функцию, выполняющую требуемые действия;
•занести номер функции в регистр аh;
•подготовить другие регистры (если это необходимо);
•написать команду int 21h;
прочесть результаты или состояние из регистров, указанных в описании данной функции.
Ниже следует описание некоторых функций 21Н.
Функции 01Н
Выполняет ввод с клавиатуры одного символа и отоббражает его на экране.
• Вызов:
ah = 01h
• Возвращаемое значение:
аl = код ASCII введенного символа
•Примечание. Введенный символ отобращается на экране (выполняется эхо-отображение). Комбинация клавиш Ctrl/С (или Ctrl/Break) прекращает выполнение программ пользователя.
Функции 02Н
Выполняет отображение символа на стандартный вывод (дисплей).
•Вызов:
ah = 02h
dl = отображаемый символ
38
•Возвращаемое значение: нет
•Примечание. Символ отображается на стандартный вывод. Комбинация клавиш Ctrl/C (или Ctrl/Break) прекращает выполнение программ пользователя.
Функция 05Н
Выполняет отображение символа на принтер.
•Вызов:
аh = 02h
dl = символ для принтера
• Возвращаемое значение: нет
•Примечание. Символ отображается на принтер. Комбинация клавиш Ctrl/C (или Ctrl/Break) прекращает выполнение программ пользователя. Эта функция не возвращает ошибки состяния принтера.
Функция 07Н
Выполняет ввод с клавиатуры одного символа.
• Вызов:
аh=07h
• Возвращаемое значение:
al = код ASCIL введенного символа
•Примечание. Введенный символ не отображается на экране (не выполняется эхо-отображения). Комбинация клавиш Ctrl/C (или Ctrl/Break) прекращает выполнение программы пользователя.
Функция 08Н
Выполняет ввод с клавиатуры одного символа.
39
• Вызов:
аh=08h
• Возвращаемое значение:
al = код ASCII введенного символа
•Примечание. Введенный символ не отображается на экране (не выполняется эхо-отображение). Комбинация клавиш Ctrl/C ( или Ctrl/Break) прекращает выполнение программы пользователя.
Функция 09Н
Выполняет отображение строки на стандартный вывод.
•Вызов:
аh = 09Н
ds: dx=указатель на отображаемую строку
Возвращаемое значение:
нет
•Примечание: Строка отображается на стандартный вывод. $ признак конца строки, $ не отображается, dx содержит смещение строки, ds - сегментный адрес. Ниже приведены код управления курсором:
0dh (13) - перевод курсора в начало текущей строки; 0ah (10) - перевод курсора вниз на 1 строку;
08h (8) - перевод влево на 1 позицию;
07h (7) - звонок.
Пример.
Чтобы вывести на экран с новой строки текст: “Функция 09Н для выдачи текста на экран” и затем перевести курсор в следующую строку, следует в сегменте данных описать строку:
beg db 0dh, 0ah, “Функция 09Н для выдачи текста наэкран”, 0dh,0ah, “$”
40