Питер Абель. Ассемблер и программирование для IBM PC

страница №16

Q20CURS ;Установить курсор
RET
G10DISP ENDP
; Прокрутка (скроллинг) экрана:
; ----------------------------
Q10SCR PROC NEAR ;в AX - адрес элемента
MOV BH,1EH ;Установить цвет
MOV CX,0000
MOV DXX,184FH ;Функция прокрутки
INT 10H
RET
Q10SCR ENDP



Ассемблер для IBM PC. Программы. 127


; Установка курсора:
; -----------------
Q20CURS PROC NEAR
MOV AH,02 ;Функция установки курсора
MOV BH,00 ; курсор
MOV DH,ROW ; строка
MOV DL,00 ; столбец
INT 10H
RET
Q20CURS ENDP
; Вывод сообщения об ошибке:
; -------------------------
X10ERR PROC NEAR
MOV AH,40H ;в DX - адрес сообщения
MOV BX,01 ;Номер
MOV CX,20 ;Длина сообщения
INT 21H
RET
X10ERR ENDP

CODESG ENDS
END BEGIN


































Ассемблер для IBM PC. Программы. 128



page 60,132
TITLE ASCREAD (COM) Чтение ASCII файла
CODESG SEGMENT PARA 'Code'
ASSUME CS:CODESG,DS:CODESG,SS:CODESG,ES:CODESG
ORG 100H
BEGIN: JMP MAIN
; -------------------------------------------------
SECTOR DB 512 DUP(' ') ;Область ввода
DISAREA DB 120 DUP(' ') ;Область вывода на экран
ENDCDE DW 00
HANDLE DW 0
OPENMSG DB '*** Open error ***'
PATHNAM DB 'D:\HANREAD.ASM', 0
ROW DB 00
; -------------------------------------------------
MAIN PROC NEAR ;Основная программя
MOV AX,0600H
CALL Q10SCR ;Очистить экран
CALL Q20CURS ;Установить курсор
CALL E10OPEN ;Открыть файл,
; установить DTA
CMP ENDCDE,00 ;Ошибка при открытии?
JNE A90 ; да - выйти,
A20LOOP: ; нет - продолжить
CALL R10READ ;Чтение первого сектора
CMP ENDCDE,00 ;Конец файла, нет данных?
JE A90 ; да - выйти
CALL G10XPER ;Выдать на экран
A90: RET ;Завершить программу
MAIN ENDP
; Открыть файл на диске:
; ---------------------
E10OPEN PROC NEAR
MOV AH,3DH ;Функция открытия
MOV AL,00 ;Только чтение
LEA DX,PATHNAM
INT 21H
JNC E20 ;Проверить флаг CF
CALL X10ERR ; ошибка, если установлен
RET
E20:
MOV HANDLE,AX ;Запомниить номер файла
RET
E10OPEN ENDP
; Построчный вывод данных на экран:
; --------------------------------
G10XPER PROC NEAR
CLD ;Направление слева-направо
LEA SI,SECTOR
G20:
LEA DI,DISAREA
G30:



Ассемблер для IBM PC. Программы. 129


LEA DX,SECTOR+512
CMP SI,DX ;Конец сектора?
JNE G40 ; нет - обойти,
CALL R10READ ; да - читать следующий
CMP ENDCDE,00 ;Конец файла?
JE G80 ; да - выйти
LEA SI,SECTOR
G40:
LEA DX,DISAREA+80
CMP DI,DX ;Конец DISAREA?
JB G50 ; нет - обойти,
MOV [DI],0D0AH ; да - установить CR/LF
CALL H10DISP ; и выдать на экран
LEA DI,DISAREA
G50:
LODSB ;Загрузить [SI] в AL
; и увеличить SI
STOSB ;Записать AL в [DI]
; и увеличить DI
CMP AL,1AH ;Конец файла?
JE G80 ; да - выйти
CMP AL,0AH ;Конец строки?
JNE G30 ; нет - повторить цикл,
CALL H10DISP ; да - вывести на экран
JMP G20
G80:
CALL H10DISP ;Вывести последнюю строку
G90: RET
G10XPER ENDP
; Вывод строки на экран:
; ---------------------
H10DISP PROC NEAR
MOV AH,40H ;Функция вывода на экран
MOV BX,01 ;Номер (Handle)
LEA CX,DISAREA ;Вычислить
NEG CX ; длину
ADD CX,DI ; строки
LEA DX,DISAREA
INT 21H
CMP ROW,22 ;Последняя строка экрана?
JAE H20 ; нет - выйти
INC ROW
JMP H90
H20:
MOV AX,0601H ;Прокрутка (скроллинг)
CALL Q10SCR
CALL Q20CURS
H90: RET
H10DISP ENDP
; Чтени дискового сектора:
; -----------------------
R10READ PROC NEAR
MOV AH,3FH ;Функция чтения



Ассемблер для IBM PC. Программы. 130


MOV BX,HANDLE ;Устройство
MOV CX,512 ;Длина
LEA DX,SECTOR ;Буфер
INT 21H
MOV ENDCDE,AX
RET
R10READ ENDP
; Прокрутка (скроллинг) экрана:
; ----------------------------
Q10SCR PROC NEAR ;в AX адрес элемента
MOV BH,1EH ;Установить цвет
MOV CX,0000 ;Прокрутка
MOV DX,184FH
INT 10H
RET
Q10SCR ENDP
; Установка курсора:
; -----------------
Q20CURS PROC NEAR
MOV AH,02 ;Функция
MOV BH,00 ; установки курсора
MOV DH,ROW
MOV DL,00
INT 10H
RET
Q20CURS ENDP
; Вывод сообщения об ошибке на диске:
; ----------------------------------
X10ERR PROC NEAR
MOV AH,40H ;Функция вывода на экран
MOV BX,01 ;Номер устройства
MOV CX,18 ;Длина
LEA DX,OPENMSG
INT 21H
MOV ENDCDE,O1 ;Индикатор ошибки
RET
X10ERR ENDP

CODESG ENDS
END BEGIN
















Ассемблер для IBM PC. Программы. 131



TITLE GETPATH (COM) Получить текущий каталог
CODESG SEGMENT PARA 'Code'
ASSUME CS:CODESG,DS:CODESG,ES:CODESG
ORG 100H
BEGIN: JMP SHORT MAIN
; -----------------------------------------------
PATHNAM DB 65 DUP(' ') ;Имя текущего пути доступа
; -----------------------------------------------
MAIN PROC NEAR
MOV AH,19H ;Определить текущий диск
INT 21H
ADD AL,41H ;Заменить шест.номер
MOV DL,AL ; на букву: 0=A, 1=B ...
CAL B10DISP ;Выдать номер дисковода,
MOV DL,':'
CAL B10DISP ; двоеточие,
MOV DL,'\'
CAL B10DISP ; обратную косую

MOV AH,47H ;Получить текущий каталог
MOV DL,00
LEA SI,PATHNAM
INT 21H
A10LOOP:
CMP BYTE PTR [SI],0 ;Конец имени пути доступа
JE A20 ; да - выйти
MOV AL,[SI] ;Выдать на экран
MOV DL,AL ; имя пути доступа
CALL B10DISP ; побайтно
INC SI
JMP A10LOOP
A20: RET ;Выход в DOS
MAIN ENDP

B10DISP PROC NEAR
MOV AH,02 ;в DL - адрес элемента
INT 21H ;Функция вывода на экран
RET
B10DISP ENDP

CODESG ENDS
END BEGIN













Ассемблер для IBM PC. Программы. 132



TITLE BIOREAD (COM) Чтение дискового сектора через BIOS
CODESG SEGMENT PARA 'Code'
ASSUME CS:CODESG,DS:CODESG,SS:CODESG,ES:CODESG
ORG 100H
BEGIN JMP MAIN
; ---------------------------------------------------------
RECDIN DB 512 DUP(' ') ;Область ввода
ENDCDE DB 00
CURADR DW 0304H ;Начало (дорожка/сектор)
ENDADR DW 0501H ;Конец (дорожка/сектор)
READMSG DB '*** Read error ***$'
SIDE DB 00
; ---------------------------------------------------------
MAIN PROC NEAR
MOV AX,0600H ;Функция прокрутки экрана
A20LOOP:
CALL Q10SCR ;Очистить экран
CALL Q20CURS ;Установить курсор
CALL C10ADDR ;Определить адрес на диске
MOV CX,CURADR
MOV DX,ENDADR
CMP CX,DX ;Последний сектор?
JE A90 ; да - выйти
CALL F10READ ;Получить дисковую запись
CMP ENDCDE,00 ;Ошибка чтения?
JNZ A90 ; да - выйти
CALL G10DISP ;Вывести сектор на экран
JMP A20LOOP ;Повторить
A90 RET ;Завершить программу
MAIN ENDP
; Вычислить следующий адрес на диске:
; ----------------------------------
C10ADDR PROC NEAR
MOV CX,CURADR ;Последняя дорожка/сектор
CMP CL,10 ;Последний сектор?
JNE C90 ; нет - выйти
CMP SIDE,00 ;Обойти, если сторона = 0
JE C20
INC CH ;Увеличить номер дорожки
C20:
XOR SIDE,01 ;Сменить сторону
MOV CL,01 ;Установить сектор = 1
MOV CURADR,CX
C90: RET
C10ADDR ENDP
; Чтение дискового сектора:
; ------------------------
F10READ PROC NEAR
MOV AL,01 ;Число секторов
MOV AH,02 ;Функция чтения
LEA BX,RECDIN ;Адрес буфера
MOV CX,CURADR ;Дорожка/сектор



Ассемблер для IBM PC. Программы. 133


MOV DH,SIDE ;Сторона
MOV DL,01 ;Дисковод B
INT 13H ;Выполнить ввод
CMP AH,00 ;Ошибка чтения?
JZ F90 ; нет - выйти
MOV ENDCDE,01 ; да:
CALL X10ERR ; ошибка чтения
F90:
INC CURADR ;Увеличить номер сектора
RET
F10READ ENDP
; Вывод сектора на экран:
; ----------------------
G10DISP PROC NEAR
MOV AH,40H ;Функция вывода на экран
MOV BX,01 ;Номер устройства
MOV CX,512 ;Длина
LEA DX,RECDIN
INT 21H
RET
G10DISP ENDP
; Очистка экрана:
; --------------
Q10SCR PROC NEAR
MOV AX,0600H ;Полный экран
MOV BH,1EH ;Установить цвет
MOV CX,0000 ;Функция прокрутки
MOV DX,184FH
INT 10H
RET
Q10SCR ENDP
; Установка курсора:
; -----------------
Q20CURS PROC NEAR
MOV AH,02 ;Функция установки
MOV BH,00 ; курсора
MOV DX,0000
INT 10H
RET
Q20CURS ENDP
; Вывод сообщения об ошибке на диске:
; ----------------------------------
X10ERR PROC NEAR
MOV AH,40H ;Функция вывода на экран
MOV BH,01 ;Номер устройства
MOV CX,18 ;Длина сообщения
LEA DX,READMSG
INT 21H
RET
X10ERR ENDP
CODESG ENDS
END BEGIN




Ассемблер для IBM PC. Программы. 134



TITLE PRTNAME (COM) Ввод и печать имен
CODESG SEGMENT PARA PUBLIC 'CODE'
ASSUME CS:CODESG,DS:CODESG,SS:CODESG,ES:CODESG
ORG 100H
BEGIN: JMP SHORT MAIN
; -----------------------------------------------------
NAMEPAR LABEL BYTE ;Список параметров
MAXNLEN DB 20 ; максимальная длина имени
NAMELEN DB ? ; длина введенного имени
NAMEFLD DB 20 DUP(' ') ; введенное имя
;Строка заголовка:
HEADG DB 'List of Employee Names Page '
PAGECTR DB '01',0AH,0AH
FFEED DB 0CH ;Перевод страницы
LFEED DB 0AH ;Перевод строки
LINECTR DB 01
PROMPT DB 'Name? '
; -----------------------------------------------------
MAIN PROC NEAR
CALL Q10CLR ;Очистить экран
CALL M10PAGE ;Установка номера страницы
A2LOOP:
MOV DX,0000 ;Установить курсор в 00,00
CALL Q20CURS
CALL D10INPT ;Ввести имя
CALL Q10CLR
CMP NAMELEN,00 ;Имя введено?
JE A30 ; если нет - выйти,
CALL E10PRNT ; если да - подготовить
; печать
JMP A20LOOP
A30:
MOV CX,01 ;Конец работы:
LEA DX,FFEED ; один символ
CALL P10OUT ; для прогона страницы,
RET ; возврат в DOS
MAIN ENDP
; Ввод имени с клавиатуры:
; -----------------------
D10INPT PROC NEAR
MOV AH,40H ;Функция
MOV BX,01 ; вывода на экран
MOV CX,05 ; 5 символов
LEA DX,PROMPT
INT 21H ;Вызов DOS
MOV AH,0AH ;Функция ввода с клавиатуры
LEA DX,NAMEPAR
INT 21H ;Вызов DOS
RET
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

Страницы

Подякувати Помилка?

Дочати пiзнiше / подiлитися