Страница:
D10INPT ENDP
; Подготовка для печати:
; ----------------------
Ассемблер для IBM PC. Программы. 135
E10PRNT PROC NEAR
CMP LINECTR,60 ;Конец страницы?
JB E20 ; нет - обойти
CALL M10PAGE ; да - печатать заголовок
E20: MOV CH,00
MOV CL,NAMELEN ;Число символов в имени
LEA DX,NAMEFLD ;Адрес имени
CALL P10OUT ;Печатать имя
MOV CX,01 ;Один
LEA DX,LFEED ; перевод строки
CALL P10OUT
INC LINECTR ;Увеличить счетчик строк
E10PRNT ENDP
; Подпрограмма печати заголовка:
; -----------------------------
M10PAGE PROC NEAR
CMP WORD PTR PAGECTR,3130H ;Первая страница?
JE M30 ; да - обойти
MOV CX,01 ;
LEA DX,FFEED ; нет --
CALL P10OUT ; перевести страницу,
MOV LINECTR,03 ; установить счетчик строк
M30:
MOV CX,36 ;Длина заголовка
LEA DX,HEADG ;Адрес заголовка
M40:
CALL P10OUT
INC PAGECTR+1 ;Увеличить счетчик страниц
CMP PAGECTR+1,3AH ;Номер страницы = шест.xx3A?
JNE M50 ; нет - обойти,
MOV PAGECTR+1,30H ; да - перевести в ASCII
INC PAGECTR
M50: RET
M10PAGE ENDP
; Подпрограмма печати:
; -------------------
P10OUT PROC NEAR ;CX и DX установлены
MOV AH,40H ;Функция печати
MOV BX,04 ;Номер устройства
INT 21H ;Вызов DOS
RET
P10OUT ENDP
; Очистка экрана:
; --------------
Q10CLR PROC NEAR
MOV AX,0600H ;Функция прокрутки
MOV BH,60H ;Цвет (07 для ч/б)
MOV CX,0000 ;От 00,00
MOV DX,184FH ; до 24,79
INT 10H ;Вызов BIOS
RET
Q10CLR ENDP
; Установка курсора (строка/столбец):
Ассемблер для IBM PC. Программы. 136
; ----------------------------------
Q20CURS PROC NEAR ;DX уже установлен
MOV AH,02 ;Функция установки курсора
MOV BH,00 ;Страница Э 0
INT 10H ;Вызов BIOS
RET
Q20CURS ENDP
CODESG ENDS
END BEGIN
Ассемблер для IBM PC. Программы. 137
TITLE PRINASK (COM) Чтение и печать дисковых записей
CODESG SEGMENT PARA 'Code'
ASSUME CS:CODESG,DS:CODESG,SS:CODESG,ES:CODESG
ORG 100H
BEGIN JMP MAIN
; ---------------------------------------------------------
PATHPAR LABEL BYTE ;Список параметров для
MAXLEN DB 32 ; ввода
NAMELEN DB ? ; имени файла
FILENAM DB 32 DUP(' ')
SECTOR DB 512 DUP(' ') ;Область ввода для файла
DISAREA DB 120 DUP(' ') ;Область вывода
COUNT DW 00
ENDCDE DW 00
FFEED DB 0CH
HANDLE DW 0
OPENMSG DB '*** Open error ***'
PROMPT DB 'Name of file? '
; ----------------------------------------------------------
MAIN PROC NEAR ;Основная программа
CALL Q10SCR ;Очистить экран
CALL Q20CURS ;Установить курсор
A10LOOP:
MOV ENDCDE,00 ;Начальная установка
CALL C10PRMP ;Получить имя файла
CMP NAMELEN,00 ;Есть запрос?
JE A90 ; нет - выйти
CALL E10OPEN ;Открыть файл,
; установить DTA
CMP ENDCDE,00 ;Ошибка при открытии?
JNE A80 ; да - повторить запрос
CALL R10READ ;Прочитать первый сектор
CMP ENDCDE,00 ;Конец файла, нет данных?
JE A80 ; да - повторить запрос
CALL G10XPER ;Распечатать сектор
A80:
JMP A10LOOP
A90: RET
MAIN ENDP
; Подпрограмма запроса имени файла:
; --------------------------------
C10PRMP PROC NEAR
MOV AH,40H ;Функция вывода на экран
MOV BX,01
MOV CX,13
LEA DX,PROMPT
INT 21H
MOV AH,0AH ;Функция ввода с клавиатуры
LEA DX,PATHPAR
INT 21H
MOV BL,NAMELEN ;Записать
MOV BH,00 ; 00 в конец
Ассемблер для IBM PC. Программы. 138
MOV FILENAM[BX],0 ; имени файла
C90 RET
C10PRMP ENDP
; Открытие дискового файла:
; ------------------------
E10OPEN PROC NEAR
MOV AH,3DH ;Функция открытия
MOV AL,00 ;Только чтение
LEA DX,FILENAM
INT 21H
JNC E20 ;Проверить флаг CF
CALL X10ERR ; ошибка, если установлен
RET
E20:
MOV HANDLE,AX ;Сохранить номер файла
MOV AX,2020H
MOV CX,256 ;Очистить пробелами
REP STOSW ; область сектора
RET
E100PEN ENDP
; Подготовка и печать данных:
; --------------------------
G10XFER PROC NEAR
CLD ;Направление слева-направо
LEA SI,SECTOR ;Начальная установка
G20:
LEA DI,DISAREA
MOV COUNT,00
G30:
LEA DX,SECTOR+512
CMP SI,DX ;Конец сектора?
JNE G40
CALL R10READ ; да - читать следующий
CMP ENDCDE,00 ;Конец файла?
JE G80 ; да - выйти
LEA SI,SECTOR
G40:
MOV BX,COUNT
CMP BX,80 ;Конец области вывода?
JB G50 ; нет - обойти
MOV [DI+BX],0D0AH ; да - записать CR/LF
CALL P10PRNT
LEA DI,DISAREA ;Начало области вывода
G50:
LODSB ;Записать [SI] в AL,
; увеличить SI
MOV BX,COUNT
MOV [DI+BX],AL ;Записать символ
INC BX
CMP AL,1AH ;Конец файла?
JE G80 ; да - выйти
CMP AL,0AH ;Конец строки?
JNE G60 ; нет - обойти,
Ассемблер для IBM PC. Программы. 139
CALL P10PRNT ; да - печатать
JMP G20
G60:
CMP AL,09H ;Символ табуляции?
JNE G70
DEC BX ; да - установить BX:
MOV BYTE PTR [DI+BX],20H ;Заменит TAB на пробел
AND BX,0FFF8H ;Обнулить правые 8 бит
ADD BX,08 ; и прибавить 8
G70:
MOV COUNT,BX
JMP G30
G80: MOV BX,COUNT ;Конец файла
MOV BYTE PTR [DI+BX],0CH ;Прогон страницы
CALL P10PRNT ;Печатать последнюю строку
G90: RET
G10XFER ENDP
; Подпрограммы печати:
; -------------------
P10PRNT PROC NEAR
MOV AH,40H ;Функция печати
MOV BX,04
MOV CX,COUNT ;Длина
INC CX
LEA DX,DISAREA
INT 21H
MOV AX,2020H ;Очистить область вывода
MOV CX,60
LEA DI,DISAREA
REP STOSW
RET
P10PRNT ENDP
; Подпрограмма чтения сектора:
; ---------------------------
R10READ PROC NEAR
MOV AH,3FH ;Функция чтения
MOV BX,HANDLE ;Номер файла
MOV CX,512 ;Длина
MOV DX,SECTOR ;Буфер
INT 21H
MOV ENDCDE,AX
RET
R10READ ENDP
; Прокрутка экрана:
; ----------------
Q10SCR PROC NEAR
MOV AX,0600H
MOV BH,1EH ;Установить цвет
MOV CX,0000 ;Прокрутка (сскроллинг)
MOV DX,184FH
INT 10H
RET
Q10SCR ENDP
Ассемблер для IBM PC. Программы. 140
; Подпрограмма установки курсора:
; ------------------------------
Q20CURS PROC NEAR
MOV AH,02 ;Функция установки
MOV BH,00 ; курсора
MOV DX,00
INT 10H
RET
Q20CURS ENDP
; Вывод сообщения об ошибке:
; -------------------------
X10ERR PROC NEAR
MOV AH,40H ;Функция вывода на экран
MOV BX,01 ;Номер
MOV CX,18 ;Длина
LEA DX,OPENMSG ;Адрес сообщения
INT 1H
MOV NDCDE,01 ;Признак ошибки
RET
X10ERR ENDP
CODESG ENDS
END BEGIN
Ассемблер для IBM PC. Программы. 141
TITLE MACRO1 (EXE) Макрос для инициализации
; --------------------------------------------
INIT1 MACRO
ASSUME CS:CSEG,DS:DSEG,SS:STACK,ES:DSEG
PUSH DS
SUB AX,AX
PUSH AX
MOV AX,DSEG
MOV DS,AX
MOV ES,AX
ENDM ;Конец макрокоманды
; --------------------------------------------
0000 STACK SEGMENT PARA STACK 'Stack'
0000 20 [ ???? ] DW 32 DUP(?)
0040 STACK ENDS
; --------------------------------------------
0000 DSEG SEGMENT PARA 'Data'
0000 54 65 73 74 20 6F MESSGE DB 'Test of macro-instruction', 13
66 20 6D 61 63 72
6F 2D 69 6E 73 74
72 65 73 74 69 6F
6E 0D
001A DSEG ENDS
; --------------------------------------------
0000 CSEG SEGMENT PARA 'Code'
0000 BEGIN PROC FAR
INIT1 ;Макрокоманда
0000 1E + PUSH DS
0001 2B C0 + SUB AX,AX
0003 50 + PUSH AX
0004 B8 ---- R + MOV AX,DSEG
0007 8E D8 + MOV DS,AX
0009 8E C0 + MOV ES,AX
000B B4 40 MOV AH,40H ;Вывод на экран
000D BB 0001 MOV BX,01 ;Номер
0010 B9 001A MOV CX,26 ;Длина
0013 8D 16 0000 R LEA DX,MESSGE ;Сообщение
0017 CD 21 INT 21H
0019 CB RET
001A BEGIN ENDP
001A CSEG ENDS
END BEGIN
Macros:
N a m e Length
INIT1. . . . . . . . . . . . . . . . 0004
Segments and Groups:
N a m e Size Align Combine Class
CSEG . . . . . . . . . . . . . . . . 001A PARA NONE 'CODE'
DSEG . . . . . . . . . . . . . . . . 001A PARA NONE 'DATA'
STACK. . . . . . . . . . . . . . . . 0040 PARA STACK 'STACK'
Ассемблер для IBM PC. Программы. 142
Symbols:
N a m e Type Value Attr
BEGIN. . . . . . . . . . . . . . . . F PROC 0000 CSEG Length=001A
MESSAGE. . . . . . . . . . . . . . . L BYTE 0000 DSEG
Ассемблер для IBM PC. Программы. 143
TITLE MACRO2 (EXE) Использование параметров
; ------------------------------------------------
INIT2 MACRO CSNAME,DSNAME,SSNAME
ASSUME CS:CSNAME,DS:DSNAME,SS:SSNAME,ES:DSNAME
PUSH DS
SUB AX,AX
PUSH AX
MOV AX,DSNAME
MOV DS,AX
MOV ES,AX
ENDM ;Конец макрокоманды
; ------------------------------------------------
0000 STACK SEGMENT PARA STACK 'Stack'
0000 20 [ ???? ] DW 32 DUP(?)
0040 STACK ENDS
; ------------------------------------------------
0000 DSEG SEGMENT PARA 'Data'
0000 54 65 73 74 20 6F MESSAGE DB 'Test of macro', '$'
66 20 6D 61 63 72
6F 24
000E DSEG ENDS
; ------------------------------------------------
0000 CSEG SEGMENT PARA 'Code'
0000 BEGIN PROC FAR
INIT2 CSEG,DSEG,STACK
0000 1E + PUSH DS
0001 2B C0 + SUB AX,AX
0003 50 + PUSH AX
0004 B8 ---- R + MOV AX,DSEG
0007 8E D8 + MOV DS,AX
0009 8E C0 + MOV ES,AX
000B B4 09 MOV AH,09 ;Вывод на экран
000D 8D 16 0000 R LEA DX,MESSGE ;Сообщение
0011 CD 21 INT 21H
0013 CB RET
0014 BEGIN ENDP
0014 CSEG ENDS
END BEGIN
Ассемблер для IBM PC. Программы. 144
TITLE MACRO3 (EXE) Директивы .LALL и .SALL
; ------------------------------------------------
INIT2 MACRO CSNAME,DSNAME,SSNAME
ASSUME CS:CSNAME,DS:DSNAME,SS:SSNAME,ES:DSNAME
PUSH DS
SUB AX,AX
PUSH AX
MOV AX,DSNAME
MOV DS,AX
MOV ES,AX
ENDM
; ------------------------------------------------
PROMPT MACRO MESSAGE
; Макрокоманда выводит на экран любые сообщения
;; Генерирует команды вызова DOS
MOV AH,09 ;Вывод на экран
LEA DX,MESSAGE
INT 21H
ENDM
; ------------------------------------------------
0000 STACK SEGMENT PARA STACK 'Stack'
0000 20 [ ???? ] DW 32 DUP (?)
0040 STACK ENDS
; ------------------------------------------------
0000 DATA SEGMENT PARA 'Data'
0000 43 75 73 74 6F 6D MESSG1 DB 'Customer name?', '$'
65 72 20 6E 61 6D
65 3F 24
000F 43 75 73 74 6F 6D MESSG2 DB 'Customer address?', '$'
65 72 20 61 64 64
72 65 73 73 3F 24
0021 DATA ENDS
; ------------------------------------------------
0000 CSEG SEGMENT PARA 'Code'
0000 BEGIN PROC FAR
.SALL
INIT2 CSEG,DATA,STACK
PROMPT MESSG1
.LALL
PROMPT MESSG2
+ ; Макрокоманда выводит на экран любые сообщения
0013 B4 09 + MOV AH,09 ;Вывод на экран
0015 8D 16 000F R + LEA DX,MESSG2
0019 CD 21 + INT 21H
001B CB RET
001C BEGIN ENDP
001C CSEG ENDS
END BEGIN
Ассемблер для IBM PC. Программы. 145
TITLE MACRO4 (COM) Использование директивы LOCAL
; -------------------------------------------------
DIVIDE MACRO DIVIDEND,DIVISOR,QUOTIENT
LOCAL COMP
LOCAL OUT
; AX=делимое, BX=делитель, CX=частное
MOV AX,DIVIDEND ;Загрузить делимое
MOV BX,DIVISOR ;Загрузить делитель
SUB CX,CX ;Регистр для частного
COMP:
CMP AX,BX ;Делимое < делителя?
JB OUT ; да - выйти
SUB AX,BX ;Делимое - делитель
INC CX ;Частное + 1
JMP COMP
OUT:
MOV QUOTIENT,CX ;Записать результат
ENDM
; ------------------------------------------------
0000 CSEG SEGMENT PARA 'Code'
ASSUME CS:CSEG,DS:CSEG,SS:CSEG,ES:CSEG
0100 ORG 100H
0100 EB 06 BEGIN: JMP SHORT MAIN
; ------------------------------------------------
0102 0096 DIVDND DW 150 ;Делимое
0104 001B DIVSOR DW 27 ;Делитель
0106 ???? QUOTNT DW ? ;Частное
; ------------------------------------------------
0108 MAIN PROC NEAR
.LALL
DIVIDE DIVDND,DIVSOR,QUOTNT
+ ; AX=делимое, BX=делитель, CX=частное
0108 A1 0102 R + MOV AX,DIVDND ;Загрузить делимое
010B 8B 1E 0104 R + MOV BX,DIVSOR ;Загрузить делитель
010F 2B C9 + SUB CX,CX ;Регистр для частного
0111 + ??0000:
0111 3B C3 + CMP AX,BX ;Делимое < делителя?
0113 72 05 + JB ??0001 ; да - выйти
0115 2B C3 + SUB AX,BX ;Делимое - делитель
0117 41 + INC CX ;Частное + 1
0118 EB F7 + JMP ??0000
011A + ??0001:
011A 89 0E 0106 R + MOV QUOTNT,CX ;Записать результат
011E C3 RET
011F MAIN ENDP
011F CSEG ENDS
END BEGIN
Ассемблер для IBM PC. Программы. 146
TITLE MACRO5 (EXE) Проверка директивы INCLUDE
EDIF
; ------------------------------------------------
0000 STACK SEGMENT PARA STACK 'Stack'
0000 20 [????] DW 32 DUP(?)
0040 STACK ENDS
; ------------------------------------------------
0000 DATA SEGMENT PARA 'Data'
0000 54 65 73 74 20 6F MESSGE DB 'Test of macro','$'
66 20 6D 61 63 72
6F 24
000E DATA ENDS
; ------------------------------------------------
0000 CSEG SEGMENT PARA 'Code'
0000 BEGIN PROC FAR
INIT CSEG,DATA,STACK
0000 1E + PUSH DS
0001 3B C0 + SUB AX,AX
0003 50 + PUSH AX
0004 B8 ---- R + MOV AX,DATA
0007 8E D8 + MOV DS,AX
0009 8E C0 + MOV ES,AX
PROMPT MESSGE
000B B4 09 + MOV AH,09 ;Вывод на экран
000D 8D 16 0000 R + LEA DX,MESSGE
0011 CD 21 + INT 21H
0013 CB RET
0014 BEGIN ENDP
0014 CSEG ENDS
END BEGIN
Ассемблер для IBM PC. Программы. 147
TITLE MACRO6 (COM) Проверка дирктив IF и IFNDEF
; ------------------------------------------------
DIVIDE MACRO DIVIDEND,DIVISOR,QUOTIENT
LOCAL COMP
LOCAL OUT
CNTR = 0
; AX-делимое, BX-делитель, CX-частное
IFNDEF DIVIDEND
; Делитель не определен
CNTR = CNTR +1
ENDIF
IFNDEF DIVISOR
; Делимое не определено
CNTR = CNTR +1
ENDIF
IFNDEF QUOTIENT
; Частное не определено
CNTR = CNTR +1
ENDIF
IF CNTR
; Макрорасширение отменено
EXITM
ENDIF
MOV AX,DIVIDEND ;Загрузка делимого
MOV BX,DIVISOR ;Загрузка делителя
SUB CX,CX ;Регистр для частного
COMP:
CMP AX,BX ;Делимое < делителя?
JB OUT ; да - выйти
SUB AX,BX ;Делимое - делитель
INC CX ;Частное + 1
JMP COMP
OUT:
MOV QUOTIENT,CX ;Запись результата
ENDM
; ------------------------------------------------
0000 CSEG SEGMENT PARA 'Code'
ASSUME CS:CSEG,DS:CSEG,SS:CSEG,ES:CSEG
0100 ORG 100H
0100 EB 06 BEGIN: JMP SHORT MAIN
; ------------------------------------------------
0102 0096 DIVDND DW 150
0104 001B DIVSOR DW 27
0106 ???? QUOTNT DW ?
; ------------------------------------------------
0108 MAIN PROC NEAR
.LALL
DIVIDE DIVDND,DIVSOR,QUOTNT
= 0000 + CNTR = 0
+ ; AX-делимое, BX-делитель, CX-частное
+ ENDIF
+ ENDIF
Ассемблер для IBM PC. Программы. 148
+ ENDIF
+ ENDIF
0108 A1 0102 R + MOV AX,DIVDND ;Загрузка делимого
0108 8B 1E 0104 R + MOV BX,DIVSOR ;Загрузка делителя
010F 2B C9 + SUB CX,CX ;Регистр для частного
0111 + ??0000:
0111 3B C3 + CMP AX,BX ;Делимое < делителя?
0113 72 05 + JB ??0001 ; да - выйти
0115 2B C3 + SUB AX,BX ;Делимое - делитель
0117 41 + INC CX
0118 EB F7 + JMP ??0000
011A + ??0001:
011A 89 0E 0106 R + MOV QUOTNT,CX ;Запись результата
DIVIDE DIDND,DIVSOR,QUOT
= 0000 + CNTR = 0
+ ; AX-делимое, BX-делитель, CX-частное
+ IFNDEF DIDND
+ ; Делитель не определен
= 0001 + CNTR = CNTR +1
+ ENDIF
+ ENDIF
+ IFNDEF QUOT
+ ; Частное не определено
= 0002 + CNTR = CNTR +1
+ ENDIF
+ IF CNTR
+ ; Макрорасширение отменено
+ EXITM
011E C3 RET
011F MAIN ENDP
011F CSEG ENDS
END BEGIN
Ассемблер для IBM PC. Программы. 149
TITLE MACRO7 (COM) Проверка директивы IFIDN
; --------------------------------------------
MOVIF MACRO TAG
IFIDN <&TAG>,<B>
REP MOVSB
EXITM
ENDIF
IFIDN <&TAG>,<W>
REP MOVSW
ELSE
; Не указан параметр B или W,
; по умолчанию принято B
REP MOVSB
ENDIF
ENDM
; --------------------------------------------
0000 CSIG SEGMENT PARA 'Code'
ASSUME CS:CSEG,DS:CSEG,SS:CSEG,ES:CSEG
0100 ORG 100H
0100 EB 00 BEGIN: JMP SHORT MAIN
; ...
0102 MAIN PROC NEAR
.LALL
MOVIF B
+ IFIDN <B>,<B>
0102 F3/A4 + REP MOVSB
+ EXITM
MOVIF W
+ ENDIF
+ IFIDN <W>, <W>
0104 F3/A5 + REP MOVSW
+ ENDIF
MOVIF
+ ENDIF
+ ELSE
+ ; Не указан параметр B или W,
+ ; по умолчанию принято B
0106 F3/A4 + REP MOVSB
+ ENDIF
0108 C3 RET
0109 MAIN ENDP
0109 CSEG ENDS
END BEGIN
Ассемблер для IBM PC. Программы. 150
+-----------+ +-----------+
| Основная | | Основная |
| программа | | программа |
+-----+-----+ +-----+-----+
| |
| |
+------------+------------+ +------+------+
| | | | |
| | | | |
+--------+ +--------+ +--------+ +--------+ +--------+
| П/П 1 | | П/П 2 | | П/П 3 | | П/П 1 | | П/П 2 |
+---------+ +---------+ +---------+ +----+----+ +---------+
|
|
+--------+
| П/П 3 |
+---------+
Ассемблер для IBM PC. Программы. 151
+---------------------------------------+
| EXTRN SUBPROG:FAR |
| MAINPROG: . |
| . |
| CALL SUBPROG |
| . |
| . |
+---------------------------------------+
| PUBLIC SUBPROG |
| SUBPROG: . |
| . |
| . |
| RET |
+---------------------------------------+
Ассемблер для IBM PC. Программы. 152
page 60,132
TITLE CALLMULL1 (EXE) Вызов подпрограммы умножения
EXTRN SUBMUL:FAR
;-----------------------------------------------
0000 STACKSG SEGMENT PARA STACK 'Stack'
0000 40 [ ???? ] DW 64 DUP(?)
0080 STACKSG ENDS
;-----------------------------------------------
0000 DATASG SEGMENT PARA 'Data'
0000 0140 QTY DW 0140H
0002 2500 PRICE DW 2500H
0004 DATASG ENDS
;-----------------------------------------------
0000 CODESG SEGMENT PARA 'Code'
0000 BEGIN PROC FAR
ASSUME CS:CODESG,DS:DATASG,SS:STACKSG
0000 1E PUSH DS
0001 2B C0 SUB AX,AX
0003 50 PUSH AX
0004 B8 ---- R MOV AX,DATASG
0007 8E D8 MOV DS,AX
0009 A1 0002 R MOV AX,PRICE ;Загрузить стоимость
000C 8B 1E 0000 R MOV BX,QTY ; и количество
0010 9A 0000 ---- E CALL SUBMUL ;Вызвать подпрограмму
0015 CB RET
0016 BEGIN ENDP
0016 CODESG ENDS
END BEGIN
Segments and Groups:
N a m e Size Align Combine Class
CODESG . . . . . . . . . . . . 0016 PARA NONE 'CODE'
DATASG . . . . . . . . . . . . 0004 PARA NONE 'DATA'
STACKSG. . . . . . . . . . . . 0080 PARA STACK 'STACK'
Symbols:
N a m e Type Value Attr
BEGIN. . . . . . . . . . . . . F PROC 0000 CODESG Length=0016
PRICE. . . . . . . . . . . . . L WORD 0002 DATASG
QTY. . . . . . . . . . . . . . L WORD 0000 DATASG
SUBMUL . . . . . . . . . . . . L FAR 0000 External
page 60,132
TITLE SUBMUL Подпрограмма для умножения
;-----------------------------------------------
0000 CODESG SEGMENT PARA 'Code'
0000 SUBMUL PROC FAR
ASSUME CS:CODESG
PUBLIC SUBMUL
0000 F7 E3 MUL BX ;AX-стоимость, BX-количество
0002 CB RET ;Произведение в DX:AX
Ассемблер для IBM PC. Программы. 153
0003 SUBMUL ENDP
0003 CODESG ENDS
END SUBMUL
Segments and groups:
N a m e Size Align Combine Class
CODESG . . . . . . . . . . . . 0003 PARA NONE 'CODE'
Symbols:
N a m e Type Value Attr
SUBMUL . . . . . . . . . . . . F PROC 0000 CODESG Clobal Length=0003
LINK
IBM Personal Computer Linker
Version 2.30 (C) Copyright IBM Corp 1981, 1985
Object Modules: B:CALLMUL1+B:SUBMUL1
Run File: [B:CALLMUL1.EXE]: <return>
List File:[NUL.MAP]: CON
Libraries [.LIB]: <return>
Start Stop Length Name Class
00000H 00015H 0016H CODESG CODE <--Примечание: 2 кодовых
00020H 00022H 0003H CODESG CODE <-- сегмента
00030H 00033H 0004H DATASG DATA
00040H 000BFH 0080H STACKSG STACK
Program entry point at 0000:0000
Ассемблер для IBM PC. Программы. 154
page 60,132
TITLE CALLMUL2 (EXE) Вызов подпрограммы умножения
EXTERN SUBMUL:FAR
;----------------------------------------------
0000 STACKSG SEGMENT PARA STACK 'Stack'
0000 40 [????] DW 64 DUP(?)
0080 STACKSG ENDS
;----------------------------------------------
0000 DATASG SEGMENT PARA 'Data'
0000 0140 QTY DW 0140H
0002 2500 PRICE DW 2500H
0004 DATASG ENDS
;----------------------------------------------
0000 CODESG SEGMENT PARA PUBLIC 'Code'
0000 BEGIN PROC FAR
ASSUME CS:CODESG,DS:DATASG,SS:STACKSG
0000 1E PUSH DS
0001 2B C0 SUB AX,AX
0003 50 PUSH AX
0004 B8 ---- R MOV AX,DATASG
0007 8E D8 MOV DS,AX
0009 A1 0002 R MOV AX,PRICE ;Загрузить стоимость
000C 8B 1E 0000 R MOV BX,QTY ; и количество
0010 9A 0000 ---- E CALL SUBMUL ;Вызвать подпрограмму
0015 CB RET
0016 BEGIN ENDP
0016 CODESG ENDS
END BEGIN
Segments and Group:
N a m e Size Align Combine Class
CODESG . . . . . . . . . . . . .0016 PARA PUBLIC 'CODE'
DATASG . . . . . . . . . . . . .0004 PARA NONE 'DATA'
STACKSG. . . . . . . . . . . . .0080 PARA STACK 'STACK'
Symbols:
N a m e Type Value Attr
BEGIN. . . . . . . . . . . . . F PROC 0000 CODESG Lenght=0016
PRICE. . . . . . . . . . . . . L WORD 0002 DATASG
QTY. . . . . . . . . . . . . . L WORD 0000 DATASG
SUBMUL . . . . . . . . . . . . L FAR 0000 External
page 60,132
TITLE SUBMUL2 Вызываемая подпрограмма умножения
;----------------------------------------------
0000 CODESG SEGMENT PARA PUBLIC 'CODE'
0000 SUBMUL PROC FAR
ASSUME CS:CODESG
PUBLIC SUBMUL
0000 F7 E3 MUL BX ;AX-стоимость, BX-количество
Ассемблер для IBM PC. Программы. 155
0002 CB RET ;Произведение в DX:AX
0003 SUBMUL ENDP
0003 CODESG ENDS
END SUBMUL
Segments and Groups:
N a m e Size Align Combine Class
CODESG. . . . . . . . . . . . . 0003 PARA PUBLIC 'CODE'
Symbols:
N a m e Type Value Attr
SUBMUL. . . . . . . . . . . . .F PROC 0000 CODESG Global Length=0003
LINK
IBM Personal Computer Linker
Version 2.30 (C) Copyright IBM Corp 1981, 1985
Object Modules: B:CALLMUL2+B:SUBMUL2
Run File: [B:CALLMUL2.EXE]: <return>
List File: [NUL.MAP]: CON
Libraries [.LIB]: <return>
Start Stop Length Name Class
00000H 00022H 0023H CODESG CODE <-- Примечание: 1 сегмент кода
00030H 00033H 0004H DATASG DATA
00040H 000BFH 0080H STACKSG STACK
Program entry point at 0000:0000
Ассемблер для IBM PC. Программы. 156
page 60,132
TITLE CALLMUL3 (EXE) Вызов подпрограммы
; для умножения
EXTRN SUBMUL:FAR
PUBLIC QTY,PRICE
;-------------------------------------------------
0000 STACKSG SEGMENT PARA STACK 'Stack'
0000 40 [????] DW 64 DUP(?)
0080 STACKSD ENDS
;-------------------------------------------------
0000 DATASG SEGMENT PARA PUBLIC 'Data'
0000 0140 QTY DW 0140H
0002 2500 PRICE DW 2500H
0004 DATASG ENDS
;-------------------------------------------------
0000 CODESG SEGMENT PARA PUBLIC 'Code'
0000 BEGIN PROC FAR
ASSUME CS:CODESG,DS:DATASG,SS:STACKSG
0000 1E PUSH DS
0001 2B C0 SUB AX,AX
0003 50 PUSH AX
0004 B8 ---- R MOV AX,DATASG
0007 8E D8 MOV DS,AX
0009 9A 0000 ---- E CALL SUBMUL ;Вызвать подпрограмму
000E CB RET
000F BEGIN ENDP
000F CODESG ENDS
END BEGIN
Segments and Groups:
N a m e Size Align Combine Class
CODESG . . . . . . . . . . . . 000F PARA PUBLIC 'CODE'
DATASG . . . . . . . . . . . . 0004 PARA PUBLIC 'DATA'
STACKSG. . . . . . . . . . . . 0080 PARA STACK 'STACK'
Symbols:
N a m e Type Value Attr
BEGIN. . . . . . . . . . . . . F PROC 0000 CODESG Length=000F
PRICE. . . . . . . . . . . . . L WORD 0002 DATASG Global
QTY. . . . . . . . . . . . . . L WORD 0000 DATASG Global
SUBMUL . . . . . . . . . . . . L FAR 0000 External
page 60,132
TITLE SUBMUL Подпрограмма для умножения
EXTRN QTY:WORD,PRICE:WORD
;-------------------------------------------------
0000 CODESG SEGMENT PARA PUBLIC 'CODE'
0000 SUBMUL PROC FAR
ASSUME CS:CODESG
PUBLIC SUBMUL
Ассемблер для IBM PC. Программы. 157
0000 A1 0000 E MOV AX,PRICE
0003 8B 1E 0000 E MOV BX,QTY
0007 F7 E3 MUL BX ;Произведение в DX:AX
0009 CB RET
000A SUBMUL ENDP
000A CODESG ENDS
END SUBMUL
Segments and Groups:
N a m e Size Align Combine Class
CODESG . . . . . . . . . . . . 000A PARA PUBLIC 'CODE'
Symbols:
N a m e Type Value Attr
PRICE. . . . . . . . . . . . . V WORD 0000 External
QTY. . . . . . . . . . . . . . V WORD 0000 External
SUBMUL . . . . . . . . . . . . F PROC 0000 CODESG Global Length=000A
LINK
IBM Personal Computer Linker
Version 2.30 (C) Copyright IBM Corp 1981, 1985
Object Modules: B:CALLMUL3+B:SUBMUL3
Run File: [B:CALLMUL3.EXE]: <return>
List File: [NUL.MAP]: CON
Libraries [.LIB]: <return>
Start Stop Length Name Class
00000H 00019H 001AH CODESG CODE
00030H 00033H 0004H DATASG DATA
00040H 000BFH 0080H STACKSG STACK
PROGRAM entry point at 0000:0000
Ассемблер для IBM PC. Программы. 158
page 60,132
TITLE CALLMULL4 (EXE) Передача параметров
; в подпрограмму
EXTRN SUBMUL:FAR
;-------------------------------------------------
0000 STACKSG SEGMENT PARA STACK 'Stack'
0000 40 [ ???? ] DW 64 DUP(?)
0080 STACKSG ENDS
;-------------------------------------------------
0000 DATASG SEGMENT PARA 'Data'
0000 0140 QTY DW 0140H
0002 2500 PRICE DW 2500H
0004 DATASG ENDS
; Подготовка для печати:
; ----------------------
Ассемблер для IBM PC. Программы. 135
E10PRNT PROC NEAR
CMP LINECTR,60 ;Конец страницы?
JB E20 ; нет - обойти
CALL M10PAGE ; да - печатать заголовок
E20: MOV CH,00
MOV CL,NAMELEN ;Число символов в имени
LEA DX,NAMEFLD ;Адрес имени
CALL P10OUT ;Печатать имя
MOV CX,01 ;Один
LEA DX,LFEED ; перевод строки
CALL P10OUT
INC LINECTR ;Увеличить счетчик строк
E10PRNT ENDP
; Подпрограмма печати заголовка:
; -----------------------------
M10PAGE PROC NEAR
CMP WORD PTR PAGECTR,3130H ;Первая страница?
JE M30 ; да - обойти
MOV CX,01 ;
LEA DX,FFEED ; нет --
CALL P10OUT ; перевести страницу,
MOV LINECTR,03 ; установить счетчик строк
M30:
MOV CX,36 ;Длина заголовка
LEA DX,HEADG ;Адрес заголовка
M40:
CALL P10OUT
INC PAGECTR+1 ;Увеличить счетчик страниц
CMP PAGECTR+1,3AH ;Номер страницы = шест.xx3A?
JNE M50 ; нет - обойти,
MOV PAGECTR+1,30H ; да - перевести в ASCII
INC PAGECTR
M50: RET
M10PAGE ENDP
; Подпрограмма печати:
; -------------------
P10OUT PROC NEAR ;CX и DX установлены
MOV AH,40H ;Функция печати
MOV BX,04 ;Номер устройства
INT 21H ;Вызов DOS
RET
P10OUT ENDP
; Очистка экрана:
; --------------
Q10CLR PROC NEAR
MOV AX,0600H ;Функция прокрутки
MOV BH,60H ;Цвет (07 для ч/б)
MOV CX,0000 ;От 00,00
MOV DX,184FH ; до 24,79
INT 10H ;Вызов BIOS
RET
Q10CLR ENDP
; Установка курсора (строка/столбец):
Ассемблер для IBM PC. Программы. 136
; ----------------------------------
Q20CURS PROC NEAR ;DX уже установлен
MOV AH,02 ;Функция установки курсора
MOV BH,00 ;Страница Э 0
INT 10H ;Вызов BIOS
RET
Q20CURS ENDP
CODESG ENDS
END BEGIN
Ассемблер для IBM PC. Программы. 137
TITLE PRINASK (COM) Чтение и печать дисковых записей
CODESG SEGMENT PARA 'Code'
ASSUME CS:CODESG,DS:CODESG,SS:CODESG,ES:CODESG
ORG 100H
BEGIN JMP MAIN
; ---------------------------------------------------------
PATHPAR LABEL BYTE ;Список параметров для
MAXLEN DB 32 ; ввода
NAMELEN DB ? ; имени файла
FILENAM DB 32 DUP(' ')
SECTOR DB 512 DUP(' ') ;Область ввода для файла
DISAREA DB 120 DUP(' ') ;Область вывода
COUNT DW 00
ENDCDE DW 00
FFEED DB 0CH
HANDLE DW 0
OPENMSG DB '*** Open error ***'
PROMPT DB 'Name of file? '
; ----------------------------------------------------------
MAIN PROC NEAR ;Основная программа
CALL Q10SCR ;Очистить экран
CALL Q20CURS ;Установить курсор
A10LOOP:
MOV ENDCDE,00 ;Начальная установка
CALL C10PRMP ;Получить имя файла
CMP NAMELEN,00 ;Есть запрос?
JE A90 ; нет - выйти
CALL E10OPEN ;Открыть файл,
; установить DTA
CMP ENDCDE,00 ;Ошибка при открытии?
JNE A80 ; да - повторить запрос
CALL R10READ ;Прочитать первый сектор
CMP ENDCDE,00 ;Конец файла, нет данных?
JE A80 ; да - повторить запрос
CALL G10XPER ;Распечатать сектор
A80:
JMP A10LOOP
A90: RET
MAIN ENDP
; Подпрограмма запроса имени файла:
; --------------------------------
C10PRMP PROC NEAR
MOV AH,40H ;Функция вывода на экран
MOV BX,01
MOV CX,13
LEA DX,PROMPT
INT 21H
MOV AH,0AH ;Функция ввода с клавиатуры
LEA DX,PATHPAR
INT 21H
MOV BL,NAMELEN ;Записать
MOV BH,00 ; 00 в конец
Ассемблер для IBM PC. Программы. 138
MOV FILENAM[BX],0 ; имени файла
C90 RET
C10PRMP ENDP
; Открытие дискового файла:
; ------------------------
E10OPEN PROC NEAR
MOV AH,3DH ;Функция открытия
MOV AL,00 ;Только чтение
LEA DX,FILENAM
INT 21H
JNC E20 ;Проверить флаг CF
CALL X10ERR ; ошибка, если установлен
RET
E20:
MOV HANDLE,AX ;Сохранить номер файла
MOV AX,2020H
MOV CX,256 ;Очистить пробелами
REP STOSW ; область сектора
RET
E100PEN ENDP
; Подготовка и печать данных:
; --------------------------
G10XFER PROC NEAR
CLD ;Направление слева-направо
LEA SI,SECTOR ;Начальная установка
G20:
LEA DI,DISAREA
MOV COUNT,00
G30:
LEA DX,SECTOR+512
CMP SI,DX ;Конец сектора?
JNE G40
CALL R10READ ; да - читать следующий
CMP ENDCDE,00 ;Конец файла?
JE G80 ; да - выйти
LEA SI,SECTOR
G40:
MOV BX,COUNT
CMP BX,80 ;Конец области вывода?
JB G50 ; нет - обойти
MOV [DI+BX],0D0AH ; да - записать CR/LF
CALL P10PRNT
LEA DI,DISAREA ;Начало области вывода
G50:
LODSB ;Записать [SI] в AL,
; увеличить SI
MOV BX,COUNT
MOV [DI+BX],AL ;Записать символ
INC BX
CMP AL,1AH ;Конец файла?
JE G80 ; да - выйти
CMP AL,0AH ;Конец строки?
JNE G60 ; нет - обойти,
Ассемблер для IBM PC. Программы. 139
CALL P10PRNT ; да - печатать
JMP G20
G60:
CMP AL,09H ;Символ табуляции?
JNE G70
DEC BX ; да - установить BX:
MOV BYTE PTR [DI+BX],20H ;Заменит TAB на пробел
AND BX,0FFF8H ;Обнулить правые 8 бит
ADD BX,08 ; и прибавить 8
G70:
MOV COUNT,BX
JMP G30
G80: MOV BX,COUNT ;Конец файла
MOV BYTE PTR [DI+BX],0CH ;Прогон страницы
CALL P10PRNT ;Печатать последнюю строку
G90: RET
G10XFER ENDP
; Подпрограммы печати:
; -------------------
P10PRNT PROC NEAR
MOV AH,40H ;Функция печати
MOV BX,04
MOV CX,COUNT ;Длина
INC CX
LEA DX,DISAREA
INT 21H
MOV AX,2020H ;Очистить область вывода
MOV CX,60
LEA DI,DISAREA
REP STOSW
RET
P10PRNT ENDP
; Подпрограмма чтения сектора:
; ---------------------------
R10READ PROC NEAR
MOV AH,3FH ;Функция чтения
MOV BX,HANDLE ;Номер файла
MOV CX,512 ;Длина
MOV DX,SECTOR ;Буфер
INT 21H
MOV ENDCDE,AX
RET
R10READ ENDP
; Прокрутка экрана:
; ----------------
Q10SCR PROC NEAR
MOV AX,0600H
MOV BH,1EH ;Установить цвет
MOV CX,0000 ;Прокрутка (сскроллинг)
MOV DX,184FH
INT 10H
RET
Q10SCR ENDP
Ассемблер для IBM PC. Программы. 140
; Подпрограмма установки курсора:
; ------------------------------
Q20CURS PROC NEAR
MOV AH,02 ;Функция установки
MOV BH,00 ; курсора
MOV DX,00
INT 10H
RET
Q20CURS ENDP
; Вывод сообщения об ошибке:
; -------------------------
X10ERR PROC NEAR
MOV AH,40H ;Функция вывода на экран
MOV BX,01 ;Номер
MOV CX,18 ;Длина
LEA DX,OPENMSG ;Адрес сообщения
INT 1H
MOV NDCDE,01 ;Признак ошибки
RET
X10ERR ENDP
CODESG ENDS
END BEGIN
Ассемблер для IBM PC. Программы. 141
TITLE MACRO1 (EXE) Макрос для инициализации
; --------------------------------------------
INIT1 MACRO
ASSUME CS:CSEG,DS:DSEG,SS:STACK,ES:DSEG
PUSH DS
SUB AX,AX
PUSH AX
MOV AX,DSEG
MOV DS,AX
MOV ES,AX
ENDM ;Конец макрокоманды
; --------------------------------------------
0000 STACK SEGMENT PARA STACK 'Stack'
0000 20 [ ???? ] DW 32 DUP(?)
0040 STACK ENDS
; --------------------------------------------
0000 DSEG SEGMENT PARA 'Data'
0000 54 65 73 74 20 6F MESSGE DB 'Test of macro-instruction', 13
66 20 6D 61 63 72
6F 2D 69 6E 73 74
72 65 73 74 69 6F
6E 0D
001A DSEG ENDS
; --------------------------------------------
0000 CSEG SEGMENT PARA 'Code'
0000 BEGIN PROC FAR
INIT1 ;Макрокоманда
0000 1E + PUSH DS
0001 2B C0 + SUB AX,AX
0003 50 + PUSH AX
0004 B8 ---- R + MOV AX,DSEG
0007 8E D8 + MOV DS,AX
0009 8E C0 + MOV ES,AX
000B B4 40 MOV AH,40H ;Вывод на экран
000D BB 0001 MOV BX,01 ;Номер
0010 B9 001A MOV CX,26 ;Длина
0013 8D 16 0000 R LEA DX,MESSGE ;Сообщение
0017 CD 21 INT 21H
0019 CB RET
001A BEGIN ENDP
001A CSEG ENDS
END BEGIN
Macros:
N a m e Length
INIT1. . . . . . . . . . . . . . . . 0004
Segments and Groups:
N a m e Size Align Combine Class
CSEG . . . . . . . . . . . . . . . . 001A PARA NONE 'CODE'
DSEG . . . . . . . . . . . . . . . . 001A PARA NONE 'DATA'
STACK. . . . . . . . . . . . . . . . 0040 PARA STACK 'STACK'
Ассемблер для IBM PC. Программы. 142
Symbols:
N a m e Type Value Attr
BEGIN. . . . . . . . . . . . . . . . F PROC 0000 CSEG Length=001A
MESSAGE. . . . . . . . . . . . . . . L BYTE 0000 DSEG
Ассемблер для IBM PC. Программы. 143
TITLE MACRO2 (EXE) Использование параметров
; ------------------------------------------------
INIT2 MACRO CSNAME,DSNAME,SSNAME
ASSUME CS:CSNAME,DS:DSNAME,SS:SSNAME,ES:DSNAME
PUSH DS
SUB AX,AX
PUSH AX
MOV AX,DSNAME
MOV DS,AX
MOV ES,AX
ENDM ;Конец макрокоманды
; ------------------------------------------------
0000 STACK SEGMENT PARA STACK 'Stack'
0000 20 [ ???? ] DW 32 DUP(?)
0040 STACK ENDS
; ------------------------------------------------
0000 DSEG SEGMENT PARA 'Data'
0000 54 65 73 74 20 6F MESSAGE DB 'Test of macro', '$'
66 20 6D 61 63 72
6F 24
000E DSEG ENDS
; ------------------------------------------------
0000 CSEG SEGMENT PARA 'Code'
0000 BEGIN PROC FAR
INIT2 CSEG,DSEG,STACK
0000 1E + PUSH DS
0001 2B C0 + SUB AX,AX
0003 50 + PUSH AX
0004 B8 ---- R + MOV AX,DSEG
0007 8E D8 + MOV DS,AX
0009 8E C0 + MOV ES,AX
000B B4 09 MOV AH,09 ;Вывод на экран
000D 8D 16 0000 R LEA DX,MESSGE ;Сообщение
0011 CD 21 INT 21H
0013 CB RET
0014 BEGIN ENDP
0014 CSEG ENDS
END BEGIN
Ассемблер для IBM PC. Программы. 144
TITLE MACRO3 (EXE) Директивы .LALL и .SALL
; ------------------------------------------------
INIT2 MACRO CSNAME,DSNAME,SSNAME
ASSUME CS:CSNAME,DS:DSNAME,SS:SSNAME,ES:DSNAME
PUSH DS
SUB AX,AX
PUSH AX
MOV AX,DSNAME
MOV DS,AX
MOV ES,AX
ENDM
; ------------------------------------------------
PROMPT MACRO MESSAGE
; Макрокоманда выводит на экран любые сообщения
;; Генерирует команды вызова DOS
MOV AH,09 ;Вывод на экран
LEA DX,MESSAGE
INT 21H
ENDM
; ------------------------------------------------
0000 STACK SEGMENT PARA STACK 'Stack'
0000 20 [ ???? ] DW 32 DUP (?)
0040 STACK ENDS
; ------------------------------------------------
0000 DATA SEGMENT PARA 'Data'
0000 43 75 73 74 6F 6D MESSG1 DB 'Customer name?', '$'
65 72 20 6E 61 6D
65 3F 24
000F 43 75 73 74 6F 6D MESSG2 DB 'Customer address?', '$'
65 72 20 61 64 64
72 65 73 73 3F 24
0021 DATA ENDS
; ------------------------------------------------
0000 CSEG SEGMENT PARA 'Code'
0000 BEGIN PROC FAR
.SALL
INIT2 CSEG,DATA,STACK
PROMPT MESSG1
.LALL
PROMPT MESSG2
+ ; Макрокоманда выводит на экран любые сообщения
0013 B4 09 + MOV AH,09 ;Вывод на экран
0015 8D 16 000F R + LEA DX,MESSG2
0019 CD 21 + INT 21H
001B CB RET
001C BEGIN ENDP
001C CSEG ENDS
END BEGIN
Ассемблер для IBM PC. Программы. 145
TITLE MACRO4 (COM) Использование директивы LOCAL
; -------------------------------------------------
DIVIDE MACRO DIVIDEND,DIVISOR,QUOTIENT
LOCAL COMP
LOCAL OUT
; AX=делимое, BX=делитель, CX=частное
MOV AX,DIVIDEND ;Загрузить делимое
MOV BX,DIVISOR ;Загрузить делитель
SUB CX,CX ;Регистр для частного
COMP:
CMP AX,BX ;Делимое < делителя?
JB OUT ; да - выйти
SUB AX,BX ;Делимое - делитель
INC CX ;Частное + 1
JMP COMP
OUT:
MOV QUOTIENT,CX ;Записать результат
ENDM
; ------------------------------------------------
0000 CSEG SEGMENT PARA 'Code'
ASSUME CS:CSEG,DS:CSEG,SS:CSEG,ES:CSEG
0100 ORG 100H
0100 EB 06 BEGIN: JMP SHORT MAIN
; ------------------------------------------------
0102 0096 DIVDND DW 150 ;Делимое
0104 001B DIVSOR DW 27 ;Делитель
0106 ???? QUOTNT DW ? ;Частное
; ------------------------------------------------
0108 MAIN PROC NEAR
.LALL
DIVIDE DIVDND,DIVSOR,QUOTNT
+ ; AX=делимое, BX=делитель, CX=частное
0108 A1 0102 R + MOV AX,DIVDND ;Загрузить делимое
010B 8B 1E 0104 R + MOV BX,DIVSOR ;Загрузить делитель
010F 2B C9 + SUB CX,CX ;Регистр для частного
0111 + ??0000:
0111 3B C3 + CMP AX,BX ;Делимое < делителя?
0113 72 05 + JB ??0001 ; да - выйти
0115 2B C3 + SUB AX,BX ;Делимое - делитель
0117 41 + INC CX ;Частное + 1
0118 EB F7 + JMP ??0000
011A + ??0001:
011A 89 0E 0106 R + MOV QUOTNT,CX ;Записать результат
011E C3 RET
011F MAIN ENDP
011F CSEG ENDS
END BEGIN
Ассемблер для IBM PC. Программы. 146
TITLE MACRO5 (EXE) Проверка директивы INCLUDE
EDIF
; ------------------------------------------------
0000 STACK SEGMENT PARA STACK 'Stack'
0000 20 [????] DW 32 DUP(?)
0040 STACK ENDS
; ------------------------------------------------
0000 DATA SEGMENT PARA 'Data'
0000 54 65 73 74 20 6F MESSGE DB 'Test of macro','$'
66 20 6D 61 63 72
6F 24
000E DATA ENDS
; ------------------------------------------------
0000 CSEG SEGMENT PARA 'Code'
0000 BEGIN PROC FAR
INIT CSEG,DATA,STACK
0000 1E + PUSH DS
0001 3B C0 + SUB AX,AX
0003 50 + PUSH AX
0004 B8 ---- R + MOV AX,DATA
0007 8E D8 + MOV DS,AX
0009 8E C0 + MOV ES,AX
PROMPT MESSGE
000B B4 09 + MOV AH,09 ;Вывод на экран
000D 8D 16 0000 R + LEA DX,MESSGE
0011 CD 21 + INT 21H
0013 CB RET
0014 BEGIN ENDP
0014 CSEG ENDS
END BEGIN
Ассемблер для IBM PC. Программы. 147
TITLE MACRO6 (COM) Проверка дирктив IF и IFNDEF
; ------------------------------------------------
DIVIDE MACRO DIVIDEND,DIVISOR,QUOTIENT
LOCAL COMP
LOCAL OUT
CNTR = 0
; AX-делимое, BX-делитель, CX-частное
IFNDEF DIVIDEND
; Делитель не определен
CNTR = CNTR +1
ENDIF
IFNDEF DIVISOR
; Делимое не определено
CNTR = CNTR +1
ENDIF
IFNDEF QUOTIENT
; Частное не определено
CNTR = CNTR +1
ENDIF
IF CNTR
; Макрорасширение отменено
EXITM
ENDIF
MOV AX,DIVIDEND ;Загрузка делимого
MOV BX,DIVISOR ;Загрузка делителя
SUB CX,CX ;Регистр для частного
COMP:
CMP AX,BX ;Делимое < делителя?
JB OUT ; да - выйти
SUB AX,BX ;Делимое - делитель
INC CX ;Частное + 1
JMP COMP
OUT:
MOV QUOTIENT,CX ;Запись результата
ENDM
; ------------------------------------------------
0000 CSEG SEGMENT PARA 'Code'
ASSUME CS:CSEG,DS:CSEG,SS:CSEG,ES:CSEG
0100 ORG 100H
0100 EB 06 BEGIN: JMP SHORT MAIN
; ------------------------------------------------
0102 0096 DIVDND DW 150
0104 001B DIVSOR DW 27
0106 ???? QUOTNT DW ?
; ------------------------------------------------
0108 MAIN PROC NEAR
.LALL
DIVIDE DIVDND,DIVSOR,QUOTNT
= 0000 + CNTR = 0
+ ; AX-делимое, BX-делитель, CX-частное
+ ENDIF
+ ENDIF
Ассемблер для IBM PC. Программы. 148
+ ENDIF
+ ENDIF
0108 A1 0102 R + MOV AX,DIVDND ;Загрузка делимого
0108 8B 1E 0104 R + MOV BX,DIVSOR ;Загрузка делителя
010F 2B C9 + SUB CX,CX ;Регистр для частного
0111 + ??0000:
0111 3B C3 + CMP AX,BX ;Делимое < делителя?
0113 72 05 + JB ??0001 ; да - выйти
0115 2B C3 + SUB AX,BX ;Делимое - делитель
0117 41 + INC CX
0118 EB F7 + JMP ??0000
011A + ??0001:
011A 89 0E 0106 R + MOV QUOTNT,CX ;Запись результата
DIVIDE DIDND,DIVSOR,QUOT
= 0000 + CNTR = 0
+ ; AX-делимое, BX-делитель, CX-частное
+ IFNDEF DIDND
+ ; Делитель не определен
= 0001 + CNTR = CNTR +1
+ ENDIF
+ ENDIF
+ IFNDEF QUOT
+ ; Частное не определено
= 0002 + CNTR = CNTR +1
+ ENDIF
+ IF CNTR
+ ; Макрорасширение отменено
+ EXITM
011E C3 RET
011F MAIN ENDP
011F CSEG ENDS
END BEGIN
Ассемблер для IBM PC. Программы. 149
TITLE MACRO7 (COM) Проверка директивы IFIDN
; --------------------------------------------
MOVIF MACRO TAG
IFIDN <&TAG>,<B>
REP MOVSB
EXITM
ENDIF
IFIDN <&TAG>,<W>
REP MOVSW
ELSE
; Не указан параметр B или W,
; по умолчанию принято B
REP MOVSB
ENDIF
ENDM
; --------------------------------------------
0000 CSIG SEGMENT PARA 'Code'
ASSUME CS:CSEG,DS:CSEG,SS:CSEG,ES:CSEG
0100 ORG 100H
0100 EB 00 BEGIN: JMP SHORT MAIN
; ...
0102 MAIN PROC NEAR
.LALL
MOVIF B
+ IFIDN <B>,<B>
0102 F3/A4 + REP MOVSB
+ EXITM
MOVIF W
+ ENDIF
+ IFIDN <W>, <W>
0104 F3/A5 + REP MOVSW
+ ENDIF
MOVIF
+ ENDIF
+ ELSE
+ ; Не указан параметр B или W,
+ ; по умолчанию принято B
0106 F3/A4 + REP MOVSB
+ ENDIF
0108 C3 RET
0109 MAIN ENDP
0109 CSEG ENDS
END BEGIN
Ассемблер для IBM PC. Программы. 150
+-----------+ +-----------+
| Основная | | Основная |
| программа | | программа |
+-----+-----+ +-----+-----+
| |
| |
+------------+------------+ +------+------+
| | | | |
| | | | |
+--------+ +--------+ +--------+ +--------+ +--------+
| П/П 1 | | П/П 2 | | П/П 3 | | П/П 1 | | П/П 2 |
+---------+ +---------+ +---------+ +----+----+ +---------+
|
|
+--------+
| П/П 3 |
+---------+
Ассемблер для IBM PC. Программы. 151
+---------------------------------------+
| EXTRN SUBPROG:FAR |
| MAINPROG: . |
| . |
| CALL SUBPROG |
| . |
| . |
+---------------------------------------+
| PUBLIC SUBPROG |
| SUBPROG: . |
| . |
| . |
| RET |
+---------------------------------------+
Ассемблер для IBM PC. Программы. 152
page 60,132
TITLE CALLMULL1 (EXE) Вызов подпрограммы умножения
EXTRN SUBMUL:FAR
;-----------------------------------------------
0000 STACKSG SEGMENT PARA STACK 'Stack'
0000 40 [ ???? ] DW 64 DUP(?)
0080 STACKSG ENDS
;-----------------------------------------------
0000 DATASG SEGMENT PARA 'Data'
0000 0140 QTY DW 0140H
0002 2500 PRICE DW 2500H
0004 DATASG ENDS
;-----------------------------------------------
0000 CODESG SEGMENT PARA 'Code'
0000 BEGIN PROC FAR
ASSUME CS:CODESG,DS:DATASG,SS:STACKSG
0000 1E PUSH DS
0001 2B C0 SUB AX,AX
0003 50 PUSH AX
0004 B8 ---- R MOV AX,DATASG
0007 8E D8 MOV DS,AX
0009 A1 0002 R MOV AX,PRICE ;Загрузить стоимость
000C 8B 1E 0000 R MOV BX,QTY ; и количество
0010 9A 0000 ---- E CALL SUBMUL ;Вызвать подпрограмму
0015 CB RET
0016 BEGIN ENDP
0016 CODESG ENDS
END BEGIN
Segments and Groups:
N a m e Size Align Combine Class
CODESG . . . . . . . . . . . . 0016 PARA NONE 'CODE'
DATASG . . . . . . . . . . . . 0004 PARA NONE 'DATA'
STACKSG. . . . . . . . . . . . 0080 PARA STACK 'STACK'
Symbols:
N a m e Type Value Attr
BEGIN. . . . . . . . . . . . . F PROC 0000 CODESG Length=0016
PRICE. . . . . . . . . . . . . L WORD 0002 DATASG
QTY. . . . . . . . . . . . . . L WORD 0000 DATASG
SUBMUL . . . . . . . . . . . . L FAR 0000 External
page 60,132
TITLE SUBMUL Подпрограмма для умножения
;-----------------------------------------------
0000 CODESG SEGMENT PARA 'Code'
0000 SUBMUL PROC FAR
ASSUME CS:CODESG
PUBLIC SUBMUL
0000 F7 E3 MUL BX ;AX-стоимость, BX-количество
0002 CB RET ;Произведение в DX:AX
Ассемблер для IBM PC. Программы. 153
0003 SUBMUL ENDP
0003 CODESG ENDS
END SUBMUL
Segments and groups:
N a m e Size Align Combine Class
CODESG . . . . . . . . . . . . 0003 PARA NONE 'CODE'
Symbols:
N a m e Type Value Attr
SUBMUL . . . . . . . . . . . . F PROC 0000 CODESG Clobal Length=0003
LINK
IBM Personal Computer Linker
Version 2.30 (C) Copyright IBM Corp 1981, 1985
Object Modules: B:CALLMUL1+B:SUBMUL1
Run File: [B:CALLMUL1.EXE]: <return>
List File:[NUL.MAP]: CON
Libraries [.LIB]: <return>
Start Stop Length Name Class
00000H 00015H 0016H CODESG CODE <--Примечание: 2 кодовых
00020H 00022H 0003H CODESG CODE <-- сегмента
00030H 00033H 0004H DATASG DATA
00040H 000BFH 0080H STACKSG STACK
Program entry point at 0000:0000
Ассемблер для IBM PC. Программы. 154
page 60,132
TITLE CALLMUL2 (EXE) Вызов подпрограммы умножения
EXTERN SUBMUL:FAR
;----------------------------------------------
0000 STACKSG SEGMENT PARA STACK 'Stack'
0000 40 [????] DW 64 DUP(?)
0080 STACKSG ENDS
;----------------------------------------------
0000 DATASG SEGMENT PARA 'Data'
0000 0140 QTY DW 0140H
0002 2500 PRICE DW 2500H
0004 DATASG ENDS
;----------------------------------------------
0000 CODESG SEGMENT PARA PUBLIC 'Code'
0000 BEGIN PROC FAR
ASSUME CS:CODESG,DS:DATASG,SS:STACKSG
0000 1E PUSH DS
0001 2B C0 SUB AX,AX
0003 50 PUSH AX
0004 B8 ---- R MOV AX,DATASG
0007 8E D8 MOV DS,AX
0009 A1 0002 R MOV AX,PRICE ;Загрузить стоимость
000C 8B 1E 0000 R MOV BX,QTY ; и количество
0010 9A 0000 ---- E CALL SUBMUL ;Вызвать подпрограмму
0015 CB RET
0016 BEGIN ENDP
0016 CODESG ENDS
END BEGIN
Segments and Group:
N a m e Size Align Combine Class
CODESG . . . . . . . . . . . . .0016 PARA PUBLIC 'CODE'
DATASG . . . . . . . . . . . . .0004 PARA NONE 'DATA'
STACKSG. . . . . . . . . . . . .0080 PARA STACK 'STACK'
Symbols:
N a m e Type Value Attr
BEGIN. . . . . . . . . . . . . F PROC 0000 CODESG Lenght=0016
PRICE. . . . . . . . . . . . . L WORD 0002 DATASG
QTY. . . . . . . . . . . . . . L WORD 0000 DATASG
SUBMUL . . . . . . . . . . . . L FAR 0000 External
page 60,132
TITLE SUBMUL2 Вызываемая подпрограмма умножения
;----------------------------------------------
0000 CODESG SEGMENT PARA PUBLIC 'CODE'
0000 SUBMUL PROC FAR
ASSUME CS:CODESG
PUBLIC SUBMUL
0000 F7 E3 MUL BX ;AX-стоимость, BX-количество
Ассемблер для IBM PC. Программы. 155
0002 CB RET ;Произведение в DX:AX
0003 SUBMUL ENDP
0003 CODESG ENDS
END SUBMUL
Segments and Groups:
N a m e Size Align Combine Class
CODESG. . . . . . . . . . . . . 0003 PARA PUBLIC 'CODE'
Symbols:
N a m e Type Value Attr
SUBMUL. . . . . . . . . . . . .F PROC 0000 CODESG Global Length=0003
LINK
IBM Personal Computer Linker
Version 2.30 (C) Copyright IBM Corp 1981, 1985
Object Modules: B:CALLMUL2+B:SUBMUL2
Run File: [B:CALLMUL2.EXE]: <return>
List File: [NUL.MAP]: CON
Libraries [.LIB]: <return>
Start Stop Length Name Class
00000H 00022H 0023H CODESG CODE <-- Примечание: 1 сегмент кода
00030H 00033H 0004H DATASG DATA
00040H 000BFH 0080H STACKSG STACK
Program entry point at 0000:0000
Ассемблер для IBM PC. Программы. 156
page 60,132
TITLE CALLMUL3 (EXE) Вызов подпрограммы
; для умножения
EXTRN SUBMUL:FAR
PUBLIC QTY,PRICE
;-------------------------------------------------
0000 STACKSG SEGMENT PARA STACK 'Stack'
0000 40 [????] DW 64 DUP(?)
0080 STACKSD ENDS
;-------------------------------------------------
0000 DATASG SEGMENT PARA PUBLIC 'Data'
0000 0140 QTY DW 0140H
0002 2500 PRICE DW 2500H
0004 DATASG ENDS
;-------------------------------------------------
0000 CODESG SEGMENT PARA PUBLIC 'Code'
0000 BEGIN PROC FAR
ASSUME CS:CODESG,DS:DATASG,SS:STACKSG
0000 1E PUSH DS
0001 2B C0 SUB AX,AX
0003 50 PUSH AX
0004 B8 ---- R MOV AX,DATASG
0007 8E D8 MOV DS,AX
0009 9A 0000 ---- E CALL SUBMUL ;Вызвать подпрограмму
000E CB RET
000F BEGIN ENDP
000F CODESG ENDS
END BEGIN
Segments and Groups:
N a m e Size Align Combine Class
CODESG . . . . . . . . . . . . 000F PARA PUBLIC 'CODE'
DATASG . . . . . . . . . . . . 0004 PARA PUBLIC 'DATA'
STACKSG. . . . . . . . . . . . 0080 PARA STACK 'STACK'
Symbols:
N a m e Type Value Attr
BEGIN. . . . . . . . . . . . . F PROC 0000 CODESG Length=000F
PRICE. . . . . . . . . . . . . L WORD 0002 DATASG Global
QTY. . . . . . . . . . . . . . L WORD 0000 DATASG Global
SUBMUL . . . . . . . . . . . . L FAR 0000 External
page 60,132
TITLE SUBMUL Подпрограмма для умножения
EXTRN QTY:WORD,PRICE:WORD
;-------------------------------------------------
0000 CODESG SEGMENT PARA PUBLIC 'CODE'
0000 SUBMUL PROC FAR
ASSUME CS:CODESG
PUBLIC SUBMUL
Ассемблер для IBM PC. Программы. 157
0000 A1 0000 E MOV AX,PRICE
0003 8B 1E 0000 E MOV BX,QTY
0007 F7 E3 MUL BX ;Произведение в DX:AX
0009 CB RET
000A SUBMUL ENDP
000A CODESG ENDS
END SUBMUL
Segments and Groups:
N a m e Size Align Combine Class
CODESG . . . . . . . . . . . . 000A PARA PUBLIC 'CODE'
Symbols:
N a m e Type Value Attr
PRICE. . . . . . . . . . . . . V WORD 0000 External
QTY. . . . . . . . . . . . . . V WORD 0000 External
SUBMUL . . . . . . . . . . . . F PROC 0000 CODESG Global Length=000A
LINK
IBM Personal Computer Linker
Version 2.30 (C) Copyright IBM Corp 1981, 1985
Object Modules: B:CALLMUL3+B:SUBMUL3
Run File: [B:CALLMUL3.EXE]: <return>
List File: [NUL.MAP]: CON
Libraries [.LIB]: <return>
Start Stop Length Name Class
00000H 00019H 001AH CODESG CODE
00030H 00033H 0004H DATASG DATA
00040H 000BFH 0080H STACKSG STACK
PROGRAM entry point at 0000:0000
Ассемблер для IBM PC. Программы. 158
page 60,132
TITLE CALLMULL4 (EXE) Передача параметров
; в подпрограмму
EXTRN SUBMUL:FAR
;-------------------------------------------------
0000 STACKSG SEGMENT PARA STACK 'Stack'
0000 40 [ ???? ] DW 64 DUP(?)
0080 STACKSG ENDS
;-------------------------------------------------
0000 DATASG SEGMENT PARA 'Data'
0000 0140 QTY DW 0140H
0002 2500 PRICE DW 2500H
0004 DATASG ENDS