Автор: Пользователь скрыл имя, 26 Сентября 2011 в 00:48, контрольная работа
Механизм шлюзов для передачи управления на сегменты кода с другими уровнями привилегий
;*****************************
;**** Ввод символа
с клавиатуры в регистр AL ******************************
;*****************************
GetKey: ; метка подпрограммы вводва символа
Mov ah, 1 ; код функции "проверка готовности"
Int 16h ; обращение к BIOS
Jz GetKey ; символ не введён, возвращаемся на начало
Xor ah, ah ; код функции "чтение символа в AL"
Int 16h ; обращение к BIOS
Cmp al, '0' ; код символа < кода нуля?
jb nodig ; -> да, символ не цифра
cmp al, '9' ; код символа > кода девятки?
ja nodig ; -> да, символ не цифра
clc ; символ - цифра, C=0
jmp massiv_in ; возврат на вызывающий модуль
nodig: ; метка
stc ; символ - не цифра, C=1
obrabotka: ; метка
jc _nodigit ; если символ - не цифра, идём на соответствующую ; ему обработку
;*****************************
;***** Ввод и "редактирование"
нововводимого элемента
;*****************************
Massiv_in: ; метка куска программы для ввода элемента массива
Xor bl, bl ; обнуляем регистр bl
Mov _flag,bl ; заносим 0 в регистр флага (снимаем признак ; введённого пробела)
Call OutSym ; вызываем эхоотображение символа
Mov bl, 30h ; заносим в bl число 30h
Xor ah, ah ; обнуляем старшую часть регистр ax
Sub al, bl ; получаем из ASCII кода число
Push ax ; сохраняем его в стеке
Xor dx, dx ; обнуляем регистр dx
Mov SI,_counter ; Заносим номер числа для работы с числом массива
Mov AX, In_massiv[SI] ; Заносим в AX элемент массива, с которым теперь
; будем работать
Mov BX, 10 ; Заносим в регистр bx число 10
Mul BX ; Умножаем регистр с элементом на десять
Pop bx ; восстанавливаем из стека в регистр bx
; нововведённую цифру
Add AX,BX ; прибавляем к элементу массива нововведённое
; число
Cmp dx,0 ; сравниваем старшую часть произведения с 0
Ja bigdigit ; если больше 0, то идём на обработку
; слишком большого числа; а также
Cmp ax,10000 ; сравниваем элемент массива с 10000
Ja bigdigit ; если получившееся число больше 10000, то идём на
; обработку слишком большого числа; иначе
Mov In_massiv[SI],AX ; Заносим обратно в массив элемент, с которым
; работали
Jmp GetKey ; идём на подпрограмму ожидания ввода символа
Bigdigit: ; метка подпрограммы обработки слишком большого
; числа
Push ax ; сохраняем в стеке регистр ax
Mov al,08 ; заносим в регистр al код символа BackSpace
call OutSym ; вызываем подпрограмму вывода символа на экран
mov al, 20h ; заносим в регистр al код символа Space
call Outsym ; вызываем подпрограмму вывода символа на экран
Mov ah, 1 ; делаем признак введённого пробела
Mov _flag, ah ;
pop ax ; сохраняем из стека регистр ax
sub ax, bx ; вычитаем из элемента массива нововведённое число
mov bx, 10 ; заносим в регистр bx число 10
div bx ; делим элемент массива на 10
Mov In_massiv[SI],AX ; Заносим обратно в массив элемент, с которым
Inc _counter ; дважды
Inc _counter ; инкрементируем счётчик элементов, и
Jmp GetKey ; идём на ожидание нажатия очередной клавиши
;*****************************
;**** Обработка символов,
которые не цифры *************
;*****************************
_nodigit: ; метка подпрограммы
Cmp al, 1Bh ; введён символ Esc ?
Jnz _nodigit1 ; идём дальше, если не Esc
int 20h ; если Esc, то выходим из программы
_nodigit1: ; просто метка "дальше"
Cmp ah, 1Ch ; введён символ Enter?
Jnz _nodigit2 ; нет; идём на метку
Mov ah, _flag ; проверяем признак введённого пробела
Cmp ah, 0 ;
Jne _nodigit1_1 ; если введён, то пропускаем, иначе
Inc _counter ; дважды
Inc _counter ; инкрементируем счётчик элементов,
_nodigit1_1:
mov ah, 9 ; делаем
lea dx,AbzacMessage ; "абзац"
int 21h ; и
Jmp Massiv_out ; идём на обработку и вывод массивов
_nodigit2: ; очередная метка "дальше"
Cmp al, 20h ; введён символ Space?
Jnz GetKey ; нет, не введён ни один из правильных символов, ; идём на ожидание очередного символа
Mov ah, _flag ; заносим в ah признак введённого пробела
Cmp ah, 0 ; сравниваем его с 0
Jne Getkey ; если введён, то идём на ожидание нажатия клавиши
Xor al, al ; да, обнуляем регистр AL
Call OutSym ; выводим пробел
Inc _counter ; дважды
Inc _counter ; инкрементируем регистр счётчика элементов
Mov ah, 1 ; делаем признак введённого пробела
Mov _flag, ah ;
Jmp GetKey ; идём на ожидание нажатия клавиши
;*****************************
;**** Вывод массивов
******************************
;*****************************
Massiv_out: ; метка подпрограммы вывода массивов
mov ah, 9 ;
lea dx, Mass1Message ;
int 21h ; Выводим сообщение "второй массив..."
xor SI, SI ; Обнулям регистр SI
mov AX,_counter ; заносим в счётчик цикла число элементов
; массива, умноженное на два
mov bl, 2 ; заносим в регистр bl число 2
div bl ; получаем правильное число элементов массива
mov cl, al ; заносим его в регистр счётчика цикла
massiv1_out_loop: ; метка цикла, выводящего на экран элементы ; второго массива
xor DX, DX ; обнуляем регистр DX
mov AX, In_massiv[SI] ; извлекаем элемент массива (индекс в SI)
inc SI ; дважды
inc SI ; инкрементируем регистр указателя
mov BX, 10 ; заносим в BX число 10
div BX ; делим элемент массива на десять
mov AX, DX ; заносим в AL остаток от деления
add Al, 30h ; получаем ASCII код символа
call OutSym ; вызываем программу вывода символа на экран
xor AL, AL ; обнуляем регистр AL
call OutSym ; выводим символ пробела
loop massiv1_out_loop ; повторяем цикл, пока счётчик элементов
; не обнулится
mov ah, 9 ; Когда закончили выводить второй массив
lea dx, AbzacMessage ; делаем абзац
int 21h ;
mov ah, 9 ;
lea dx, Mass2Message ;
Int 21h ; Выводим сообщение "третий массив..."
xor SI, SI ; Обнуляем регистр указателя SI
mov AX,_counter ; заносим в счётчик цикла число элементов
; массива, умноженное на два
mov bl, 2 ; заносим в регистр bl число 2
div bl ; получаем правильное число элементов массива
mov cl, al ; заносим его в регистр счётчика цикла
massiv2_out_loop: ; метка цикла, выводящего на экран элементы
; третьего массива
Xor DX, DX ; обнуляем регистр DX
Mov AX, In_massiv[SI] ; извлекаем элемент массива (индекс в SI)
Cmp ax, 0 ; сравниваем элемент массива с нулём
Je M2_6 ; если равно, то сразу перескакиваем на метку
Mov BX, 2 ; иначе заносим в BX число 2
Mul BX ; Умножаем элемент массива на два
mov bx, 10 ; следующие команды поочерёдно сранивают с нулём
div bx ; каждый разряд десятичного числа, начиная с
push dx ; самого младшего, путём деления элемента на 10
xor dx, dx ; и сохранения в стеке разрядов.
cmp ax, 0 ; когда в частном остаётся 0,
je M2_5 ; выводятся разряды числа, начиная с самого
div bx ; старшего.
push dx ; незначащие нули впереди числа не выводятся,
xor dx, dx ; первый ноль выводится, только если
cmp ax, 0 ; всё число равно 0.
je M2_4 ;
div bx ;
push dx ;
xor dx, dx ;
cmp ax, 0 ;
je M2_3 ;
div bx ;
push dx ;
xor dx, dx ;
cmp ax, 0 ;
je M2_2 ;
div bx ;
push dx ;
pop ax ;
add al, 30h ;
call OutSym ;
M2_2: ;
pop ax ;
add al, 30h ;
call OutSym ;
M2_3: ;
pop ax ;
add al, 30h ;
call OutSym ;
M2_4: ;
pop ax ;
add al, 30h ;
call OutSym ;
M2_5: ;
pop ax ;
add al, 30h ;
call OutSym ;
jmp M2_7 ;
M2_6: ;
Mov al, 30h ; Выводим 0
Call Outsym ;
M2_7: ;
Xor AL, AL ; обнуляем регистр AL
Call OutSym ; выводим пробел
Inc SI ; дважды
Inc SI ; инкрементируем счётчик элементов