ГЛАВА 21
МАКРОЯЗЫК
(часть 3/3)
Контрольные вопросы и упражнения - Описать с помощью подходящего блока повторения решение следующей задачи:
- записать в регистр AH сумму чисел из регистров AL, BL, CL и DH;
- обнулить переменные A, B и C типа DWORD;
- используя стандрартную функцию вывода на экран вывести (с кавычками) текст "A+B=B+A";
- зарезервировать (с помощью директивы DB) место в памяти для 40 байтов, присвоив им в качестве начальных значений первые 40 нечетных чисел (1, 3, 5, ..., 79).
- Выписать текст окончательной программы, который построит макрогенератор по следующему фрагменту исходной программы:
| Assembler | 1
2
3
| IRP C,<INC A,JE L>
C
ENDM |
|
| Assembler | 1
2
3
| IRP W,<SW,< A,2>>
MOV&W
ENDM |
|
| Assembler | 1
2
3
4
| N EQU 5
IRP OP,<N,%N,N%N>
ADD AX,OP
ENDM |
|
| Assembler | 1
2
3
4
| IRP C,<K,LL,M>
C EQU C&C&CC
DB 'C&C&CC'
ENDM |
|
| Assembler | 1
2
3
4
5
6
| IRP T,<AB,C>
IRPC U,T
DW U,T&U,T&&U
ENDM
DW U,T&U
ENDM |
|
| Assembler | 1
2
3
| IRPC CH,<! %">
ADD AL,'&CH' ;код CH
ENDM |
|
- Описать в виде указанных (слева) макросов указанные операции над двойными словами (X, Y и Z — переменные типа DWORD, L — метка):
| Assembler | 1
2
3
4
| 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 |
|
- . Описать в виде макроса DEF X, T, N, V определение массива X из N величин V, тип которых задается параметром T: при T = B это тип BYTE, при T = W — тип WORD, при T = D — тип DWORD.
Выписать текст, который построит макрогенератор по следующему фрагменту исходной программы:
| Assembler | 1
2
3
4
5
| K EQU 4
DEF C,B,10,'*'
DEF W,W,K+1,<TYPE C>
DEF ,D,%K+1,%(TYPE W)
DEF A,B,1,<1,2,3> |
|
- Описать полную программу, которая вводит три числа H, M и S и проверяет, удовлетворяют ли они следующим условиям: 0 <= H <=23, 0 <= M, S <= 59. Если нет,
программа должна выдать сообщение об ошибке, а иначе, трактуя эти числа как
час (H), минута (M) и секунда (S) некоторого момента суток, должна напечатать
время суток, на 1 секунду большее (с учетом смены суток).
Определить и использовать в этой программе два макроса, один из которых проверяет условие a <= X <= b, а другой — увеличивает X на 1 и, если X > b, обнуляет X.
- Описать в виде указанного (слева) макроса указанное действие над знаковыми числами размером в байт:
- ABS R,X : R := abs(X), где R — регистр, X — переменная
- SUM X,N : AX := сумма элементов массива X из N байтов (N > 0)
- MAX X,N : AL := максимум элементов массива X из N байтов (N > 0)
- Предположим, что следующих команд не существует. Опишите их в виде макроса (в качестве вспомогательных можно использовать регистры AX и BX):
- PUSH X (X — переменная размером в слово);
- POP X (X — переменная размером в слово);
- CALL P (P — имя близкой процедуры);
- RET N (близкий возврат);
- LOOP L (L — метка);
- Дано описание:
| Assembler | 1
2
3
4
5
6
7
8
9
10
| X DW 1234h
A MACRO R,U
MOV R,U
ENDM
B MACRO R,V
A R,<V>
ENDM
C MACRO R,V
A R,V
ENDM |
|
Определить значения регистров AH и AL после выполнения следующего фрагмента программы:
| Assembler | 1
2
| B AH,<BYTE PTR X>
C AL,<BYTE PTR X> |
|
- Описать в виде макроса 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+1,D
- Пусть K — числовая константа с положительным значением, а alpha, beta и gamma — некоторые группы предложений. Используя средства условного ассемблирования, выписать фрагмент исходной программы, в котором alpha, beta и gamma указаны лишь по разу и по которому в зависимости от значения K формируются следующие варианты окончательной программы:
при K = 1: при K = 2:при K > 2: | Assembler | 1
2
3
4
| bata
gamma
... (K раз)
gamma |
|
- Пусть RUN — константа, которая своим значением 1 или 0 указывает режим текущего прогона программы: счет или отладка. Используя средства условного ассемблирования, выписать фрагмент программы, в котором находится наибольший общий делитель двух положительных чисел с записью его в регистр AX, при условии, что в режиме счета эти два числа должны вводиться, а в режиме отладки эти числа равны 45 и 30.
- Имеются следующие описания макроса M X, который должен уменьшить значение X на 5, если X — это переменная-байт, или на 12, если X — это переменная-слово:
| Assembler | 1
2
3
4
5
6
7
8
9
| M MACRO X
LOCAL L2,L
CMP TYPE X,BYTE
JNE L2
SUB X,5
JMP L
L2: SUB X,12
L:
ENDM |
|
| Assembler | 1
2
3
4
5
6
7
8
9
10
| M MACRO X
LOCAL L2,L
MOV AL,TYPE X
CMP AL,BYTE
JNE L2
SUB X,5
JMP L
L2: SUB X,12
L:
ENDM |
|
| Assembler | 1
2
3
4
5
6
7
| M MACRO X
IF TYPE X EQ BYTE
SUB X,5
ELSE
SUB X,12
ENDIF
ENDM |
|
Какое из этих описаний неправильно (и почему) и какое из двух правильных описаний лучше другого (и почему)?
- Описать в виде макроса SHIFT X, K (X — имя байтовой переменной, K — явно заданное число) сдвиг значения X на | K | разрядов вправо (при K > 0) или влево (при K < 0).
Выписать макрорасширения для макрокоманд SHIFT A, -1 и SHIFT B, 5.
- Описать в виде макроса IF0 X, L (X — переменная размером в байт, слово или двойное слово, L — метка) переход на метку L в том случае, когда значение переменной X равно 0.
Выписать макрорасширения для макрокоманд IF0 B, L1 и IF0 D, L2 при условии, что B — переменная типа BYTE, а D — типа DWORD.
- Описать в виде макроса SIGN X (X — знаковая переменная размером в байт, слово или двойное слово) операцию засылки в регистр AL числа 1 при X > 0, числа 0 при X = 0 и числа -1 при X < 0.
Выписать макрорасширения для макрокоманд SIGN W и SIGN D при условии, что W — переменная размером в слово, а D — размером в двойное слово.
- Описать в виде макроса NULL X, N, T (X — имя массива из N байтов, N — положительное целое число, T — это FIRST или LAST) обнуление либо начального (при T = FIRST), либо последнего (при T = LAST) элемента массива X.
Выписать макрорасширение для макрокоманды NULL A, 100, LAST.
- Описать в виде макрос VAR X, EQ, V определение байтовой переменной с именем X и начальным значением V, а если последний параметр не задан — без начального значения (параметр EQ фиктивный).
Выписать макрорасширения для макрокоманд:- VAR A = '*'
- VAR B : <10 DUP(?)>
- VAR C
- VAR
- Описать в виде макроса NULL RS (RS — это <R1, R2, ..., Rk>, где Ri — имена регистров общего назначения, k >= 0) обнуление регистров Ri.
Выписать макрорасширения для макрокоманд NULL <AL, BX, SI> и NULL <>.
- Описать макрос SUM R, где R — имя (большими буквами) одного из 16-разрядных регистров общего назначения, для записи в R суммы значений всех остальных таких регистров.
- Описать в виде макроса OUTF без параметров вывод текущих значений флагов CF, OF, SF и ZF в виде четверки из 0 и 1, причем значения всех флагов и используемых макросом регистров должны быть сохранены.
Воспользоваться командами PUSHF и POPF. В регистре флагов Flags указанным флагам соответствуют биты со следующими номерами (нумерация битов справа налево от 0):
CF — 0, OF — 11, SF — 7, ZF — 6.
- Описать в виде макроса SL RS, OP (RS — это <R1, R2, ..., Rk>, где Ri — 16-разрядные регистры общего назначения, k > 0; OP — это SAVE или LOAD) запись в стек (при OP = SAVE) или восстановление из стека (при OP = LOAD) регистров Ri.
Выписать макрорасширение для макрокоманды SL <AX, CX, DI>, LOAD.
- Описать в виде макроса SUM X (X — это <X1, X2, ..., Xk>, где Xi — имена знаковых байтовых переменных, k > 0) вычисление суммы значений Xi и записи ее в регистр BX.
Выписать макрорасширение для макрокоманды SUM <A, B, C>.
- Описать в виде макроса MAX X (X — это <X1, X2, ..., Xk>, где Xi — имена знаковых байтовых переменных, k > 0) вычисление максимума Xi и записи его в регистр AL. (Обратить особое внимание на метки, которые будут появляться в макрорасширениях.)
Выписать макрорасширение для макрокоманды MAX <A, B, A>.
- Предположим, что имеется процедура 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
- Выписать при указанном макроопределении макрорасширение для указанной макрокоманды:
| Assembler | 1
2
3
4
5
6
7
| MA MACRO K
JMP M1
MOV AX,K
M&K: ADD AX,K
ENDM
...
MA 1 |
|
| Assembler | 1
2
3
4
5
6
7
8
| MB MACRO K
MOV AH,K
IFIDN <AH>,<2>
ADD AH,K
ENDIF
ENDM
...
MB 2 |
|
| Assembler | 1
2
3
4
5
6
7
8
| MV MACRO K
A EQU K
IFDIF <A>,<K>
ADD DX,A&K
ENDIF
ENDM
...
MV 3 |
|
| Assembler | 1
2
3
4
5
6
7
8
| MG MACRO K
IFDIF <K+1>,<5>
MOV AX,K
ENDIF
MOV BX,K&K
ENDM
...
MG 4 |
|
| Assembler | 1
2
3
4
5
6
7
8
| MD MACRO K
IF K+1 EQ 6
X DB '&K+1'
ENDIF
Y&K DW K+1
ENDM
...
MD 5 |
|
| Assembler | 1
2
3
4
5
6
7
8
| ME MACRO K
MOV AH,0
IRPC C,K-1
ADD AH,'&C'
ENDM
ENDM
...
ME 6 |
|
0
|