TASKASM1 (1109490), страница 4
Текст из файла (страница 4)
а) Подсчитать, сколькими пробелами оканчивается строка S; ответ запи-
сать в регистр AL.
б) Определить индекс (при нумерации индексов от 1) первого вхождения
буквы 'Q' в строку S и записать его в регистр DI; если эта буква не вхо-
дит в S, то в DI записать 0.
в) Записать в регистр BH число вхождений символа '*' в строку S.
г) В строке S заменить все пробелы на точку.
д) Циклически сдвинуть элементы строки S на две позиции влево.
е) Если левая и правая половины строки S не равны, заменить левую по-
ловину на правую.
ж) В строке S заменить большие латинские буквы на соответствующие ма-
лые.
10.2 S DB 256 DUP(?) ;длина(S)<=255
T DB 101 DUP(?) ;длина(T)<=100
Рассматривая S и T как символьные строки переменной длины (с текущей дли-
ной в начальном байте), размещенные в одном сегменте памяти, на начало
которого уже установлены регистры DS и ES, и используя строковые команды,
выписать фрагменты программы для решения следующих задач.
а) Сделать значением S строку из 50 пробелов.
б) Удалить все пробелы в конце строки S.
в) Удалить все пробелы в начале строки S.
г) Удалить из строки S все пробелы.
д) Если в строке S от 10 до 40 символов, то удвоить ее 10-й символ.
е) В конец строки S дописать символы строки T, отбросив лишние (256-й
и последующие) символы, если такие окажутся.
ж) Сравнить строки S и T; если они равны, в регистр AL записать 1, не
равны - записать 0.
з) Определить, является ли строка T подстрокой строки S; ответ 1 (яв-
ляется) или 0 записать в регистр AL.
10.3 Описать процедуру DELDIG, удаляющую все цифры из строки перемен-
ной длины (с текущей длиной в начальном байте), абсолютный адрес начала
которой в виде пары seg:ofs передается через стек, причем часть seg запи-
сана в стек первой. (Рекомендация: воспользоваться командами LDS и LES.)
10.4 Считая, что уже описаны константа NIL, тип NODE и процедуры NEW
и DISPOSE, что регистр ES уже установлен на начало сегмента кучи и что в
сегменте данный описана переменная-слово LIST, значение которой трактует-
ся как ссылка на список из знаковых чисел-слов, выписать фрагменты прог-
раммы для решения следующих задач.
а) Определить количество нулевых элементов в списке LIST и записать
ответ в регистр AX.
б) Если в списке LIST не менее двух элементов, то обнулить его пред-
последний элемент. (Рекомендация: хранить в двух модификаторах, например
BX и SI, адреса текущего и предыдущего звеньев списка.)
в) Построить список LIST из 50 элементов - чисел от 1 до 50. (Реко-
мендация: список строить от конца.)
г) В список LIST вставить нулевой элемент после первого отрицательно-
го элемента.
д) В список LIST вставить нулевой элемент перед первым отрицательным
элементом.
е) Удалить из списка LIST первый нулевой элемент.
ж) Перенести первый элемент непустого списка LIST в конец списка.
з) Перенести последний элемент непустого списка LIST в начало списка.
и) Уничтожить список LIST, освободив место, занимаемое его эвеньями,
и присвоить переменной LIST значение NIL.
к) Ввести непустую последовательность положительных чисел, за которой
следует 0, и определить, сколько раз в этой последовательности повторяет-
ся ее максимальный элемент, записав ответ в регистр AX (список, созданный
при решении этой задачи, в конце уничтожить).
л) Определить, есть ли в списке LIST хотя бы два равных элемента, и
записать ответ 1 (есть) или 0 в регистр AL.
10.5 Очередью (queue) называется последовательность элементов, в ко-
торой добавление и удаление элементов производятся согласно следующему
правилу: новый элемент всегда добавляется в конец очереди, а первым из
очереди всегда удаляется ее начальный элемент. (Примеры очередей хорошо
известны из жизни.)
Очередь можно представить в виде списка, в котором элементы распола-
гаются в порядке их поступления в очередь. При этом желательно хранить
как ссылку на начало этого списка (отсюда будут удаляться элементы очере-
ди), так и ссылку на последнее звено списка (к нему будут добавляться но-
вые элементы). Зная эти две ссылки, можно считать, что известна и вся
очередь, поэтому формально очереди можно рассматривать как структуры сле-
дующего типа:
QUEUE STRUC
FIRST DW NIL ;ссылка на начало очереди
LAST DW ? ;ссылка на конец очереди
QUEUE ENDS
(в пустой очереди поле FIRST равно NIL, а поле LAST может быть любым).
Задать конкретную очередь - значит задать имя (адрес) переменной-структу-
ры (из сегмента данных) типа QUEUE.
Считая, что в программе используется несколько очередей из элементов
размером в слово и что уже определены все средства для работы со списками
(см. предыдущее упражнение), описать в виде процедур следующие действия
над очередью (ее адрес передается через регистр BX):
- проверить, пуста ли очередь; ответ 1 (пуста) или 0 (не пуста) вер-
нуть через флаг нуля ZF;
- очистить очередь (сделать ее пустой, освободив место, занимаемое ее
элементами);
- добавить в очередь новый элемент, заданный в регистре AX;
- удалить из очереди первый элемент и записать его в регистр AX (если
очередь пуста, сообщить от ошибке и прекратить выполнение программы).
Используя эти процедуры, решить следующую задачу: ввести заданную по-
следовательность положительных чисел, за которой следует 0, и вывести эти
числа в следующем порядке: сначала все числа величиной от 100 до 300, за-
тем все числа меньше 100 и в конце, но только если было хотя бы одно чис-
ло меньше 100, все остальные числа (в каждой из этих трех групп сохранять
исходный взаимный порядок чисел).
Глава 11. МАКРОСРЕДСТВА.
Макрогенератор и этап макрогенерации. Блоки повторения (REPT, IPR, IPRC).
Макрооператоры (&, <>, !, %, ;;). Макросы: макроописания, макрокоманды,
макроподстановки и макрорасширения; отличие макросов от процедур; дирек-
тивы LOCAL, EXITM и PURGE. Условное ассемблирование: IF-блоки, директивы
IF и IFE, IFIDN и IFDIF, IFB и IFNB. Операторы отношения (EQ, NE, LT, LE,
GT, GE) и логические операторы (NOT, AND, OR, XOR).
УПРАЖНЕНИЯ.
11.1 Описать с помощью подходящего блока повторения решение следую-
щей задачи:
а) записать в регистр AH сумму чисел из регистров AL, BL, CL и DH;
б) обнулить переменные A, B и C размером в двойное слово;
в) используя из операций вывода только операцию OUTCH, вывести (с ка-
вычками) текст "A+B=B+A";
г) зарезервировать (с помощью директивы DB) в памяти место для 40
байтов, присвоив им в качестве начальных значений первые 40 нечетных чи-
сел (1, 3, 5, ..., 79).
11.2 Выписать текст окончательной программы, который построит макро-
генератор по следующему фрагменту исходной программы:
а) IRP C,<INC A,JE L> б) IRP W,<SW,< A,2>> в) N EQU 5
C MOV&W IRP OP,<N,%N,N%N>
ENDM ENDM ADD AX,OP
ENDM
г) IRP C,<K,LL,M> д) IRP T,<AB,C> е) IRPC CH,<! %">
C EQU C&C&CC IRPC U,T ADD AL,'&CH' ;код CH
DB 'C&C&CC' DW U,T&U,T&&U ENDM
ENDM ENDM
DW U,T&U
ENDM
11.3 Описать в виде указанных макросов указанные операции над двойны-
ми словами (X,Y и Z - переменные типа dword, L - метка):
DMOV X,Y : X:=Y
DADD X,Y,Z : X:=Y+Z
DSUB X,Y,Z : X:=Y-Z
DJNE X,Y,L : при X<>Y перейти на L
11.4 Описать полную программу, которая вводит три числа H, M и S и
проверяет, удовлетворяют ли они следующим условиям: 0<=H<=23, 0<=M,S<=59.
Если нет, программа должна выдать сообщение об ошибке, а иначе, трактуя
эти числа как час (H), минута (M) и секунда (M) некоторого момента суток,
должна напечатать время суток, на 1 секунду большее (с учетом смены су-
ток).
Определить и использовать в этой программе два макроса, один из кото-
рых проверяет условие a<=X<=b, а другой - увеличивает X на 1 и, если X>b,
обнуляет X.
11.5 Описать в виде макроса DEF X,T,N,V определение массива X из N
величин V, тип которых задается параметром T: при T=B это тип BYTE, при
T=W - тип WORD, при T=D - тип DWORD.
Выписать текст, который построит макрогенератор по следующему фраг-
менту исходной программы:
K EQU 4
DEF CH,B,10,'*'
DEF W,W,K+1,<TYPE CH>
DEF ,D,%K+1,%(TYPE W)
DEF A,B,1,<1,2,3>
11.6 Описать в виде указанного макроса указанное действие над знако-
выми числами размером в байт:
а) ABS R,X : R:=abs(X), где R - регистр, X - переменная;
б) SUM X,N : AX:=сумма элементов массива X из N байтов (N>0);
в) MAX X,N : AL:=максимум элементов массива X из N байтов (N>0).
11.7 Описать в виде макроса указанную команду, предполагая, что ее
нет в ПК (в качестве вспомогательного можно использовать регистр BX):
а) PUSH X (X - переменная размером в слово);
б) POP X (X - переменная размером в слово);
в) CALL P (P - имя близкой процедуры);
г) RET N (близкий возврат);
д) LOOP L (L - метка);
е) REPE command (command - любая строковая команда).
11.8 Описать в виде макроса MAX2 M,X,Y вычисление M=max(X,Y) и на его
основе описать макрос MAX3 M,X,Y,Z для вычисления M=max(X,Y,Z), где M, X,
Y и Z - знаковые байтовые переменные.
Выписать макрорасширение для макрокоманды MAX3 A,<BYTE PTR B>,C.
11.9 Описать в виде макроса SHIFT X,K (X - имя байтовой переменной,
K - явно заданное число) сдвиг значения X на |K| разрядов вправо (при
K>0) или влево (при K<0).
Выписать макрорасширения для макрокоманд SHIFT A,-1 и SHIFT B,5.
11.10 Описать в виде макроса IF0 X,L (X - переменная размером в байт,
слово или двойное слово, L - метка) переход на метку L в том случае, ког-
да значение переменной X равно 0.
Выписать макрорасширения для макрокоманд IF0 B,L1 и IF0 D,L2 при ус-
ловии, что B - переменная типа BYTE, а D - типа DWORD.
11.11 Описать в виде макроса SGN X (X - знаковая переменная размером
в байт, слово или двойное слово) операцию засылки в регистр AL числа 1
при X>0, числа 0 при X=0 и числа -1 при X<0.
Выписать макрорасширения для макрокоманд SGN W и SGN D при условии,
что W - переменная размеров в слово, а D - размером в двойное слово.
11.12 Описать в виде макроса NULL X,N,T (X - имя массива из N байтов,
N - положительное целое число, T - слово FIRST или LAST) присваивание ну-
ля либо начальному (при T=FIRST), либо последнему (при T=LAST) элементу
массива X.
Выписать макрорасширение для макрокоманды NULL A,100,LAST.
11.13 Описать в виде макрос VAR X,EQ,V определение байтовой перемен-
ной с именем X и начальным значением V, а если последний параметр не за-
дан - без начального значения (параметр EQ фиктивный).
Выписать макрорасширения для макрокоманд:
а) VAR A = '*' б) VAR B : <10 DUP(?)> в) VAR C г) VAR
11.14 Описать в виде макроса OUTF без параметров вывод текущих значе-
ний флагов CF, OF, SF и ZF в виде четверки из 0 и 1, причем значения всех
флагов и используемых макросом регистров должны быть сохранены.
Воспользоваться командами PUSHF и POPF. В регистре флагов Flags ука-
занным флагам соответствуют биты со следующими номерами (нумерация битов
справа налево от 0): CF - 0, OF - 11, SF - 7, ZF - 6.
11.15 Описать в виде макроса NULL RS (RS - это <R1,R2,...,Rk>, где
Ri - имена несегментных регистров, k>=0) обнуление регистров Ri.
Выписать макрорасширения для макрокоманд NULL <> и NULL <AL,BX,SI>.
11.16 Описать в виде макроса SL RS,OP (RS - это <R1,R2,...,Rk>, где
Ri - регистры общего назначения, k>0; OP - слово SAVE или LOAD) запись в
стек (при OP=SAVE) или восстановление из стека (при T=LOAD) регистров Ri.
Выписать макрорасширение для макрокоманды SL <AX,CX,DI>,LOAD.
11.17 Описать в виде макроса SUM X (X - это <X1,X2,...,Xk>, где Xi -
имена знаковых байтовых переменных, k>=0) вычисление суммы X1+X2+...+Xk и
записи ее в регистр BX.
Выписать макрорасширение для макрокоманды SUM <A,B,C>.
11.18 Описать в виде макроса MAX X (X - это <X1,X2,...,Xk>, где Xi -
имена знаковых байтовых переменных, k>0) вычисление максимума Xi и запи-
си его в регистр AL. (Обратите особое внимание на метки, которые будут
появляться в макрорасширениях.)
Выписать макрорасширение для макрокоманды MAX <A,B,A>.
11.19 Предположим, что имеется процедура P от двух параметров, кото-
рые по значению передаются через регистры AX и BX. Описать в виде макроса
CALL_P X,Y команды обращения к этой процедуре, которые должны сохранять
регистры AX и BX и которые должны корректно работать, когда в качестве X
и Y указаны AX и/или BX. (Считать, что названия регистров записываются
только большими буквами.)
Выписать макрорасширения для макрокоманд:
а) CALL_P Q,2 б) CALL_P AX,BX в) CALL_P BX,5 г) CALL_P BX,AX
11.20 Выписать при указанном макроопределении макрорасширение для
указанной макрокоманды:
а) MA MACRO K б) MB MACRO K в) MV MACRO K
JMP M1 MOV AH,K A EQU K
MOV AX,K IFIDN <AH>,<2> IFDIF <A>,<K>
M&K: ADD AX,K ADD AH,K ADD DX,A&K
ENDM ENDIF ENDIF
MA 1 ENDM ENDM