Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
27
Добавлен:
20.06.2014
Размер:
1.08 Mб
Скачать

Int 21h ;системного прерывания 21h

code ends ;конец сегмента команд

end main ;конец основной программы

Использование дальней подпрограммы

Следующая программа иллюстрирует использование подпрограммы, находящейся в отдельном сегменте. Такая подпрограмма называется дальней. Для простоты подпрограмма осуществляет наложение маски на число, т.е. маскирование заданных битов в исходных данных.

Поскольку при дальнем вызове содержимое сегментного регистра кода CS изменяется, то адрес возврата представляет собой пару сегмент:смещение (CS:IP).

Параметры передаются подпрограмме через стек. Указатель базы указывает на кадр параметров с младшего адреса.

;MaskPF.asm

;программа наложения маски на число

;наложение выполняет подпрограмма, находящаяся в отдельном сегменте

;сегмент стека

stck segment stack

dw 10h dup(0) ;16 слов, инициализированных нулем

stck ends

;сегмент данных

data segment

m dw 2 dup(0F0Fh), 2 dup(0F0F0h) ;маска

X dw 0aabBh, 0abbAh, 0baaBh, 0bbaAh ;исходные данные

y dw 4 dup(?) ;результаты

data ends

;сегмент кода подпрограмма наложения маски

PrcCode segment

maskp proc far

mov bp, sp ;направление указателя базы на верхушку стека

add bp, 4 ;направление указателя базы на кадр параметров

mov ax, [bp] ;передача в аккумулятор исходного значения

and ax, [bp+2] ;наложение маски на исходное значение

ret 2*2 ;возврат из подпрограммы с очисткой стека

maskp endp ;конец подпрограммы наложения маски

PrcCode ends ;конец сегмента подпрограммы

;сегмент кода с основной программой

MCode segment

assume cs:MCode, ds:data, es:data, ss:stck

main: mov dx, data ;точка входа в программу

mov ds, dx ;инициализация регистра сегмента данных

mov es, dx ;инициализация регистра ES

xor si, si ;инициализация индекса источника

lea di, y ;инициализация индекса приемника

mov cx, 4 ;инициализация счетчика цикла

;цикл чтения исходных данных, передачи их подпрограмме

;и записи результатов

mloop: push m[si] ;помещение в стек очередной маски

push x[si] ;помещение в стек очередного исходного значения

add si, 2 ;направление SI на следующую пару

call maskp ;вызов подпрограммы наложения маски

stosw ;размещение результата

loop mloop ;команда управления циклом

mov ax, 4C00h ;функция завершения программы

int 21h ;системного прерывания 21h

MCode ends ;конец сегмента команд

end main ;конец основной программы

Использование подпрограмм для ввода-вывода

Следующая программа осуществляет ввод исходных данных с клавиатуры с помощью подпрограммы.

Используется также еще одна подпрограмма, осуществляющая преобразование исходных данных, которые передаются ей через стек. Для простоты преобразование заключается в маскировании заданных битов в вводимых числах.

;MaskIO.asm

;наложение маски на числа, вводящиеся к клавиатуры,

;и вывод результатов на дисплей

;сегмент стека

stck segment stack

dw 10h dup(0) ;16 слов, инициализированных нулем

stck ends

;сегмент данных

data segment

m dw 0F0F0h ;маска

x dw 4 dup(?) ;исходные данные

y dw 4 dup(?) ;результаты

data ends

;сегмент команд

code segment

assume cs:code, ds:data, ss:stck

;подпрограмма ввода исходных данных с клавиатуры

inpp proc

;сохранение регистров, изменяемых подпрограммой, в стеке

push dx

push cx

push ax

;инициализация приемника вводимого числа и счетчика цикла

xor dx, dx ;в DX будет формироваться вводимое число

mov cx, 10h ;счетчик битов вводимого числа

;цикл ввода

inloop: in al, 60h ;чтение скан-кода клавиши из порта 60h

cmp al, bl ;сравнение с предыдущим скан-кодом,

;если не равно, то клавиша отжата

je inloop ;цикл повторяется, пока клавиша не будет отжата

mov bl, al ;скан-код в BL для последующего сравнения

cmp al, 01h ;скан-код клавиши Esc

jne NotEsc

jmp quit

NotEsc: cmp al, 02h ;скан-код клавиши 1

je num1

cmp al, 0Bh ;скан-код клавиши 0

jne inloop

shl dx, 1 ;в очередной разряд числа записан введенный 0

mov es:[di], 0730h ;и выведен на экран в качестве эха

jmp NxtNum ;переход к вводу следующей цифры

num1: shl dx, 1 ;если введена 1

or dx, 1 ;то она записана в очередной разряд

mov es:[di], 0731h ;и выведена на экран в качестве эха

NxtNum: inc di

inc di ;смещение в видеопамяти на следующий символ

dec cx ;декремент счетчика битов

jnz inloop ;если еще не все цифры введены,

;ввод следующей цифры

mov ds:[si], dx ;если все цифры введены, число записывается

;в область памяти исходных данных

;восстановление измененных регистров и возврат из подпрограммы

pop ax

pop cx

pop dx

ret

inpp endp ;конец подпрограммы ввода с клавиатуры

;подпрограмма наложения маски

maskp proc ;начало подпрограммы наложения маски

mov bp, sp ;направление указателя базы на верхушку стека

add bp, 2 ;направление указателя базы на параметр

and ax, [bp] ;наложение маски на исходное значение

ret 2 ;возврат из подпрограммы с очисткой стека

maskp endp ;конец подпрограммы наложения маски

;главная программа

main:

;подготовка к очистке экрана

mov dx, 0B800h ;база видеопамяти

mov es, dx ;дополнительный сегмент - видеопамять

xor di, di ;смещение в видеопамяти - левая верхняя позиция

;очистка экpана

mov ax, 0720h

mov cx, 80*25 ;размер видеопамяти одного экрана в словах

rep stosw ;цикл заполнения экрана пробелом

;инициализация регистров для ввода числа

mov dx, data ;в DX база сегмента данных

mov ds, dx ;инициализация регистра сегмента данных

xor di, di ;снова на начало видеопамяти

lea si, x ;инициализация индекса источника смещением

;первого числа из области исходных данных

mov cx, 4 ;инициализация счетчика числом исходных данных

;цикл ввода исходных данных (значений переменной x)

ixloop: call inpp ;вызов подпрограммы ввода исходных данных

add si, 2

add di, 2

loop ixloop

;инициализация регистров перед главным циклом

mov es, dx

lea si, x ;инициализация индекса источника

lea di, y ;инициализация индекса приемника

mov cx, 4 ;инициализация счетчика цикла

;главный цикл

mloop: push m ;помещение в стек маски

lodsw ;загрузка аккумулятора исходным значением

call maskp ;вызов подпрограммы наложения маски

stosw ;размещение результата

loop mloop ;команда управления циклом

;инициализация регистров перед циклом вывода результатов на экран

mov dx, 0B800h ;база видеопамяти

mov es, dx ;дополнительный сегмент - сегмент видеопамяти

lea si, y ;индекс источника - смещение первого числа

;из области результатов

mov di, 80*2 ;индекс приемника - начало второй строки

mov cx, 4 ;счетчик цикла - количество выводимых чисел

;цикл вывода результатов на экран

obloop: lodsw

mov bx, 8000h

olloop: test ax, bx

jnz bit1

mov es:[di], 0730h

jmp NxtBit

bit1: mov es:[di], 0731h

NxtBit: inc di

inc di

shr bx, 1

jnc olloop

mov es:[di], 0720h

inc di

inc di

loop obloop

pause: in al, 60h

cmp al, 01h

jne pause

quit: mov ax, 4C00h

int 21h

code ends

end main

Соседние файлы в папке Задания к лабораторным