
- •Программирование эвм
- •Int 21h ;кодом возврата 0 прерывания 21h
- •Работа с битами
- •Порядок выполнения работы
- •Устройства ввода-вывода
- •Ввод исходных данных с клавиатуры и вывод результатов на дисплей
- •Inc di ;смещение в видеопамяти на следующий символ
- •Порядок выполнения работы
- •Контрольные задания
- •Система команд процессора
- •Способы адресации
- •Влияние команд на регистр флагов
- •Расширенные регистры и типы данных процессоров x86
- •Система команд процессоров ia-32 и Intel 64
- •Int 21h ;системного прерывания 21h
- •Использование дальней подпрограммы
- •X dw 0aabBh, 0abbAh, 0baaBh, 0bbaAh ;исходные данные
- •Использование подпрограмм для ввода-вывода
- •Порядок выполнения работы
- •Контрольные задания
- •Дескрипторы
- •Порядок работы процессора в защищенном режиме
- •Использование дальней подпрограммы в защищенном режиме
- •Использование idt. Ввод данных с клавиатуры в защищенном режиме
- •Порядок выполнения работы
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