TASKASM1 (1109490), страница 3
Текст из файла (страница 3)
в) Ввести текст из 100 (любых) символов и для каждой большой латинской буквы определить, сколько раз она входит в этот текст.
г) Ввести 45 различных знаковых чисел и найти сумму чисел между максимальным и минимальных из этих чисел.
д) Ввести дату, заданную в формате
<десятичное число>/<номер месяца римскими цифрами>
(например: 5/XII, 12/IV), и вывести ее в формате
<десятичное число> <название месяца>
(например: 5 декабря, 12 апреля).
Глава 8. СТЕК.
Сегмент стека, регистры SS и SP. Стековые команды (PUSH, POP, PUSHF,
POPF). Приемы работы со стеком. Регистр BP и доступ к элементам стека.
УПРАЖНЕНИЯ.
8.1 X и Y - переменные размером в двойное слова. Выписать команды,
которые пересылают значение X в Y через стек, т.е. выполняют присваивание
Y:=X.
8.2 Определить, какие значения будут находиться в байте с адресом
SS:SP и в байте с адресом SS:(SP+1) после выполнения команд
MOV AX,0102h
PUSH AX
8.3 Если на сегмент стека отведено 200 байтов и текущее значение ре-
гистра SP равно 150, то сколько сейчас слов записано в стеке?
8.4 Под сегмент стека отведено 256 байтов. Выписать группу команд,
записывающих в стек содержимое регистра DX, но только если стек не полон
(при полном стеке передать управление на метку ERR1), и группу команд,
считывающих в регистр DX слово из вершины стека, но только если стек не
пуст (при пустом стеке передать управление на метку ERR2).
8.5 Выписать фрагмент программы, в котором вводится вводится последовательность ненулевых чисел, заканчивающаяся нулем, и эти числа выводятся
в обратном порядке, но только если среди них нет отрицательных чисел (в
противном случае ничего не выводить). Исходное значение регистра SP должно быть сохранено.
8.6 В стек записано 40 слов. Определить, сколько из них нулевых, и
записать ответ в регистр AL.
8.7 В стек записано 49 байтов. Определить, есть ли среди них хотя бы
два одинаковых. Ответ 1 (есть) или 0 записать в регистр AL.
8.8 Пусть под сегмент стека отведено 200 слов и пусть в сегменте дан-
ных описан массив X из 200 слов. Скопировать в начало этого массива теку-
щее содержимое стека ("верхнее" слово стека должно быть записано в на-
чальный элемент массива), заполнив нулями оставшуюся часть массива. Зна-
чения регистров SP и BP должны быть сохранены.
8.9 Под сегмент стека отведено 30 слов. Скопировать текущее содержи-
мое стека в область памяти, начинающуюся с абсолютного адреса 3B128h.
Значения регистров DS, ES, SS, SP и BP должны быть сохранены.
8.10 В стек записано 14 слов, каждое из которых - это адрес (смещение) некоторого байта в сегменте данных. Обнулить все эти байты.
8.11 Выписать программу для решения следующей задачи.
а) Для ввода задана последовательность символов, представляющая собой
(без ошибок) формулу следующего вида:
<формула> ::= <цифра> | (<формула> <знак> <формула>)
<знак> ::= + | -
<цифра> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
Вычислить значение этой формулы. (Пример: ((5-2)+7) --> 10)
б) Для ввода задана последовательность символов, представляющая собой
(без ошибок) формулу следующего вида:
<формула> ::= <цифра> | M(<формула>,<формула>) | m(<формула>,<формула>)
<цифра> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
где M трактуется как max (максимум), а m - как min (минимум).
Вычислить значение этой формулы. (Пример: M(2,m(5,7)) --> 5)
Глава 9. ПРОЦЕДУРЫ.
Дальние безусловные переходы. Описание процедур, команды CALL и RET. Пе-
редача параметров (по значению и по адресу) через регистры. Передача па-
раметров через стек, "входные" и "выходные" действия процедуры. Локальные
данные процедуры. Реализация рекурсивных процедур.
УПРАЖНЕНИЯ.
9.1 Описать программу, которая вводит 4 положительных числа и опреде-
ляет их наибольший общий делитель.
В программе описать и использовать процедуру нахождения наибольшего
общего делителя двух чисел (эти числа-параметры передавать через регист-
ры) при условии, что:
а) в программе должен быть только один сегмент команд,
б) процедура должна быть описана в отдельно сегменте команд.
9.2 Используя из операций ввода только операцию INCH, описать проце-
дуру INBYTE, которая вводит десятичное число от 0 до 255 (число задано
без ошибок, за ним следует пробел) и присваивает его байтовой переменной,
адрес (смещение в сегменте данных) которой передается процедуре через ре-
гистр BX.
9.3 Описать процедуру NEGATIVE, которой через регистр BX передается
адрес некоторой переменной (из сегмента данных) размером в двойное слово
и которая меняет ее значение на противоположное (меняет знак).
Используя эту процедуру, выписать фрагмент программы, в котором меня-
ются знаки у переменных X, Y и Z, имеющих размер двойного слова.
9.4 DATE STRUC ;тип "дата"
D DB ? ;день
M DB ? ;месяц
Y DW ? ;год
DATE ENDS
Описать процедуру LESS, которая сравнивает две даты типа DATE, адрес пер-
вой их которых передается через регистр SI, а адрес второй - через DI, и
которая возвращает через регистр AL свой ответ: 1, если первая дата пред-
шествует второй, и 0 иначе.
9.5 Описать процедуру OUTARR, осуществляющую вывод байтового массива,
чей начальный адрес передается через регистр BX, а количество элементов -
через регистр CX. Используя эту процедуру, выписать фрагмент программы
для решения следующей задачи: если последний элемент 60-байтового массива
A равен среднему элементу 101-байтовому массиву B, тогда вывести массив
A, иначе вывести массив B.
9.6 Описать подходящую процедуру и, используя ее, выписать фрагмент
программы для решения следующей задачи.
Имеются массивы X[0..59], Y[0..22] и Z[0..89] из знаковых чисел-слов.
Требуется заменить максимальный элемент массива X на последний элемент
массива Y и заменить все элементы массива Z, предшествующие его макси-
мальному элементу, на максимальный элемент массива Z. (Считать, что в ка-
ждом массиве только один максимальный элемент.)
9.7 Описать процедуру F(X,N,P), подсчитывающую количество элементов
массива X из N слов, равных числу P, при условии, что адрес X передается
через регистр BX, число N - через CX, число P - через AL, а результат
процедуры возвращается через регистр AL.
Использовать эту процедуру для вычисления
K:=F(A,70,F(B,30,K))
где A - массив из 70 слов, B - массив из 30 слов, а K - байтовая перемен-
ная.
9.8 Описать дальнюю процедуру SIGN, которая определяет знак своего
параметра (выдает 1 при положительном параметре, 0 при нулевом и -1 при
отрицательном), при условии, что результат процедура возвращает через ре-
гистр AL, а параметр ей передается (по значению) через стек.
Процедуру описать в двух вариантах:
а) размер параметра - слово,
б) размер параметра - байт.
9.9 Описать близкую процедуру SETABS, которой через стек передается
адрес (смещение в сегменте данных) некоторой знаковой байтовой переменной
и которая заменяет ее значение на абсолютную величину.
Использовать эту процедуру для решения следующей задачи: A и B -
знаковые байтовые переменные; при A>B заменить на абсолютную величину
значение переменной B, иначе - переменной A.
9.10 Описать дальнюю процедуру ZERO от 20 параметров, которые переда-
ются через стек и каждый из которых представляет собой адрес некоторой
байтовой переменной (из сегмента данных). Процедура должна обнулить те из
этих переменных, значения которых положительны.
9.11 Описать близкую процедуру, которая определяет, есть ли в задан-
ном байтовом массиве хотя бы два равных элемента, при условии, что пара-
метры (начальный адрес массива и число элементов в нем) передаются через
стек.
Использовать эту процедуру для решения следующей задачи: если в мас-
сиве X из 400 байтов есть повторяющиеся элементы, а в массиве Y из 60
байтов все элементы различны, тогда в регистр AL записать 1, а иначе за-
писать 0.
9.12 Используя из операций вывода только операцию OUTCH, описать
дальнюю процедуру OUTW, которая выводит в десятичном виде и без незнача-
щих нулей беззнаковое число размером в слово, переданное процедуре:
а) через регистр AX,
б) через стек.
Процедура должна выделять десятичные цифры числа справа налево и вре-
менно сохранять их в массиве, место под который отводится в стеке.
9.13 Описать близкую процедуру, которая за один просмотр заданного
байтового массива циклически сдвигает его элементы на заданное число по-
зиций вперед, при условии, что параметры для процедуры (способ передачи
параметров - через регистры или стек - выбрать самим). В своей работе
процедура должна использовать вспомогательный массив, отведя место для
него в стеке.
Использовать эту процедуру для решения следующей задачи: элементы
300-байтового массива X циклически сдвинуть на 40 позиций вперед, а эле-
менты 80-байтового массива Y - на 15 позиций.
9.14 Для каждой из байтовых переменных A и B вывести строку вида
<адрес>:<содержимое>
где <адрес> - это адрес (смещение в сегменте данных) переменной в виде
четырехзначного шестнадцатиричного числа, а <содержимое> - значение пере-
менной в виде двузначного шестнадцатиричного числа (например: 01A8:F5).
При решении этой задачи описать и использовать следующие процедуры:
- вывод числа от 0 до 15 в шестнадцатиричном виде,
- вывод байта в виде двух шестнадцатиричных цифр,
- вывод строки указанного вида для одной переменной.
9.15 Описать программу, которая в цикле вводит приказы указанных ниже
типов и тут же выполняет их. (Считать, что приказы задаются без ошибок.)
Возможные приказы:
S seg:ofs. - напечатать в шестнадцатиричном виде (4 цифры) слово,
абсолютный адрес которого определяется парой seg:ofs
(номер сегмента : смещение);
L seg:ofs=w. - в слово памяти, абсолютный адрес которого задан парой
seg:ofs, записать новое значение w;
E. - завершить работу программы.
Здесь seg, ofs и w - шестнадцатиричные числа (от 1 до 4 цифр), причем
"буквенные" цифры могут быть записаны как большими (от A до F), так и ма-
лыми (от a до f) латинскими буквами.
9.16 Для ввода задана последовательность положительных чисел, за ко-
торой следует 0. Описать рекурсивную процедуру REVERSE, которая вводит
эти числа и выводит их (без 0) в обратном порядке.
9.17 Описать рекурсивную процедуру C, вычисляющую биномиальный коэф-
фициент C(m,n), где 0<=m<=n, по следующей формуле:
| 1 при m=0 или m=n
C(m,n) = {
| C(m,n-1)+C(m-1,n-1) при 0<m<n
Параметры n и m передаются процедуре через регистры AH и AL соответс-
твенно, а свой ответ она возвращает через регистр BX.
9.18 Описать рекурсивную процедуру MM, которая вводит последователь-
ность символов, представляющую собой правильную запись формулы следующего
вида:
<формула> ::= <цифра> | M(<формула>,<формула>) |
m(<формула>,<формула>)
<цифра> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
(M трактуется как максимум (max), а m - как минимум (min)), которая вы-
числяет значение этой формулы (как число) и присваивает его регистру AL.
9.19 Описать программу, которая вводит текст вида
<формула> = <формула>
где
<формула> ::= <цифра> | (<формула> <знак> <формула>)
<цифра> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
<знак> ::= + | -
и которая определяет, равны ли значения двух указанных формул, и печатает
ответ ДА или НЕТ.
В программе описать и использовать рекурсивную процедуру, которая
вводит и вычисляет значение одной формулы.
9.20 Описать процедуру SELFCOPY без параметров, действие которой зак-
лючается в том, что она копирует саму себя (все относящиеся к ней машин-
ные коды) в область памяти, начинающуюся с абсолютного адреса 12345h.
Глава 10. ДИНАМИЧЕСКИЕ СТРУКТУРЫ ДАННЫХ.
Флаг направления DF, команды STD и CLD. Строковые команды (CMPS, SCAS,
MOVS, LODS, STOS). Префиксы повторения. Команды LDS и LES. Строки пере-
менной длины: представление и операции. Списки: представление и операции;
организация куч, реализация процедур NEW и DISPOSE.
УПРАЖНЕНИЯ.
10.1 S DB 100 DUP(?)
Рассматривая S как 100-символьную строку фиксированной длины, размещенную
в сегменте памяти, на начало которого уже установлены регистры DS и ES, и
используя строковые команды, выписать фрагменты программы для решения
следующих задач.