Пильщиков В.Н. - Упражнения по языку ассемблера MASM (1110572), страница 4
Текст из файла (страница 4)
и пусть сегмент команд имеет имя CODE. Предполагая неопределенными значения регистров DS и ES и не используя регистр SS, реализовать (выписать подходящую директиву ASSUME и группу команд) следующее сложение массивов:
а) Y:=X+Y б) Z:=X+Y
6.11 C SEGMENT
ASSUME CS:C
X DW 1
BEG: MOV AX,Y
ADD AX,X
...
Y DW 2
C ENDS
При трансляции команды MOV ассемблер зафиксирует ошибку, тогда как трансляция команды ADD пройдет без ошибки. В чем разница между этими двумя случаями? Как исправить ошибку в команде MOV?
6.12 A SEGMENT
DB 400 DUP(?)
A ENDS
Выписать группу команд, копирующих самих себя в начало сегмента A.
6.13 Пусть в программе описан следующий сегмент данных:
S SEGMENT
A DB 100 DUP(4)
B DW 5,8,6
S ENDS
и пусть регистр DS уже установлен на начало этого сегмента. Определить, какое значение будет иметь регистр AX после выполнения каждой из следующих команд:
а) MOV AX,B б) MOV AX,OFFSET B в) LEA AX,B
г) MOV AX,B+2 д) MOV AX,OFFSET B + 2 е) MOV AX,B - OFFSET B
6.14 X DB 200 DUP(?) ; X[0..199]
Пусть в регистре BX находится адрес (смещение) одного из элементов массива X. Используя оператор OFFSET реализовать переход на метку L, если:
а) в BX находится адрес элемента X[37];
б) BX указывает на вторую половину массива X.
6.15 Описать полную программу для решения следующей задачи.
а) Напечатать фразу "Hello Wordl".
б) Дан текст из 50 символов. Определить, симметричен ли он. Ответ: "симметричен" или "не симметричен".
в) Дан массив из 40000 чисел (размером в слово). Определить, симметричен ли этот массив. Ответ: "да" или "нет".
г) Дан текст из любых символов (кроме точки), за которым следует точка и в котором не более 66000 символов. Напечатать этот текст в обратном порядке.
д) Дан непустой текст из любых символов (кроме точки), за которым следует точка. Напечатать этот текст, удалив из него лишние пробелы (из подряд идущих пробелов оставить только один).
е) Дан текст из больших латинских букв, за которым следует точка. Для каждой буквы указать, сколько раз она входит в этот текст.
ж) Дан непустой текст из любых символов (кроме точки), за которым следует точка. Определить, сколько различных больших русских гласных букв (А, Е, И, О, У, Ы, Э, Ю, Я) входит в этот текст.
6.16 Пусть под сегмент стека отведено 900 байтов. Реализовать переход на метку L, если в текущий момент:
а) стек полон;
б) стек пуст;
в) стек занимает ровно треть сегмента стека.
6.17 Используя любые регистры как вспомогательные, описать через другие команды действие команды:
а) PUSH AX б) POP AX
6.18 Определить, какие значения будут находиться в байте с адресом SS:SP и в байте с адресом SS:(SP+1) после выполнения команд
MOV AX,0102h
PUSH AX
6.19 Выписать фрагмент программы, в котором вводится последовательность ненулевых чисел, заканчивающаяся нулем, и эти числа выводятся в обратном порядке, но только если среди них нет отрицательных чисел (в противном случае ничего не выводить). Исходное значение регистра SP должно быть сохранено.
6.20 Пусть в стек записано 40 слов. Реализовать следующую операцию:
а) поменять местами два "верхних" слова стека, сохранив при этом значения всех регистров и не используя переменные;
б) определить, сколько среди этих слов нулевых, и записать ответ в регистр AL;
в) удалить из стека нулевые слова, "сжав" остальные (дополнительный массив не использовать);
г) определить, есть ли в стеке хотя бы два одинаковых слова, и записать ответ 1 (есть) или 0 в регистр AL;
д) рассматривая слова из стека как адреса (смещения) некоторых байтов из сегмента данных, обнулить все эти байты.
6.21 Пусть под сегмент стека отведено 200 слов и пусть в сегменте данных описан массив X из 200 слов. Выписать фрагмент программы, в котором в начало этого массива копируется текущее содержимое стека ("верхнее" слово стека должно быть записано в начальный элемент массива) и заполняется нулями оставшаяся часть массива. Значение регистра SP должно быть сохранено.
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 выводится строка вида
<адрес>:<содержимое>