TASK_ASM (1000388), страница 4
Текст из файла (страница 4)
6.22 Используя команды PUSHF и POPF, реализовать следующую операцию:
а) записать в регистр AL текущее значение флага SF, сохранив при этом значения всех флагов;
б) поменять на противоположное текущее значение флага SF, сохранив при этом значения всех остальных флагов.
(Замечание: флаг SF - это 7-й справа (при нумерации с 0) бит регистра флагов.)
6.23 Выписать программу для решения следующей задачи.
а) Для ввода задана последовательность символов, представляющая собой (без ошибок) формулу следующего вида:
<формула> ::= <цифра> | (<формула> <знак> <формула>)
<знак> ::= + | -
<цифра> ::= 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)
7. ПРОЦЕДУРЫ.
7.1 Используя регистр AX как вспомогательный, описать через другие команды действие команды:
а) CALL P (P - имя близкой процедуры);
б) RET n (в случае близкого возврата).
7.2 Описать программу, которая вводит 4 положительных числа и определяет их наибольший общий делитель.
В программе описать и использовать процедуру нахождения наибольшего общего делителя двух чисел (эти числа-параметры передавать через регистры) при условии, что:
а) в программе должен быть только один сегмент команд;
б) процедура должна быть описана в отдельном сегменте команд.
7.3 X DD ?
Описать близкую процедуру OUTW16, которая печатает в виде 4-значного беззнакового 16-ричного числа значение заданного слова. Используя эту процедуру, выписать фрагмент основной программы, печатающий значение переменной X в 16-ричном виде.
Выполнить это упражнение при условии, что параметр передается процедуре:
а) через регистр; б) через стек.
7.4 X DB 100 DUP(?) ; X[0..99]
Описать дальнюю процедуру SETABS, которой передается адрес (смещение в сегменте данных) некоторого знакового байта памяти и которая заменяет его значение на абсолютную величину. Используя эту процедуру, выписать фрагмент основной программы для решения следующей задачи: при X[0]>X[27] заменить на абсолютную величину значение элемента X[27], иначе - элемента X[0].
Выполнить это упражнение при условии, что параметр передается процедуре:
а) через регистр; б) через стек.
7.5 DATE STRUC ; тип "дата"
D DB ? ; день
M DB ? ; месяц
Y DW ? ; год
DATE ENDS
Описать близкую процедуру LESS, которая сравнивает две даты типа DATE и возвращает через регистр AL свой ответ: 1, если первая дата предшествует второй, и 0 иначе. Процедуру описать при условии, что адреса дат (смещения в сегменте данных) передаются ей:
а) через регистры SI (первая дата) и DI;
б) через стек (сначала в стек записывается адрес первой даты).
7.6 A DW ? ; числа со знаком
B DW ?
C DW ?
Выписать фрагмент основной программы, в котором значения переменных A, B и C перераспределяются так, чтобы оказалось ABC. Для решения этой задачи предварительно описать близкую процедуру MAXMIN(X,Y), которая перераспределяет значения X и Y так, чтобы большее из них оказалось в X, а меньшее - в Y.
Выполнить это упражнение при условии, что параметры передаются процедуре:
а) через регистры; б) через стек.
7.7 A DB 60 DUP(?) ; числа со знаком
B DB 101 DUP(?)
Описать дальнюю процедуру OUTARR8, которой передается начальный адрес знакового байтового массива и число элементов в нем и которая печатает этот массив. Используя эту процедуру, выписать фрагмент основной программы для решения следующей задачи: если последний элемент массива A равен среднему элементу массива B, тогда напечатать массив A, иначе - массив B.
Выполнить это упражнение при условии, что параметры передаются процедуре:
а) через регистры; б) через стек.
7.8 A DB 100 DUP(?) ; числа со знаком
B DW ?
Описать близкую процедуру SUM(X,N,S), которая присваивает параметру-слову S сумму элементов массива X из N знаковых байтов, и выписать команды, соответствующие следующему обращению к процедуре: SUM(A,100,B).
Выполнить это упражнение при условии, что параметры передаются процедуре:
а) через регистры; б) через стек.
7.9 Описать близкую процедуру F(X,N,P), определяющую, сколько элементов массива X из N байтов равно байту P, и возвращающую результат через регистр AL. Использовать эту процедуру для вычисления
K:=F(A,70,F(B,30,K))
где A - массив из 70 байтов, B - массив из 30 байтов, а K - байтовая переменная.
Выполнить это упражнение при условии, что параметры передаются процедуре:
а) через регистры; б) через стек.
7.10 Описать подходящую процедуру и, используя ее, выписать фрагмент основной программы для решения следующей задачи.
Имеются массивы X[0..59], Y[0..22] и Z[0..89] из знаковых чисел-слов. Требуется заменить максимальный элемент массива X на последний элемент массива Y и заменить все элементы массива Z, предшествующие его максимальному элементу, на максимальный элемент массива Y. (Считать, что в каждом массиве только один максимальный элемент.)
7.11 Описать подходящую процедуру и, используя ее, выписать фрагмент основной программы для решения следующей задачи.
Если в массиве X из 400 слов есть повторяющиеся элементы, а в массиве Y из 60 слов все элементы различны, тогда в регистр AL записать 1, а иначе записать 0.
7.12 Описать близкую процедуру SHIFT23, которой передается начальный адрес некоторого массива из 100 байтов и которая за один просмотр этого массива циклически сдвигает его элементы на 23 позиции вперед (влево). В своей работе процедура должна использовать вспомогательный массив, отведя ему место в стеке.
Выполнить это упражнение при условии, что параметр передается процедуре:
а) через регистр; б) через стек.
7.13 Описать дальнюю процедуру MAXLET для определения, какая из больших латинских букв чаще всего встречается в символьном массиве, начальный адрес которого передается через регистр BX, а число элементов в нем - через регистр CX (считать, что такая буква есть и она единственная). Свой ответ процедура должна вернуть через регистр AL. В своей работе процедура должна использовать вспомогательный массив, отведя ему место в стеке.
7.14 Используя из операций вывода только OUTCH, описать дальнюю процедуру OUTSTRING, действие которой эквивалентно операции вывода строки OUTSTR.
7.15 Описать близкую процедуру OUTW, печатающую значение регистра AX как беззнаковое число в системе счисления, основание которой (от 2 до 10) передается через регистр BL. (Обратить внимание на возможность переполнения в команде DIV.)
7.16 Используя из операций ввода-вывода только INCH и OUTSTR, описать дальнюю процедуру INDWORD, которая вводит десятичное число от 0 до 232-1 (концом числа считать первый символ, отличный от цифры) и записывает его в регистры DX (старшие цифры) и AX (младшие). Если число задано с ошибкой, то процедура должна выдать сообщение от ошибке ("нет цифр", "слишком большое число") и попросить повторить ввод числа, после чего заново начать ввод числа. Все используемые данные должны быть размещены в самой процедуре, после команды RET. (Следует учесть, что операция OUTSTR печатает строку, чей абсолютный начальный адрес передается через регистры DS:DX.)
7.17 Описать близкую процедуру SUM, которой через регистр BX передается начальный адрес, а через регистр CX - число элементов некоторого массива, элементы которого (размером в слово) являются адресами каких-то знаковых байтов в сегменте данных. Процедура должна найти сумму значений всех этих байтов и вернуть ответ через регистр AX.
7.18 Описать дальнюю процедуру ZERO от 20 параметров, которые передаются через стек и каждый из которых (размером в слово) представляет собой адрес некоторой знаковой байтовой переменной из сегмента данных. Процедура должна обнулить те из этих переменных, значения которых положительны.
7.19 Описать дальнюю процедуру CONCAT(S1,S2,...,Sn,S,n), которая осуществляет конкатенакцию (сцепление) n строк (символьных массивов из сегмента данных) Si и записывает получившуюся строку-результат (в ней сначала идут все символы из S1, затем - из S2, ..., в конце - из Sn) в строку S. Параметры процедуре передаются через стек в таком порядке: сначала в стек записываются данные (начальный адрес и длина-слово) о S1, затем - о S2, ..., в конце - о S и, наконец, число-слово n (>0), указывающее количество сцепляемых строк Si. Если длина строки-результат больше размера строки S, то лишние справа символы отбросить, если меньше - в конец S дописать пробелы.
7.20 A DB ?
B DB ?
Выписать фрагмент основной программы, в котором для каждой из переменных A и B выводится строка вида
<адрес>:<содержимое>
где <адрес> - это адрес (смещение) переменной в виде четырехзначного 16-ричного числа, а <содержимое> - значение переменной в виде двузначного 16-ричного числа (например: 01A8:F5).
При решении этой задачи описать и использовать следующие процедуры:
- вывод числа от 0 до 15 в 16-ричном виде;
- вывод байта в виде двух 16-ричных цифр;
- вывод строки указанного вида для одной переменной.
7.21 Описать программу, которая в цикле вводит приказы указанных ниже типов и тут же выполняет их. (Считать, что приказы задаются без ошибок.)
Возможные приказы:
S seg:ofs. - напечатать в 16-ричном виде (4 цифры) слово памяти, абсолютный адрес которого определяется парой seg:ofs (сегмент : смещение);
L seg:ofs=w. - в слово памяти, абсолютный адрес которого задан парой seg:ofs, записать новое значение w;
E. - завершить работу программы.
Здесь seg, ofs и w - 16-ричные числа (от 1 до 4 цифр), в которых "буквенные" цифры записываются большими латинскими буквами от A до F.
7.22 Описать программу, которая вводит два массива из 100 знаковых чисел-слов в каждом и определяет, составлены ли эти массивы из одних и тех же чисел (без учета порядка их следования, но с учетом повторяющихся чисел). (Рекомендация: упорядочить оба массива, а затем сравнить их.)
7.23 Описать близкую рекурсивную процедуру C, вычисляющую биномиальный коэффициент C(m,n), где 0mn, по следующей формуле:
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.
7.24 Для ввода задана последовательность символов (отличных от точки), за которой следует точка. Описать дальнюю рекурсивную процедуру REVERSE без параметров, которая вводит эти символы и выводит их (без точки) в обратном порядке.
7.25 Для ввода задана последовательность ненулевых чисел, за которой следует 0. Описать близкую рекурсивную процедуру PR без параметров, которая вводит эти числа и выводит сначала всех отрицательные числа, а затем - все положительные (в любом порядке).
7.26 Описать близкую рекурсивную процедуру BITS1, которая подсчитывает количество двоичных единиц в значении регистра AX и возвращает ответ через регистр BL.
7.27 Для ввода задана последовательность символов, представляющая собой правильную запись формулы следующего вида:
<формула> ::= <цифра> | M(<формула>,<формула>) |
m(<формула>,<формула>)
<цифра> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
(M трактуется как максимум (max), а m - как минимум (min)). Описать близкую рекурсивную процедуру MM без параметров, которая вводит эту формулу, вычисляет ее значение (как число) и присваивает его регистру AL.
7.28 Описать программу, которая вводит текст вида
<формула> = <формула>
где
<формула> ::= <цифра> | (<формула> <знак> <формула>)
<знак> ::= + | -
<цифра> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
и которая определяет, равны ли значения двух указанных формул. Ответ: ДА или НЕТ.
В программе описать и использовать рекурсивную процедуру, которая вводит и вычисляет значение одной формулы.
7.29 Описать близкую рекурсивную процедуру FORM без параметров, которая вводит текст из любых символов (кроме точки), за которым (обязательно) следует точка, и проверяет, удовлетворяет ли этот текст следующему определению:
<текст> ::= <пусто> | <элемент> <текст>