ПРИМЕРЫ ПРОГРАММ НА MASM




 

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

 

; Сег<



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2016-02-16 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: