1) EX1: ПРОСТЕЙШАЯ ПРОГРАММА, СООБЩАЮЩАЯ О ТОМ, ЧТО ЕЕ ЗАПУСТИЛИ.
2) EX2+EX2A: КОМБИНАЦИИ СЕГМЕНТОВ (common-public).
3) EX3: СЛОВА И БАЙТЫВ ПАМЯТИ.
4) EX4: СЛОВА И БАЙТЫВ РЕГИСТРАХ
5) EX5: ЦЕЛЫЕ ДВОИЧНЫЕ (С ФИКС.ТОЧКОЙ) В ПАМЯТИ И РЕГИСТРАХ
6) EX6: АРИФМЕТИКА ДВОИЧНЫХ ЦЕЛЫХ:Y=(A+4-B)*2/C.
7) EX7: ВЕТВЛЕНИЯ, ПЕРЕХОДЫ, ЦИКЛЫ.
8) EX8: ИНДЕКСАЦИЯ.
9) EX9: ИМЕНА И ВЫРАЖЕНИЯ.
10) EX10: СТРОКИ СИМВОЛОВ В ПАМЯТИ И РЕГИСТРАХ
11) EX11: ПЕРЕСЫЛКА СТРОКИ СИМВОЛОВ
12) EX12: ПОИСК ПРОБЕЛА В СТРОКЕ СИМВОЛОВ
13) EX13: СРАВНЕНИЕ СТРОК
14) EX14: БЛИЖНЯЯ ПРОЦЕДУРА С ДВУМЯ ПАРАМЕТРАМИ (ПО ЗНАЧЕНИЮ)
15) EX15: БЛИЖНИЙ ВЫЗОВ БЕЗ ПРОЦЕДУРЫ(АНАЛОГ EX13 С ПОМЕЧЕННОЙ П/П)
16) EX16: БЛИЖНЯЯ ПРОЦЕДУРА С ТРЕМЯ ПАРАМЕТРАМИ (ПО БЛИЖНЕМУ АДРЕСУ)
17) EX17: БЛИЖНЯЯ ПРОЦЕДУРА С ТРЕМЯ ПАРАМЕТРАМИ (ПО ДАЛЬНЕМУ АДРЕСУ)
18) EX18+EX18A: МЕЖМОДУЛЬНЫЕ ССЫЛКИ (ДАННЫЕ И МЕТКИ).
19) EX19+EX19A: ВЫЗОВ ВНЕШНЕЙ БЛИЖНЕЙ ПРОЦЕДУРЫ.
20) EX20+EX20A: ВЫЗОВ ВНЕШНЕЙ ДАЛЕКОЙ ПРОЦЕДУРЫ(ПАР.ПО ДАЛЬН.АДРЕСУ)
21) EX21: ДАЛЕКАЯ ПРОЦЕУРА - ОБРАЩЕНИЕ К DOS (INT 21H)
22) EX22: ПОЛЬЗОВАТЕЛЬСКИЙ ОБРАБОТЧИК ПРЕРЫВАНИЯ.
23) EX23: ПОВТОРЯЕМЫЕ БЛОКИ REPT, IRP, IRPC.
24) DX01: ДИСКИ-ФАЙЛЫСРЕДСТВАМИ DOS:
FAT-сколько места;DTA-поиск файлов.
25) DX02: ДИСКИ-ФАЙЛЫСРЕДСТВАМИ DOS:
поиск файла и извлечение полей оглавления из DTA
DX03: HANDLE-ФАЙЛЫ:СОЗДАНИЕ,ОТКРЫТИЕ,ПОЗИЦИОНИР.,ИЗМЕРЕНИЕ,В/В
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; EX1: ПРОСТЕЙШАЯ ПРОГРАММА, СООБЩАЮЩАЯ О ТОМ, ЧТО ЕЕ ЗАПУСТИЛИ.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;180195;;;;
include userv.mac
; Сегмент данных:
data segment;-именование сегмента.
str db "Пример программы",13,10,"$";-объявление данных.
data ends;-конец сегмента.
; Сегмент кода:
code segment;-именование сегмента.
|
assume cs:code,ds:data;-сементные регистры.
start:;-метка точки входа.
mov ax,data;-адрес сегмента данных.
mov ds,ax; в регистр ds.
mov dx,offset str;-адрес вых.строки в dx.
mov ah,09h;-обращение к системной.
int 21h; функции вывода строки.
u_msg
u_show_r16 ds,'Сегмент данных: '
lea ax,str
u_show_ax ':'
u_msg
u_show_r16 cs,'Сегмент кода: '
lea ax,start
u_show_ax ':'
mov ah,4ch;-обращение к сис.функ.
int 21h; завершения программы.
code ends;-конец сегмента.
; Сегмент стека:
stack segment stack;-именование сегмента.
dw 64 dup(?);-место для стека.
stack ends;-конец сегмента.
end start;-конец исходного модуля
; и имя точки входа
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; EX2: КОМБИНАЦИИ СЕГМЕНТОВ. Первая половина.
; Этот пример "собирается" из двух исходников EX2.ASM и EX2A.ASM,
; которые по отдельности транслируются и совместно линкуются:
; masm ex2;
; masm ex2a;
; link ex2 ex2a;
; ex2 (M2.BAT)
; Сегменты данных накладываются (EX2A на EX2),а сегмент кода до-
; полнится сегментом кода из EX2A.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;180195;;;;
; Сегмент данных:
data segment byte common; COMMON-на этот сегмент наложится
str db "Пример"; такой же сегмент из EX2A.
data ends; BYTE-выравнивание по байтам.
; Сегмент кода:
code segment byte public; PUBLIC-этот сегмент дополнится
assume cs:code,ds:data; таким же сегментом из EX2A,на-
; чиная со следующего байта.
start:
mov ax,data
mov ds,ax
mov dx,offset str; Программа не закончена, она
; продолжится командами из кодо-
; вого сегмента EX2A.
code ends
; Сегмент стека:
stack segment stack
dw 64 dup(?)
stack ends
end start
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; EX2A: КОМБИНАЦИИ СЕГМЕНТОВ. Вторая половина.
; Этот пример "собирается" из двух исходников EX2.ASM и EX2A.ASM,
; которые по отдельности транслируются и совместно линкуются:
|
; masm ex2;
; masm ex2a;
; link ex2 ex2a;
; ex2 (M2.BAT)
; Сегменты данных накладываются (EX2A на EX2),а сегмент кода до-
; полнится сегментом кода из EX2A.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;180195;;;;
data segment byte common
db " Наложение данных (common)",13,10
db " Сложение кодов (public)",13,10,"$"
; COMMON-этот сегмент наложится
; на такой же сегмент из EX2.
; BYTE-выравнивание по байтам.
data ends
code segment byte public; PUBLIC-этот сегмент дополняет
mov ah,09h; такой же сегмент из EX2.
int 21h; Команды логически продолжают
mov ah,4ch; программу из EX2.
int 21h
code ends
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; EX3: СЛОВА И БАЙТЫВ ПАМЯТИ.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
include userv.mac
RC equ <13,10>
data segment
; В программе шестнадцатеричные величины записываются слева на-
; право. В памяти каждыий байт читается слева направо, но:
; - байты в слове читаются справа налево,
; - слова в двойном слове читаются справа налево...
;
xbyte db 12h,34h,0ABh;-поле из трех байт: 12 34 AB
xword dw 5678h,1A1Bh;-поле из двух слов: 7856 1B1A
xdword dd 2A2B2C2Dh;-двойное слово: 2D2C2B2A
data ends
code segment
assume cs:code,ds:data
start:
mov ax,data
mov ds,ax
u_show_byte xbyte,11,<RC,'Вывод поля из 11 байт: xbyte:',RC>
u_show_word xbyte,4,<RC,'Вывод поля из 4 слов: xbyte:',RC>
u_show_word xword,2,<RC,'Вывод двух слов, начиная с xword:',RC>
mov ah,4ch
int 21h
code ends
stack segment stack
dw 64 dup(?)
stack ends
end start
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; EX4: СЛОВА И БАЙТЫВ РЕГИСТРАХ
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
include userv.mac
RC equ <13,10>
data segment
; Байты в регистре размещаются справа налево, но каждыий байт
; читается слева направо.
; То есть слово-константа читается также как и регистр.
|
xbyte db 12h,34h,0ABh;-поле из трех байт: 12 34 AB
xword dw 5678h,1A1Bh;-поле из двух слов: 7856 1B1A
data ends
code segment
assume cs:code,ds:data
start:
mov ax,data
mov ds,ax
;начало:
mov ax,word ptr xbyte
u_show_ax <RC,'Два байта 12h,34h в регистре AX:'>
u_show_al <RC,' младшая часть (регистр AL):'>
mov al,ah
u_show_al <RC,' старшая часть (регистр AH):'>
mov ax,xword
u_show_ax <RC,'Слово 5678h в регистре AX:'>
u_show_al <RC,' младшая часть (регистр AL):'>
mov al,ah
u_show_al <RC,' старшая часть (регистр AH):'>
mov ax,1A1Bh
u_show_ax <RC,'Непоср.опер.1A1Bh в регистре AX:'>
u_show_al <RC,' младшая часть (регистр AL):'>
mov al,ah
u_show_al <RC,' старшая часть (регистр AH):'>
;конец.
mov ah,4ch
int 21h
code ends
stack segment stack
dw 64 dup(?)
stack ends
end start
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; EX5: ЦЕЛЫЕ ДВОИЧНЫЕ (С ФИКС.ТОЧКОЙ) В ПАМЯТИ И РЕГИСТРАХ
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
include userv.mac
data segment
nbyte db 17,-17
nword dw 17,-17
data ends
code segment
assume cs:code,ds:data
start:
mov ax,data
mov ds,ax
;начало:
u_msg <13,10,'Примеры:',13,10>
u_show_byte nbyte,2,'Короткие числа 17 и -17 в памяти:'
u_msg
mov al,17
u_show_al 'Короткие числа 17 и -17 в регистре AX:'
mov al,-17
u_show_al
u_msg
u_show_word nword,2,'Двухбайт.числа 17 и -17 в памяти:'
u_msg
u_msg 'Двухбайт.числа 17 и -17 в регистре AX:'
u_msg
mov ax,nword
u_show_ax ' после "mov ax,nword": '
u_msg
mov ax,-17
u_show_ax ' после "mov ax,-17": '
u_msg <13,10,'Пробуем сами:'>
rpt:
u_key_bin <13,10,'Введите число (не число - конец работы)==='>
jnc cont
jmp fin
cont:
u_show_ax <13,10,' Так оно выглядит в регистре AX='>
mov nword,ax
u_show_word nword,,<13,10,' Так оно выглядит в памяти WORD='>
jmp rpt
fin:
;конец.
mov ah,4ch
int 21h
code ends
stack segment stack
dw 64 dup(?)
stack ends
end start
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; EX6: АРИФМЕТИКА ДВОИЧНЫХ ЦЕЛЫХ:Y=(A+4-B)*2/C.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
include userv.mac
data segment
a dw 3; A,B,C - в формате слова
b dw -2
c dw -4
ab db 4; A,B,C - в формате байта
bb db -2
cb db -4
data ends
RC equ <13,10>
code segment
assume cs:code,ds:data
start:
mov ax,data
mov ds,ax
u_msg <rc,'Считаем Y=(A+4-B)*2/C в формате слова:'>
; Печать исходных данных:
mov ax,a
u_show_bin <rc,"A=">
mov ax,b
u_show_bin <rc,"B=">
mov ax,c
u_show_bin <rc,"C=">
; Вычисления:
mov ax,a; A -> ax =A
u_show_bin <rc,'mov ax,a ax:'>
add ax,4; ax+4 -> ax =A+4
u_show_bin <rc,'add ax,4 ax:'>
sub ax,b; ax-B -> ax =A+4-B
u_show_bin <rc,'sub ax,b ax:'>
mov bx,2; 2 -> bx
imul bx; ax*bx -> dx|ax =(A+4-B)*2
u_show_bin <rc,'imul bx ax:'>
idiv c; dx|ax:C ->dx=остаток
; ax=частное
; Печать последнего результата:
u_show_bin <rc,'idiv c частное=ax:'>
mov ax,dx
u_show_bin <rc,' остаток=dx:'>
u_msg <rc,rc>
u_msg 'Считаем Y=(A+4-B)*2/C в формате байта (без подробностей):'
; Печать исходных данных:
mov al,1;
imul ab; -распространение короткого числа на
u_show_bin <rc,"A=">; весь регистр AX и вывод AX.
mov al,1
imul bb
u_show_bin <rc,"B=">
mov al,1
imul cb
u_show_bin <rc,"C=">
; Вычисления:
mov al,ab; A -> al =A
add al,4; al+4 -> al =A+4
sub al,bb; al-B -> al =A+4-B
mov bl,2; 2 -> bl
imul bl; al*bl -> ah|al =(A+4-B)*2
idiv cb; ah|al:C ->ah=остаток
; al=частное
; Печать последнего результата:
push ax
mov bl,1; -распространение короткого частного на
imul bl; весь регистр AX и вывод AX.
u_show_bin <rc,'Получилось частное=al:'>
pop ax
mov al,ah; -распространение короткого остатка на
imul bl; весь регистр AX и вывод AX.
u_show_bin <rc,' остаток=ah:'>
mov ah,4Ch
int 21h
code ends
stack segment stack
dw 64 dup(?)
stack ends
end start
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; EX7: ВЕТВЛЕНИЯ, ПЕРЕХОДЫ, ЦИКЛЫ.;
; Вычисляется сумма 6 чисел, вводимых с пульта.;
; При этом очередное число суммируется только;
; если оно больше 0. На каждом шагу печатается;
; накопленная сумма.;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; - Условные переходы JA, JB, JC, JNC, LOOP,...выполняются;
; не более чем на +127 или -128 байт, что особенно неудобно;
; для организации циклов (LOOP).;
; - Безусловный переход JMP позволяет "прыгнуть" на любое;
; расстояние.;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
include userv.mac
data segment
data ends
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
RC equ <13,10>; В этом примере цикл органи-;
code segment; зован "вручную", так-как его;
assume cs:code,ds:data; начало слишком удалено от;
start:; "зацикливающего" перехода.;
mov ax,data;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov ds,ax
sub bx,bx; - обнуление суммы
mov cx,1; - счетчик повторений
rpt: u_key_bin <RC,'Введите число: '>; - нач.цикла,ввод числа
jnc cnt; - переход по флагу CF
u_msg <RC,'Ошибка! Попробуйте еще раз!'>
jmp rpt; - безусловный переход
cnt: cmp ax,0; - сравнение с нулем
jb met; - переход, если меньше
add bx,ax; - накопление суммы
met: mov ax,bx
u_show_bin <RC,'Сумма='>; - вывод суммы
inc cx; - увеличение счетчика
cmp cx,6;;;;;;;;;;; - сравнение его с 6
ja exit; условие;; - переход, если больше
jmp rpt; выхода;; - безусловный переход
;;;;;;;;;;; к началу цикла
exit:
mov ah,4Ch
int 21h
code ends
stack segment stack
dw 64 dup(?)
stack ends
end start
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; EX8: индексация:;
; Вычисляется сумма 6 чисел, размещенных в памяти,;
; используется три способа индексации:;
;;
; {смещение}[BX] -Базовые операнды;
; {смещение}[DI] -Индексные операнды;
; {смещение}[BX][DI] -Базово-индексные операнды;
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
include userv.mac
data segment
x db 1,2,3,4,5,6
data ends
RC equ <13,10>
code segment
assume cs:code,ds:data
start:
mov ax,data
mov ds,ax
; Базовые операнды
sub bx,bx; - обнуление базы
sub al,al; - обнуление суммы
mov cx,6; - счетчик повторений
repeat:
add al,x[bx]; операнд базируется изменяемым
; значением bx
inc bx
loop repeat
cbw
u_show_bin <RC,"Базовые операнды. Результат=">
; Индексные операнды
sub di,di; - обнуление индекса
sub al,al; - обнуление суммы
mov cx,6; - счетчик повторений
repeat1:
add al,x[di]; операнд индексируется изменяменяемым
; значением di
inc di
loop repeat1
cbw
u_show_bin <RC,"Индексные операнды. Результат=">
; Базово-индексные операнды
lea bx,x; - установка базы
sub di,di; - обнуление индекса
sub al,al; - обнуление суммы
mov cx,6; - счетчик повторений
repeat2:
add al,[bx][di]; операнд адресуется постоянной базой bx
; и изменяемым индексом di.
inc di
loop repeat2
cbw
u_show_bin <RC,"Базово-индексные операнды. Результат=">
mov ah,4Ch
int 21h
code ends
stack segment stack
dw 64 dup(?)
stack ends
end start
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; EX9: Имена и выражения;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;include userv.mac
RC equ <13,10>
data segment
ABC dw 7,8,9
CNT=$
CDE db RC,'Этот пример надо транслировать с листингом: mams ex9,,list;$'
CNT1=$
data ends
; ТИПЫИМЕН
AW=ABC;Абс. симв. имена типа переменной в памяти
AB=CDE;или метки (WORD, BYTE, NEAR)
AN=LAB
AWA EQU ABC;Псевдоимена (ALIAS)
ABA EQU CDE
ANA EQU LAB
AWV EQU ABC+1;Абс. симв. имена типа переменной в памяти
ABV EQU CDE+1;или метки (WORD, BYTE, NEAR)
ANV EQU START+1; (смещение+число - число)
TXT EQU <TEXXXT>;Текстовое символьное имя (TEXT)
NUM=2;Число
NUME EQU 2;Число
; ТИПЫВЫРАЖЕНИЯ ДЛЯ +-:
EXN1=2+4;Число Оба операнда числа - число!
EXN2=NUM+EXN1;Число Оба операнда числа - число!
EXW1=EXN2+ABC;WORD Один число,другой смещение - смещение!
EXN3=CDE-ABC;Число!!! Оба операнда смещения - число!
;EXN4=CDE+CDE;Ошибка Нельзя складывать смещения!!!
;EX=LAB-CDE;Ошибка Нельзя брать операнды из разных сегментов!!!
EXB1=CDE-ABC+CDE;BYTE
;EX=2-(CDE+ABC);Ошибка Нельзя складывать смещения!!!
EXN5=2-(CDE-ABC);Число
;EX=2-CDE+ABC;Ошибка Нельзя вычесть из числа смещение!!!;
;EX=CDE+ABC;Ошибка Нельзя складывать смещения!!!
;EX=2-CDE;Ошибка Нельзя вычесть из числа смещение!!!
;EX=CDE+ABC-CDE;Ошибка Нельзя вычесть из числа смещение!!!
;ОСТАЛЬНЫЕ АРИФМЕТИЧЕСКИЕ ОПЕРАТОРЫТОЛЬКО ДЛЯ ЧИСЕЛ!!!:
EXN6=EXN1*2
EXN7 EQU EXN6/2
code segment
assume cs:code,ds:data
start:
mov ax,data
mov ds,ax
lea dx,CDE
mov ah,09h
int 21h
LAB:
mov ah,4Ch
int 21h
code ends
stack segment stack
sttt dw 64 dup(?)
stack ends
end start
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; EX10: СТРОКИ СИМВОЛОВ В ПАМЯТИ И РЕГИСТРАХ
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
include userv.mac
data segment
; Строковая константа, заданная с помощью DB располагаеся в памяти
; в порядке написания. Заданная с помощью DW располагается "задом
; на перед".
;
xbyte db 'abcdefgh';-память: 61 62... ('a' 'b'...)
xword dw '12';-память: 32 31 ('2' '1')
buf db 11, 11 dup(?);-буфер для системного ввода
data ends
code segment
assume cs:code,ds:data
start:
mov ax,data
mov ds,ax
u_msg <13,10,'Примеры:',13,10>
u_show_byte xbyte,8,'Вывод поля из 8 байт, начиная с xbyte:'
u_msg
u_show_word xword,,'Слово xword с символами "12":'
mov ax,xword
u_msg
u_show_ax 'Регистр после mov ax,xword:'
mov ax,'12'
u_msg
u_show_ax 'Регистр после mov ax,"12":'
u_msg <13,10,10,'Пробуем сами:'>
rpt:
u_key_str buf,<13,10,'Введите строку до 10 символов (пустой Enter-конец): '>
cmp byte ptr buf+1,0
jne cont
jmp final
cont:
u_show_byte buf+2,buf+1,<13,10,'Так она выглядит в памяти:',13,10>
jmp rpt
final:
mov ah,4ch
int 21h
code ends
stack segment stack
dw 64 dup(?)
stack ends
end start
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; EX11: ПЕРЕСЫЛКА СТРОКИ СИМВОЛОВ
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
include userv.mac
data segment
len db?;длина входной строки
from db 80 dup(?);буфер входной строки (оригинала)
to db 80 dup(?);первая выходная строка
to2 db 80 dup(?);вторая выходная строка
data ends
code segment
assume cs:code,ds:data
start:
mov ax,data
mov ds,ax; DS:SI -адрес оригинала
mov si,offset from;
mov es,ax; ES:DI -адрес первой копии
mov di,offset to;
u_key_char from,len,<13,10,'Введите строку до 80 символов',13,10>
; Первая копия:
cld; (DF)=0 - направление ->
mov cx,0; счетчик
mov cl,len;
rpt:
movsb; пересылка обычным циклом
loop rpt
u_show_char to,len,<13,10,"Это ее копия:",13,10>
; Вторая копия:
std; (DF)=1 - направление <-
mov cx,0; счетчик
mov cl,len;
dec si; указатель на конец оригинала
mov di,offset to2+79; указатель на конец второй копии
rep movsb; пересылка с префиксным повторителем
u_show_char to2,80,<13,10,"Еще одна копия:",13,10>
mov ah,4ch
int 21h
code ends
stack segment stack
dw 64 dup(?)
stack ends
end start
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; EX12: ПОИСК ПРОБЕЛА В СТРОКЕ СИМВОЛОВ
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
include userv.mac
data segment
len db?;длина строки
str db 80 dup(?);буфер строки
data ends
code segment
assume cs:code,ds:data
start:
mov ax,data
mov ds,ax
mov es,ax;сегментный адрес для SCASB
repto:;ввод и определение длины строки
u_key_char str,len,<13,10,'Введите строку до 80 символов',13,10>
mov al,len
cbw
cmp al,0
jne work
jmp fin
work:
u_show_bin <13,10,'Длина строки:'>
cld;направление DF=0
mov di,offset str;указатель строки
mov ax,2;
cmp ax,1;ZF=0 перед REPNE
mov cx,0;установка счетчика
mov cl,len;
mov al,' ';искомый пробел
repne scasb;поиск пробела
jne not_fnd;ZF=O после SCASB -пшробел не найден, обход.
mov al,len;вычисление позиции пробела:
cbw; (ax)=len-cx
sub ax,cx;
u_show_bin <13,10,"Позиция пробела: ">
jmp repto
not_fnd:
u_msg <13,10,"Нет пробела!">
jmp repto
fin:
mov ah,4ch
int 21h
code ends
stack segment stack
dw 64 dup(?)
stack ends
end start
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; EX13: СРАВНЕНИЕ СТРОК
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
include userv.mac
data segment
len1 db?;длина строки 1
str1 db 80 dup(?);буфер строки 1
len2 db?;длина строки 2
str2 db 80 dup(?);буфер строки 2
data ends
code segment
assume cs:code,ds:data
start:
mov ax,data
mov ds,ax
doit:
;ввод и определение длины строки 1
u_key_char str1,len1,<13,10,'Введите строку-1 до 80 символов',13,10>
mov al,len1
cbw
cmp al,0
jne work
jmp fin
work:
u_show_bin <13,10,'Длина строки-1:'>
;ввод и определение длины строки 2:
u_key_char str2,len2,<13,10,'Введите строку-2 до 80 символов',13,10>
mov al,len2
cbw
cmp al,0
jne work1
jmp fin
work1:
u_show_bin <13,10,'Длина строки-2:'>
mov al,len1
cmp al,len2
jne strne
mov ax,data
mov es,ax
mov si,offset str1
mov di,offset str2
cld;направление DF=0
mov cx,0
mov cl,len1
repe cmpsb
je streq
strne:
u_msg <13,10,'Строки не равны'>
jmp doit
streq:
u_msg <13,10,'Строки равны'>
jmp doit
fin:
mov ah,4ch
int 21h
code ends
stack segment stack
dw 64 dup(?)
stack ends
end start
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; EX14: ближняя процедура с двумя параметрами (по значению)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
include userv.mac
code segment
assume cs:code
subr proc; z=x+y
push bp; сохранили BP
mov bp,sp; записали в него SP-положение вершины стека
push ax; прочие сохранения
push bx
mov ax,[bp+4]; y->AX -параметры из стека, не изменяя SP
mov bx,[bp+6]; x->BX
add ax,bx; z=x+y ->AX -проблемная часть
mov [bp+4],ax; AX -> STACK -результат в стек, не изменяя SP
pop bx; прочие восстановления
pop ax
pop bp; восстановили BP
ret; вернулись
subr endp
start:
mov ax,sp
u_show_ax <13,10,'Вершина стека:'>
u_key_bin <13,10,'Введите X:'>
mov bx,ax
u_key_bin <13,10,'Введите Y:'>
PUSH BX; x 1-й входной параметр в стек
PUSH AX; y 2-й входной параметр в стек
CALL SUBR; вызов процедуры
POP AX; результат из стека в AX (и удаление 2-го
; параметра.)
ADD SP,2; удаление 1-го параметра
u_show_bin <13,10,'Получился Z=X+Y='>
mov ax,sp
u_show_ax <13,10,'Вершина стека:'>
mov ah,4ch
int 21h
code ends
stack segment stack
dw 64 dup(?)
stack ends
end start
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; EX15: ближний вызов без процедуры (аналог EX13 с помеченной п/п)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
include userv.mac
data segment
db?
data ends
code segment
assume cs:code,ds:data
subr:; псевдоподпрограмма
push bp; сохранили BP
mov bp,sp; записали в него SP-положение вершины стека
push ax; прочие сохранения
push bx
mov ax,[bp+4]; адрес символатека, не изменяя SP
mov bx,[bp+6]; x->BX
add ax,bx; z=x+y ->AX -проблемная часть
mov [bp+6],ax; AX -> STACK -результат в стек, не изменяя SP
pop bx; прочие восстановления
pop ax
pop bp; восстановили BP
ret 2; вернулись с удаление лишнего параметра
start:
mov ax,data
mov ds,ax
mov ax,sp
u_show_ax <13,10,'Вершина стека:'>
u_key_bin <13,10,'Введите X:'>
mov bx,ax
u_key_bin <13,10,'Введите Y:'>
PUSH BX; x 1-й входной параметр в стек
PUSH AX; y 2-й входной параметр в стек
CALL SUBR; переход к подпрограмме
POP AX; результат из стека в AX (и удаление 2-го пар.)
u_show_bin <13,10,'Получился Z=X+Y='>
mov ax,sp
u_show_ax <13,10,'Вершина стека:'>
mov ah,4ch
int 21h
code ends
stack segment stack
dw 64 dup(?)
stack ends
end start
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; EX16: ближняя процедура с тремя параметрами (по адресу)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
include userv.mac
data segment;
x dw?; параметры; ¦ BP ¦ 5)push bp
y dw?; в сегменте; ¦ IP ¦ 4)call subr
z dw?; данных; ¦ AdZ ¦ 3)push...
data ends; ¦ AdY ¦ 2)push...
code segment; ¦ AdX ¦ 1)push...
assume cs:code,ds:data;
subr proc; процедура SUBR(x,y,z): z=x+y
; запоминание вершины стека:
push bp; сохранили BP
mov bp,sp; записали в него SP-положение вершины
; стека
; сохранение прочих регистров:
push ax
push bx
; настройка параметров:
mov si,[bp+8];адрес X -
mov ax,[si];знач. X ¦ входные
mov si,[bp+6];адрес Y ¦
mov bx,[si];знач. Y --
mov si,[bp+4];адрес Z выходной
; проблемная часть:
add ax,bx; (AX)+(BX)->(AX)
mov [si],ax; (AX) -> Z
; восстановление регистров:
pop bx; прочие восстановления
pop ax;
pop bp; восстановили BP
ret 6; вернулись, обойдя три слова в стеке
subr endp
start:
mov ax,data
mov ds,ax
u_show_r16 sp,<13,10,'Вершина стека:'>
u_key_bin <13,10,'Введите X:'>
mov x,ax
u_key_bin <13,10,'Введите Y:'>
mov y,ax
; подготовка адресов параметров в стеке:
MOV AX,OFFSET X
PUSH AX
MOV AX,OFFSET Y
PUSH AX
MOV AX,OFFSET Z
PUSH AX
; вызов процедуры:
CALL SUBR
mov ax,z
u_show_bin <13,10,'Получился Z=X+Y='>
u_show_r16 sp,<13,10,'Вершина стека:'>
mov ah,4ch
int 21h
code ends
stack segment stack
dw 64 dup(?)
stack ends
end start
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; EX17: ближняя процедура с тремя параметрами(по дальнему адресу)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
include userv.mac; ------
; ¦ BP ¦ 8)push bp BP
data segment; ¦ IP ¦ 7)call subr BP+2
x dw?; параметры; ¦ AdZ ¦ 6)push... BP+4
y dw?; в сегменте; ¦ DS ¦ 5)push dx BP+6
z dw?; данных; ¦ AdY ¦ 4)push... BP+8
data ends; ¦ DS ¦ 3)push dx BP+10
code segment; ¦ AdX ¦ 2)push... BP+12
assume cs:code,ds:data; ¦ DS ¦ 1)push dx BP+14
; -------
subr proc; процедура SUBR(x,y,z): z=x+y
; запоминание вершины стека:
push bp; сохранили BP
mov bp,sp; записали в него SP-положение вершины стека
; сохранение прочих регистров:
push ax
push bx
; настройка параметров:
LDS si,[bp+12];адрес X -
mov ax,[si];знач. X ¦ входные
LDS si,[bp+8];адрес Y ¦
mov bx,[si];знач. Y --
LDS si,[bp+4];адрес Z выходной
; проблемная часть:
add ax,bx; (AX)+(BX)->(AX)
mov [si],ax; (AX) -> Z
; восстановление регистров:
pop bx; прочие восстановления
pop ax;
pop bp; восстановили BP
ret 12; вернулись, обойдя 6слов в стеке (3 по 4)
subr endp
start:
mov ax,data
mov ds,ax
u_show_r16 sp,<13,10,'Вершина стека:'>
u_key_bin <13,10,'Введите X:'>
mov x,ax
u_key_bin <13,10,'Введите Y:'>
mov y,ax
; подготовка адресов параметров в стеке:
MOV AX,OFFSET X
PUSH DS
PUSH AX
MOV AX,OFFSET Y
PUSH DS
PUSH AX
MOV AX,OFFSET Z
PUSH DS
PUSH AX
; вызов процедуры:
CALL SUBR
mov ax,z
u_show_bin <13,10,'Получился Z=X+Y='>
u_show_r16 sp,<13,10,'Вершина стека:'>
mov ah,4ch
int 21h
code ends
stack segment stack
dw 64 dup(?)
stack ends
end start
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; EX18-EX18A: МЕЖМОДУЛЬНЫЕ ССЫЛКИ (ДАННЫЕ И МЕТКИ).
; Каждый файл-модуль отдельно транслируется: MASM EX18;
; MASM EX18A;
; Оба модуля совместно линкуются: LINK EX18 EX18A;
; Программа запускается: EX18
; Пользуйтесь процедурой М18,
; которая все это сделает сама.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Главный модуль EX18.ASM
; Глобальные имена:
PUBLIC FINISH,STR,START;-Эти имена определены в данном
; модуле, но на них можно
; ссылаться из других модулей.
; Внешнее имя"
EXTRN PRINT:NEAR;-Данный модуль пользуется
; этим именем, хотя оно в нем
; не определялось; оно опреде-
; лено в другом модуле.
data segment
STR db "Строка STR определена в одном модуле,";-глобальные
db " а печатается в другом.$"; данные
data ends
code segment byte public 'code';-свойства BYTE и PUBLIC необхо-
; димы для связывания сегментов
; кода из разных модулей
assume cs:code,ds:data
START:; глобальная метка
mov ax,data
mov ds,ax
jmp PRINT; переход на внешнюю метку (в другой модуль)
FINISH:; глобальная метка
mov ah,4ch
int 21h
code ends
stack segment stack
dw 64 dup(?)
stack ends
end; нет указателя имени входа
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; EX18A-EX18: МЕЖМОДУЛЬНЫЕ ССЫЛКИ (ДАННЫЕ И МЕТКИ).
; Каждый файл-модуль отдельно транслируется: MASM EX18;
; MASM EX18A;
; Оба модуля совместно линкуются: LINK EX18 EX18A;
; Программа запускается: EX18
; Пользуйтесь процедурой М18,
; которая все это сделает сама.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Вспомогательный модуль EX18а.ASM
include userv.mac
; Глобальное имя:
PUBLIC PRINT;-Это имя определено в данном
; модуле, но на него можно
; ссылаться из других модулей.
; Внешние имена
EXTRN FINISH:NEAR,STR:BYTE,START:NEAR
;-Данный модуль пользуется
; этими именами, хотя они в нем
; не определялись; они опреде-
; лено в другом модуле.
code segment byte public 'code';-свойства BYTE и PUBLIC необхо-
; димы для связывания сегментов
; кода из разных модулей
assume cs:code;-локальных данных нет, поэтому
; нет сегмента данных
PRINT:; глобальная метка
u_show_std str
jmp FINISH; переход на внешнюю метку (в другой модуль)
code ends
end START; ссылка на внешнюю метку - объявление
; точки входа, находящейся в другом модуле!
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; EX19-EX19A: вызов внешней ближней процедуры.
; Каждый файл-модуль отдельно транслируется: MASM EX19;
; MASM EX19A;
; Оба модуля совместно линкуются: LINK EX19 EX19A;
; Программа запускается: EX19
; Пользуйтесь процедурой М19,
; которая все это сделает сама.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
include userv.mac
EXTRN SUBR:NEAR; внешнее имя ближней процедуры
data segment; ------
x dw?; параметры; ¦ BP ¦ 5)push bp
y dw?; в сегменте; ¦ IP ¦ 4)call subr
z dw?; данных; ¦ AdZ ¦ 3)push...
data ends; ¦ AdY ¦ 2)push...
code segment byte public 'code'; ¦ AdX ¦ 1)push...
assume cs:code,ds:data; -------
start:
mov ax,data
mov ds,ax
u_key_bin <13,10,'Введите X:'>
mov x,ax
u_key_bin <13,10,'Введите Y:'>
mov y,ax
; подготовка адресов параметров в стеке:
mov ax,offset x
push ax
mov ax,offset y
push ax
mov ax,offset z
push ax
; вызов внешней процедуры:
CALL SUBR
mov ax,z
u_show_bin <13,10,'Получился Z=X+Y='>
mov ah,4ch
int 21h
code ends
stack segment stack
dw 64 dup(?)
stack ends
end start
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; EX19A: ВНЕШНЯЯ БЛИЖНЯЯ ПРОЦЕДУРА ДЛЯ EX19
; Каждый файл-модуль отдельно транслируется: MASM EX19;
; MASM EX19A;
; Оба модуля совместно линкуются: LINK EX19 EX19A;
; Программа запускается: EX19
; Пользуйтесь процедурой М19,
; которая все это сделает сама.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PUBLIC SUBR; глобальное имя
code segment byte public 'code'
assume cs:code
SUBR proc; -процедура SUBR(x,y,z): z=x+y,
; передача параметров по ближнему
; адресу
; запоминание вершины стека:
push bp;сохранили BP
mov bp,sp;записали в него SP-положение вершины стека
; сохранение прочих регистров:
push ax
push bx
; настройка параметров:
mov si,[bp+8];адрес X -
mov ax,[si];знач. X ¦ входные
mov si,[bp+6];адрес Y ¦
mov bx,[si];знач. Y --
mov si,[bp+4];адрес Z выходной
; проблемная часть:
add ax,bx; (AX)+(BX)->(AX)
mov [si],ax; (AX) -> Z
; восстановление регистров:
pop bx; прочие восстановления
pop ax;
pop bp; восстановили BP
ret 6; вернулись, обойдя три слова в стеке
subr endp
code ends
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; EX20-EX20A: ВЫЗОВ ВНЕШНЕЙ ДАЛЕКОЙ ПРОЦЕДУРЫС ДАЛЕКИМИ АДРЕСАМИ
; ПАРАМЕТРОВ.
; Каждый файл-модуль отдельно транслируется: MASM EX20;
; MASM EX20A;
; Оба модуля совместно линкуются: LINK EX20 EX20A;
; Программа запускается: EX20
; Пользуйтесь процедурой М20,
; которая все это сделает сама.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
include userv.mac
EXTRN SUBR:FAR; внешнее имя дальней процедуры f(x,y)
data segment
x dw?; 1-й параметр в сегменте данных
data ends
main segment
assume cs:main,ds:data
y dw?; 2-й параметр в сегменте кода
start:
mov ax,data
mov ds,ax
u_key_bin <13,10,'Введите X:'>
mov x,ax
u_key_bin <13,10,'Введите Y:'>
mov y,ax
; подготовка адресов параметров в стеке:
mov ax,offset x; далекий адрес 1-го
push ds; параметра (в сегменте
push ax; данных)
mov ax,offset y; далекий адрес 2-го
push cs; параметра (в сегменте
push ax; кода)
; вызов внешней процедуры:
CALL FAR PTR SUBR
mov ax,y
u_show_bin <13,10,'Получился X+Y='>
mov ah,4ch
int 21h
main ends
stack segment stack
dw 64 dup(?)
stack ends
end start
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; EX20A: ВНЕШНЯЯ ДАЛЬНЯЯ ПРОЦЕДУРА ДЛЯ EX20
; Каждый файл-модуль отдельно транслируется: MASM EX20;
; MASM EX20A;
; Оба модуля совместно линкуются: LINK EX20 EX20A;
; Программа запускается: EX20
; Пользуйтесь процедурой М20,
; которая все это сделает сама.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PUBLIC SUBR; -глобальное имя внешней процедуры
code segment; -этот сегмент отличается от вызывающего,
assume cs:code; тот называется MAIN
SUBR proc FAR; -процедура SUBR(x,y): y=x+y,
; передача параметров по дальнему
; адресу
; запоминание вершины стека:
push bp; сохранили BP
mov bp,sp; записали в него SP-положение вершины стека
; сохранение прочих регистров:
push ax
push bx
push si
; настройка параметров:
lds si,[bp+10];адрес X -
mov ax,[si];знач. X ¦ входные
lds si,[bp+6];адрес Y ¦
mov bx,[si];знач. Y --
; проблемная часть:
add ax,bx; (AX)+(BX)->(AX)
mov [si],ax; (AX) -> Y
mov bx,si
; восстановление регистров:
pop si;
pop bx; прочие восстановления
pop ax;
pop bp; восстановили BP
RET 8; вернулись, обойдя четыре слова в стеке
subr endp
code ends
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; EX21: Далекая процеура - обращение к DOS (int 21h)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Процедура KEY возвращает строку, введенную с пульта с помощью
; INT 21h Fn01h и дополненную ограничителем "$".
; Процедура SHOW выводит эту строку с помошью INT 21h Fn02h.
; Вызываюшая часть находится в сегменте MAIN,процедуры в сегменте
; SUBR, а данные в сегменте DATA.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
include userv.mac
data segment
str db 80 dup(?);буфер строки
data ends
main segment;коды основной программы
assume cs:main,ds:data
start:
mov ax,data
mov ds,ax
u_msg <13,10,"Введите строку",13,10>
mov ax,offset str;дальний адрес параметра в стек
push ds
push ax
CALL FAR PTR KEY;вызов
u_msg <13,10,"Введено:",13,10>
mov ax,offset str;дальний адрес параметра в стек
push ds
push ax
CALL FAR PTR SHOW;вызов
mov ah,4ch
int 21h
main ends
subr segment;коды подпрограммы
assume cs:subr
KEY PROC FAR;процедура F(str)
push bp;сохранения
mov bp,sp
push ds
push ax
push si
lds si,[bp+6];адрес параметра-строки
more:
MOV AH,01H;функция чтения: символ->(al)
INT 21H
mov [si],al
inc si
cmp al,13
jne more;если не Enter,то повторить,
mov byte ptr[si],"$";иначе послать признак конца
pop si;восстановление
pop ax
pop ds
pop bp
ret 4;возврат
key endp
SHOW PROC FAR;процедура F(str)
push bp;сохранения
mov bp,sp
push es
push dx
push di
les di,[bp+6];адрес параметра-строки
againe:
mov dl,byte ptr[di]
cmp dl,"$"
je exit
MOV AH,02H;функция: (al)->символ
INT 21H
inc di
jmp againe
exit:
pop di;восстановление
pop dx
pop es
pop bp
ret 4;возврат
show endp
subr ends
stack segment stack
dw 64 dup(?)
stack ends
end start
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; EX22: ПОЛЬЗОВАТЕЛЬСКИЙ ОБРАБОТЧИК ПРЕРЫВАНИЯ.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
include userv.mac
data segment
str db 80 dup(?);какие то данные
data ends
code segment;коды основной программы
assume cs:code,ds:data
usint:
; Подпрограмма пользовательской обработки прерывания:
U_MSG <13,10,'***Пользовательская бработка прерывания 12H!!!'>
IRET
start:
mov ax,data
mov ds,ax
; Узнать и сохранить старый вектор прерывания 12H:
mov al,12h;-тип прерывания
mov ah,35h;-функция DOS 35h
int 21h;-ES:BX=адрес старого обработчика
push es; сохраняется в стеке
push bx;
; Изменить вектор прерывания (указать на USINT):
push ds;-сохранение DS
mov ax,cs;-адрес пользовательского
mov ds,ax; обработчика
mov dx,offset usint; в DS:DX
mov al,12h;-тип прерывания
mov ah,25h;-фумкция DOS 25h
int 21h
pop ds;-восстановление DS
; Пользовательская обработка:
INT 12H
; Восстановить старый вектор прерывания 12H:
mov bx,ds;-сохранение DS
pop dx;-адрес старого обработчика
pop ds; восстанавливается из стека
mov al,12h;-тип прерывания
mov ah,25h;-фумкция DOS 25h
int 21h
mov ds,bx;-восстановление DS
; Стандартная обработка:
int 12h
U_MSG <13,10,'***Стандартная обработка int 12h:'>
U_SHOW_BIN <13,10,' Основной памяти, Кб:'>
mov ah,4ch
int 21h
code ends
stack segment stack
dw 64 dup(?)
stack ends
end start
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;EX23: Повторяемые блоки REPT, IRP, IRPC.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
include userv.mac
stack segment stack
dw 64 dup('**')
stack ends
data segment
stro db '.БлокREPT.'
fix db?
data ends
; Сегмент кода:
code segment
assume cs:code,ds:data
start:
mov ax,data
mov ds,ax
;Строка из памяти выводится посимвольно повторением
;DOS Fn02h с помощью REPT-блока
ind=0
REPT fix-stro;количество повторений
mov ah,02h
mov dl,stro[ind]
int 21h
ind=ind+1
ENDM
;Строка задана как список символов-параметров блока IRP
IRP par,<.,Б,л,о,к,I,R,P,.>; <>-обязятельны
mov dl,'&par';&-параметр внутри текст.конст.
mov ah,02h
int 21h
ENDM
;Строка задана как один параметр блока IRP
IRPC SYM,<.БлокIRPC.>; <>-из-за русских букв
mov dl,'&sym'
mov ah,02h
int 21h
ENDM
mov ah,4ch
int 21h
code ends
end start
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;dx01: диски-файлы средствами DOS:
; FAT - сколько места;
; DTA - поиск файлов.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
include userv.mac
data segment
filemask db '*.*'; -маска для поиска файлов- все
dta db 44 dup (?); -область DTA
data ends