Анализ программы Assembler
Рассмотрение основных особенностей компьютерной программы Assembler: функции, структурное описание. Характеристика собственных векторов обработчиков прерываний. Div64 как функция-вычислитель, реализующая операцию деления знаковых чисел в формате 64:16.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | контрольная работа |
Язык | русский |
Дата добавления | 11.03.2013 |
Размер файла | 224,7 K |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Размещено на http://www.allbest.ru/
Задание
Знаковое деление четырёхсловного делимого на однословный делитель на основе использования штатной команды процессора div src (формат 64:16=64).
Структурное описание программы
На входе программы получаем десятичное число -- делимое и делитель. Нам необходимо произвести с их помощью деление. Мы преобразуем и делимое и делитель в двоичную систему исчисления в ASCII строку, после преобразования производим деление делимого на делитель. Мы учитываем остаток от деления и сам результат. После этого преобразуем результат и остаток в десятичную систему счисления, после чего выводим результат на экран
Описание собственных векторов обработчиков прерываний
Обработчик мультиплексного прерывания New_2Fh
Прерывание New_2Fh используется для межпрограммных связей. Поэтому в нашем программном комплексе используем его для реализации механизма общения между резидентом и транзитной программой. Для использования в программном комплексе выбрана функция 0С8h, поскольку ее номер является свободным и предназначена для реализации функции прикладными программами. Опишем подфункции нашей функции, номер подфункции задается в регистре al.
Процедура Init: служит для индикации нахождения резидента в памяти, в результате ее работы al становится равным 0ffh в качестве основного признака и dx становится равным 8888h
Ппроцедура no также служит для индикации резидента и выполняет вывод сообщения от резидента на экран.
Процедура uninstall выполняет удаление резидента из памяти. При помощи функции 25h int 21h восстанавливает старое значение векторов обработчиков прерываний. И удаляет блок резидента из памяти.
Подфункция 04h выполняет загрузку результа деления из резидента в транзитную программу. При этом результат содержится в dx:ax, в случае если процедура умножения не была вызвана значение регистра cx равно 0ffffh
Обработчик прерывания клавиатуры New_09h
Рис.
программа assembler вектор
В случае если установлен флаг активности сканирования клавиатуры, выполняет проверку на нажатие Alt+A, если нажата эта клавиатурная комбинация, то вызывается процедура деления, устанавливается флаг выполнения деления и снимается флаг активности сканирования клавиатуры.
Div64: Функция-вычислитель, реализует операцию деления знаковых чисел в формате 64:16. В виду алгоритмической сложности непосредственной реализации деления чисел в дополнительном коде эту операцию выполняют как деление с предварительным преобразованием делимого и делителя в модульную форму с нулевым знаковым разрядом. Деление проводится в четыре этапа.
Результаты демонстрации программы.
Результат работы резидента
Рис.
Результаты работы программы
Листинг программы.
Resid.asm
p286n
CSEG segment
assume cs:CSEG, ds:CSEG, es:CSEG, ss:CSEG ;настроим сегменты для COM программы
org 100h
Start:
Переходим на метку инициализации.
jmp Init
Обработчик мультиплексного прерывания int 2Fh
new_2fh proc
cmp ah, 0C8h ;наша функция
jne no
cmp al, 00h ;подфункция проверки наличия резидента в памяти
je testt
cmp al, 01h ; подфункция визуальной проверки
je mestest
cmp al, 02h ;подфункция загрузки данных в поля резидента
je load
cmp al, 03h ;подфункция удаления резидента из памяти
je uninstall
cmp al, 04h ;подфункция получения результата процедуры
je get
jmp no
uninstall:
push cs
pop ds
mov ah, 09h
mov dx, offset mes1 ;сообщение
int 21h
lds dx, [dword ptr cs:old_09h] ;установка старого вектора 09h
mov ax, 2509h
int 21h
lds dx, [dword ptr cs:old_2fh] ;установка старого вектора 2Fh
mov ax, 252fh
int 21h
push cs ;настройка es на сs
pop es
mov ah, 49h ;освобождение сегмента
int 21h
iret
NO:
jmp [dword ptr cs:old_2fh] ;в старый обработчик без возврата
iret
load: ;загрузка данных
;ds-si -семгент оффсет операнда из транцитной программы
push es cs
pop es
mov di, offset operand
mov cx, 5
rep movsw
mov [cs:Active], 0
mov [cs:fl_active], 1
mov [cs:error],0
pop es
iret
get: ;возврат результат
push ds cs
pop ds
mov si, offset Result
mov cx, 5
rep movsw
cmp [Active], 1 ;установка идентификатора вызова процедуры умножения
je tiret
net:
stc
mov ch, 0ffh ;сх=0ffffh индикатор не вызова процедуры
tiret:
mov cl,[cs:Error]
pop ds
iret
testt: ;проверка на налицие в памяти
mov al, 0ffh
mov dx, 8888h
iret
mestest: ;проверка с выводом сообщения
push ax dx ds cs
pop ds
mov ah, 09h
mov dx, offset mes
int 21h
pop ds dx ax
iret
old_2fh dd ? ;cтарые адреса векторов прерываний
old_09h dd ?
;Строка, которая будет выводится
Mes db 'Резидент в памяти!',13,10,'$'
Mes1 db 'Резидент выгружен!',13,10,'$'
Mes2 db 'Резидент установлен!',13,10,'$'
new_2fh endp
;конец обработчика
Operand DQ 0
Deler Dw 0
Result DQ 0
Rem DW 0
SignR DB 0
SignC DB 0
Active DB 0 ;флаг активации резидента
fl_active db 0 ;флаг активности клавиатуры
Error db 0
buf dd ?
Neg64 proc ;cмена знака 64 разрядного числа
;bx- адрес числа
;перевод по схеме !A+1
push ds cs
pop ds
not [word ptr bx+6]
not [word ptr bx+4]
not [word ptr bx+2]
not [word ptr bx]
add [word ptr bx],1
adc [word ptr bx+2],0
adc [word ptr bx+4],0
adc [word ptr bx+6],0
pop ds
ret
Neg64 endp
----------
Div64 proc ;деление 64 разрядного числа
cmp bx, 0 ;если нулевой делитель
jne ggood
mov [cs:Error],1 ;то ошибка
ret
ggood:
push ds cs
pop ds
mov [SignR],1
mov [SignC],1
or bx,bx ;знак делителя
jns positive1
neg [SignR] ;учитываем если -
neg bx
positive1:
mov si, [word ptr Operand+6] ;знак делимого
or si,si
jns positive2 ;учитываем если минус
neg [SignR]
neg [SignC]
push bx
mov bx, offset Operand
call Neg64
pop bx
positive2:
xor dx, dx ;деление
mov ax, [word ptr Operand+6]
div bx
mov [word ptr result+6], ax
mov ax, [word ptr Operand+4]
div bx
mov [word ptr result+4], ax
mov ax, [word ptr Operand+2]
div bx
mov [word ptr result+2], ax
mov ax, [word ptr Operand]
div bx
mov [word ptr result], ax
mov [Rem], dx
cmp [word ptr result+6], 8000h ;если получили дольше максимального полодительного
jne welldon
cmp [word ptr result+4], 0000h
jne welldon
cmp [word ptr result+2], 0000h
jne welldon
cmp [word ptr result], 0000h
jne welldon
mov [cs:error], 1 ;то ошибка
welldon:
cmp [SignC], 1
je ok1
neg [Rem] ;востановим верные знаки
ok1:
cmp [SignC],1
je ok2
mov bx, offset operand
call Neg64
ok2:
pop ds
ret
Div64 endp
new_09h proc ;Новый обработчик прерывания 09h
pusha ;Сохраним регистры
push ds es
mov ax,cs
mov ds,ax ;ds=cs
cmp [fl_active],1 ;Производить проверку кодов нажатия клавиш?
je @@work ;Да
jmp @@Exit ;Нет
@@work: ;Отфильтровываем комбинацию Alt-A
in al,60h ;Читаем из порта данных клавиатуры скан-код клавиши
cmp al,1Eh ;Если это [А], то работаем дальше
jz @@ok
@@Exit:
pop es ds
popa
jmp dword ptr cs:[old_09h] ;в старый обработчик без возврата
@@ok:
mov ax,40h
mov es,ax
mov al,[es:17h] ;Получим первый байт флагов состояния клавиатуры
test al,08h ;Клавиша Alt нажата?
je @@Exit ;Нет, перейдём в системный обработчик
sti ;Разрешим аппаратные прерывания
mov [fl_active],0 ;Запретим дальнейшую проверку нажатия клавиш
mov [active],1
mov bx, [cs:Deler]
call DIV64 ;Вызов процедуры деления при ds=cs и es=40h
cli ;Запретим аппаратные прерывания
in al,61h ;Разрешим дальнейшую работу контроллеру клавиатуры
or al,80h
out 61h,al
and al,7fh
out 61h,al
mov al,20h ;Пошлём в контроллер команду EOI
out 20h,al
pop es ds ;Восстановим регистры и выйдем из прерывания
popa
iret
new_09h endp
Init:
mov ax,0c800h ;проверка на наличие в памяти
int 2fh
cmp al, 0ffh
jne install
cmp dx, 8888h
jne install
mov ax, [cs:82h]
cmp ax , 'u/'
je deinstall
mov ah, 9
mov dx, offset message
int 21h
jne exit
проверка на off
deinstall:
mov ax, 0c803h
int 2fh
jmp exit
install:
mov ah, 09h
mov dx, offset Mes2
int 21h
mov ah,35h ;AH содержит номер функции (это понятно)
mov al,09h ;AL указывает номер прерывания, адрес (или вектор)
;которого нужно получить
int 21h;Теперь в ES:BX адрес (вектор) прерывания
(ES - сегмент, BX - смещение)
mov [word ptr cs:old_09h],bx
mov [word ptr cs:old_09h+2],es
mov ax,2509h
mov dx,offset new_09h ;DX должен указывать на наш обработчик
int 21h
mov ah,35h ;AH содержит номер функции (это понятно)
mov al,2fh ;AL указывает номер прерывания, адрес (или вектор)
;которого нужно получить
int 21h;Теперь в ES:BX адрес (вектор) прерывания
;(ES - сегмент, BX - смещение)
mov [word ptr cs:old_2fh],bx
mov [word ptr cs:old_2fh+2],es
mov ax,252fh
mov dx,offset new_2fh ;DX должен указывать на наш
;обработчик
int 21h
mov dx,offset Init
int 27h
exit:
mov ax, 4c00h
int 21h
message db 'Копия резидента уже присутствует в памяти.',13,10,'Pапустите с опцией /u для выгрузки',13,10,'$'
CSEG ends
end Start
h.asm
p586n
%TITLE "HELLO.ASM"
IDEAL
MODEL small
STACK 256
Macro window N,attrib,y1,x1,y2,x2 ; инициализация (N=0) или прокрутка окна вверх
mov ah,06h
mov al,N
mov bh,attrib
mov ch,y1
mov cl,x1
mov dh,y2
mov dl,x2
int 10h
Endm window
Macro readkey ; ожидание ввода любого символа
mov ah,10h ; функция ввода символа с ожиданием
int 16h
Endm readkey
Macro getmode ; получение режима дисплея
mov ah,0Fh
int 10h
mov [oldmode],al ; запись исходного режима дисплея в переменную oldmode
Endm getmode
Macro setmode mode ; установка дисплея в режим mode
mov ah,00h
mov al,mode
int 10h
Endm setmode
Macro out_str mes,leng,attrib ; тvтюф ёююс•хэш фышэющ leng яю
; рфЁхёє es:offset mes ё рЄЁшсєЄюь ёшьтюыют attrib
mov ah,13h
mov al,1
mov bh,0
mov bl,attrib
mov cx,leng
mov bp,offset mes
int 10h
Endm out_str
Macro locate y,x ; єёЄрэютър ъєЁёюЁр т яючшЎш¦ ¤ъЁрэр row=y, column=x
mov ah,02h
mov bh,0
mov dh,y
mov dl,x
int 10h
Endm locate
DATASEG
Operand DQ 0FF734FAD45672344h
Deler Dw 0
Result DQ 0
Rem DW 0
SignR DB 0
SignC DB 0
oldmode DB ?
Buf DQ 0
Режим экрана, используемый в программе
usemode EQU 83h ; 10000011b режим 3 с запретом очистки экрана
ExCode DB 0
STR64 DB 21,?,21 DUP(?)
STR16 DB 7,?,7 DUP(?)
QUOT DB 21 DUP (?),13,10,'$'
ErrorOver DB 'Переполнение'
overlen=$-errorover
ErrorBad DB 'Не верный сивол'
badlen=$-errorbad
ErrorOver2 DB 'Переполнение',13,10,'$'
Errorbad2 DB 'Не верный символ',13,10,'$'
type4 DB 'Выберите: новое деление - N, выход -Esc'
type4len = $-type4
sprite DB '|/-\'
hellomes db 'Программа совместно в резидентом выполняющая деление чисел в формате 64:16',13,10,'результат 64 частное 16 остаток. Деление выполняется на основе команды div.'
hlen=$-hellomes
First DB 'Введите делимое, знакокое 64 битное число'
Flen=$-first
Second DB 'Введите делитель, знаковое 16 разрядное число'
Slen=$-second
_del db 'Делимое'
hd=$-_del
_del2 db 'Делитель'
hd2=$-_del2
_ost db 'Остаток'
olen=$-_ost
_chast db 'Частное'
clen=$-_chast
nosign db 'У резидента не верная сигнатура. Нажмите любую клавишу для выхода.'
nosignlen=$-nosign
divover DB 'Переполнение деления.'
divoverlen = $-divover
noinst db 'Резидент отсутствует в памяти. Нажмите любую клавишу для выхода.'
noinstlen=$-noinst
mainmes db 'Выберите Alt+A-деление, Esc-выход из режима ожидания'
mainlen=$-mainmes
mes_nocall DB 'Деление на выполнено - не была нажата комбинация Alt+A'
mes_nocalllen = $-mes_nocall
Ostatok db 6 dup (?)
OstatokLEN=$-Ostatok
Chastnoe db 20 dup (?)
ChastnoeLEN =$-Chastnoe
CODESEG
proc Neg64 ;смена знака опиисана в резиденте
not [word ptr bx+6]
not [word ptr bx+4]
not [word ptr bx+2]
not [word ptr bx]
add [word ptr bx],1
adc [word ptr bx+2],0
adc [word ptr bx+4],0
adc [word ptr bx+6],0
ret
endp Neg64
;-----------------
proc Div64 ;деление описано в резиденте
mov [SignR],1
mov [SignC],1
or bx,bx
jns positive1
neg [SignR]
neg bx
positive1:
mov si, [word ptr Operand+6]
or si,si
jns positive2
neg [SignR]
neg [SignC]
push bx
mov bx, offset Operand
call Neg64
pop bx
positive2:
xor dx, dx
mov ax, [word ptr Operand+6]
div bx
mov [word ptr result+6], ax
mov ax, [word ptr Operand+4]
div bx
mov [word ptr result+4], ax
mov ax, [word ptr Operand+2]
div bx
mov [word ptr result+2], ax
mov ax, [word ptr Operand]
div bx
mov [word ptr result], ax
mov [Rem], dx
cmp [SignC], 1
je ok1
neg [Rem]
ok1:
cmp [SignC],1
je ok2
mov bx, offset operand
call Neg64
ok2:
ret
endp Div64
;---------------
proc mul6410 ;умножение на 10 для перевода из ascii строки
mov di,10 ;основание системы
mov ax, [word ptr Operand+6] ;умножим старшую часть
mul di
jnc nocar ;переполнение
ret
nocar:
mov [word ptr Buf+6],ax
mov ax, [word ptr Operand+4] ;умножим оставшиеся части
mul di
add [word ptr Buf+6] ,dx ;c учетом переносов
mov [word ptr Buf+4],ax
mov ax, [word ptr Operand+2]
mul di
add [word ptr buf+4] ,dx
mov [word ptr buf+2],ax
mov ax, [word ptr Operand]
mul di
add [word ptr buf+2] ,dx
mov [word ptr buf],ax
clc
ret
endp mul6410
;----------------------
PROC ADD64 ;cложение с числом
add [word ptr operand],dx
adc [word ptr operand+2],0
adc [word ptr operand+4],0
adc [word ptr operand+6],0
ret
endp add64
;-------------------
proc xchg64 ;обмен
push cx
mov cx, [word ptr si] ;обмениваем по частям с использованием регистра сх
xchg cx, [word ptr di]
mov [word ptr si],cx
mov cx,[word ptr si+2]
xchg cx, [word ptr di+2]
mov [word ptr si+2],cx
mov cx,[word ptr si+4]
xchg cx, [word ptr di+4]
mov [word ptr si+4],cx
mov cx,[word ptr si+6]
xchg cx, [word ptr di+6]
mov [word ptr si+6],cx
pop cx
ret
endp xchg64
;---------------------------
proc mov64 ;перемещение
push cx
mov cx, [word ptr si] ;перемещаем по частям
mov [word ptr di],cx
mov cx,[word ptr si+2]
mov [word ptr di+2],cx
mov cx,[word ptr si+4]
mov [word ptr di+4],cx
mov cx,[word ptr si+6]
mov [word ptr di+6],cx
pop cx
ret
endp mov64
proc clear64 ;обнуление
push cx
mov [word ptr di],0
mov [word ptr di+2],0
mov [word ptr di+4],0
mov [word ptr di+6],0
pop cx
ret
endp clear64
;-------------------
proc decbin ;процедура перевода десятичного числа представленного ascii строкой в двоичное находящееся в регистре ax
cmp [byte bx],'-' ;Отрицательное число?
jne positive
inc bx ;Продвинем указатель и
dec cx;уменьшим счётчик цикла
call conv ;Преобразуем модуль отрицательного десятичного числа.
;На выходе: ax - двоичный код, сf=1, если преобразуемое число превышает значение 65535
jc badend ;Число > 65535 или не допустимый символ?
cmp ax,32768
ja overflow;Число >32768
neg ax;Сформируем дополнительный код
js good;Закончим преобразование
positive:
call conv;Преобразуем модуль положительного десятичного числа.
jc badend; Число > 65535?
cmp ax,32767
jbe good;Число< 32767
overflow:
locate 22,0
out_str errorover,overlen,34h ; сообщение о переполнении
badend:
stc;cf=1
jmp n_good ;Выйдем из преобразования
good: clc;cf=0
n_good:ret
endp decbin
proc conv ;конвертация
push dx di
xor ax,ax;Очистим регистр двоичного числа
mov di,10;10- основание системы счисления
cycl: mul di;dx:ax = ax*10
jc over_flow;Переход, если CF=1
mov dl,[bx] ;Выберем очередную ASCII-цифру
sub dl,30h ;Образуем двоичное число
cmp dl, 0h
jl Bd
cmp dl, 9h
jg Bd
add ax,dx;Промежуточная сумма
jc over_flow;Переход, если CF=1
inc bx
loop cycl;Продолжим, если cx>0
clc;Нет, сбросим флаг CF=1
jmp last
bd:
locate 22,0
out_str errorbad,badlen,34h ; сообщение о нецифровом символе
stc
jmp last
over_flow:
locate 22,0
out_str errorover,overlen,34h ; сообщение о переполнении
stc
last:
pop di dx
ret
endp conv
proc dec_bin64 ;процедура перевода десятичного числа представленного ascii строкой в двоичное находящееся в регистре ax
cmp [byte bx],'-' ;Отрицательное число?
jne positiveq
inc bx ;Продвинем указатель и
dec cx;уменьшим счётчик цикла
call conv64 ;Преобразуем модуль отрицательного десятичного числа.
;На выходе: ax - двоичный код, сf=1, если преобразуемое число превышает значение 65535
jc badend2;Число > 65535 или не допустимый символ?
cmp [word ptr Operand+6],8000h
ja overflow2;Число >32768
cmp [word ptr Operand+4],0000h
ja overflow2;Число >32768
cmp [word ptr Operand+2],0000h
ja overflow2;Число >32768
cmp [word ptr Operand],0000h
ja overflow2;Число >32768
mov bx, offset Operand
Call Neg64;Сформируем дополнительный код
js good2;Закончим преобразование
positiveq:
call conv64 ;Преобразуем модуль положительного десятичного числа.
jc badend2; Число > 65535?
cmp [word ptr Operand+6],7fffh
jbe good2;Число< 32767
cmp [word ptr Operand+4],0ffffh
jbe good2;Число< 32767
cmp [word ptr Operand+2],0ffffh
jbe good2;Число< 32767
cmp [word ptr Operand],0ffffh
jbe good2;Число< 32767
overflow2:
; print ErrorOver2
locate 22,0
out_str errorover,overlen, 34h ; сообщение о переполнении
badend2:
stc;cf=1
jmp n_good2;Выйдем из преобразования
good2:clc;cf=0
n_good2:
ret
endp dec_bin64
;-----------------
proc conv64 ;конвертация
push dx di
mov di, offset operand
call clear64
cycl2:
call mul6410;dx:ax = ax*10
jc over_flow3;Переход, если CF=1
mov di, offset operand
mov si, offset buf
call mov64
mov dl,[bx] ;Выберем очередную ASCII-цифру
xor dh,dh
sub dl,30h;Образуем двоичное число
cmp dl, 0h
jl Bd
cmp dl, 9h
jg Bd
call add64;Промежуточная сумма
jc over_flow3;Переход, если CF=1
inc bx
loop cycl2;Продолжим, если cx>0
clc;Нет, сбросим флаг CF=1
jmp last3
bd3:
; print ErrorBad2
locate 22,0
out_str errorbad,badlen, 34h
stc
jmp last
over_flow3:
; print ErrorOver2
locate 22,0
out_str errorover,overlen, 34h
stc
last3:
pop di dx
ret
endp conv64
;---------------------
Proc Bindec
mov cx,21;Размер буфера в байтах
Blank:mov [byte bx],' ' ;Очистим буфер, т.е. заполним его пробелами
inc bx
loop Blank
dec bx;Установим адрес последнего элемента буфера
push [word ptr operand+6]
MOV AX, [word ptr Operand+6]
or AX,AX;Установим флаг знака SF
jns trans
push bx;Перейдём к преобразованию, если SF=0
mov bx, offset Operand
call neg64;Изменим знак
pop bx
trans:
push bx
mov bx, 10
call Div64;ax=quot(dx:ax/10), dx=rem(dx:ax/10)
add [word ptr Rem],'0';Сформируем десятичную ASCII-цифру
mov si, offset result
mov di, offset operand
call mov64
pop bx
MOV AL, [BYTE REM]
mov [byte bx],AL ;Занесём в буфер
dec bx;Движение назад
cmp [word ptr Operand+6],0000h
jne trans;Число< 32767
cmp [word ptr Operand+4],0000h
jne trans;Число< 32767
cmp [word ptr Operand+2],0000h
jne trans;Число< 32767
cmp [word ptr Operand],0000h
jne trans;Число< 32767
pop ax;Восстановить исходное число,
or ax,ax;Установим флаг знака SF
jns out_trans;Выходим из подпрограммы, если SF=0
mov [byte bx],'-' ;Запишем знак '-' для отрицательного числа
out_trans:
ret
Endp Bindec
;------------
Proc delay
mov ah,0 ;Функция "чтения" циклов таймера
int 1Ah ;Получаем значение счетчика циклов в cx:dx
add dx,9 ;Добавляем 5 сек. к младшему слову в dx
mov bx,dx ;Запоминаем требуемое значение в bx и выполняем
;постоянную проверку значений счетчика времени суток
repeat:int 1Ah ;Вновь получаем значение счетчика
cmp dx,bx ;Сравниваем с искомым
jne repeat
ret
endp delay
Процедура ожидания (заглушка) Waiting, реализующая в бесконечном цикле вывод на экран
;вращающегося курсора. Производится фильтрация нажатия клавиш:
;Резидентом - комбинация Alt-A - приказ на выполнение процедуру вычисления,
;Программой trans_m - клавиша Esc - выход из процедуры Waiting.
Proc Waiting
push ds
pop es ; es=ds (сегмент данных транзитной программы)
window 0,3Bh,24,0,24,79
locate 22,0
out_str mainmes, mainlen, 03Ah
;Получим позицию курсора, используя функцию 03h прерывания int 10h
;Вывод на экран спрайта анимации (вращающийся курсор) путём непосредственного программиро-
;ования памяти. Преобразуем координаты курсора из системы "строка - столбец" в номер пиксела
;(рег. ах) на экране монитора
;Настроим пару es:di на адрес вывода
push es
mov ax,0B800h
mov es,ax
mov di,24*160
mov si,0 ;Индекс считывания элементов Sprite
;Вывод в цикле текущего символа строки sprite
@@loop: mov dh,34h ;красный по синему
mov dl,[sprite+si] ;очередной символ
mov [es:di],dx ;вывод на экран
inc si
and si,03h ;Цикл вывода включает все элементы Sprite
mov bp,2
call delay ;Временная задержка
;Проверка буфера клавиатуры без ожидания (функция 01h, int 16h) на наличие в нём символа. При
;проверке, возвращаемая в АХ информация не удаляется из буфера: ZF=1- буфер пуст, ZF=0-
;в буфере есть сисмволы
mov ah,01h
int 16h
jz short @@loop ;Символ отсутствует
mov ah,00h ;Чтение символа клавиатуры в АХ (скан-код и ASCII-код) с
int 16h ; с удалением из буфера. Ожидаем, если буфер пуст
cmp al,1Bh ;Нажата Esc?
je short @@end ;Да, на выход
jmp short @@loop ;Нет, продолжим вывод анимации
@@end: pop es
window 0,3Bh,22,0,24,79
ret
Endp Waiting
Proc Bidec
push ax ;Сохраним знак преобразуемого числа
mov cx,6;Размер буфера в байтах
Blank2: mov [byte bx],' ' ;Очистим буфер, т.е. заполним его пробелами
inc bx
loop Blank2
dec bx;Установим адрес последнего элемента буфера
mov di,10 ;Введём основание десятичной системы счисления
or ax,ax ;Установим флаг знака SF
jns trans2 ;Перейдём к преобразованию, если SF=0
neg ax ;Изменим знак
trans2: sub dx,dx ;Сделаем dx=0
div di ;ax=quot(dx:ax/10), dx=rem(dx:ax/10)
add dl,'0' ;Сформируем десятичную ASCII-цифру
mov [byte bx],dl ;Занесём в буфер
dec bx ;Движение назад
or ax,ax ;Преобразование закончено?
jnz trans2 ;Повторить, если АХ>0
pop ax ;Восстановить исходное число,
or ax,ax ;с целью определения его знака
jns out_trans2 ;Выходим из подпрограммы, если SF=0
mov [byte bx],'-' ;Запишем знак '-' для отрицательного числа
out_trans2: ret
Endp Bidec
Start:
mov ax, @data
mov ds,ax
mov es,ax ; es=ds
getmode ; сохранение старого режима
setmode usemode ; установка нового режима
allagain: window 0,03Bh,0,0,24,79 ;главное окно
window 0, 0F0h,7,7,7,7+21 ;окна ввода
window 0, 0F0h,7,7+40,7,7+46
window 0, 0F0h,10,7,10,7+21 ;окна вывода
window 0, 0F0h,10,7+40,10,7+46
locate 0,0 ;подписи к окнам
out_Str hellomes, hlen, 03bh
locate 6,7
out_Str _del, hd, 03bh
locate 6,7+40
out_Str _del2, hd2, 03bh
locate 9,7
out_Str _chast, clen, 03bh
locate 9,7+40
out_Str _ost, olen, 03bh
xor dx,dx
mov ax, 0c800h ;проверка на наличие резидента
int 2fh
cmp al, 0ffh ;наш..?
jne no
cmp dx, 8888h ;совпала сигнатура?
jne nosignature
again1:
window 0, 0F0h,7,7,7,7+21
locate 24,0
out_Str first, flen, 03Ah
locate 7,7
mov dx,offset Str64
mov ah,0Ah
int 21h ;ввод делимого
xor ch,ch
mov cl,[str64+1]
mov bx,offset str64+2
call dec_bin64 ;перевод делимого
jc again1 ;если ошибка то повторить ввод
window 0,03Bh,22,0,22,79
again2:
window 0, 0F0h,7,7+40,7,7+46
locate 24,0
out_Str second, slen, 03Ah
locate 7,7+40
mov dx,offset Str16
mov ah,0Ah ;ввод делителя
int 21h
xor ch,ch
mov cl,[str16+1]
mov bx,offset str16+2
call decbin ;перевод делителя
jc again2 ;если ошибка то перевод
mov [Deler],ax
window 0,03Bh,22,0,22,79
send:
mov si, offset operand ;подготовка к передачи данных резуденту
mov ax, 0c802h ;передача
int 2fh
call waiting ;заглушка
mov ax, 0c804h ;подготовка к получению данных
push ds
pop es
mov di, offset Result
int 2fh
cmp ch, 0ffh ;произведена активаций...?
je nocall
cmp cl, 0 ;нет ошибок..?
je results
locate 22,0
out_str divover,divoverlen ,34h ; вывод ошибки
jmp PrintQuestion
results:
mov ax, [Rem]
mov bx, offset Ostatok
call bidec ;преобразование остатка
locate 10, 47
out_str Ostatok, Ostatoklen, 0F0h ;вывод остатка
mov di, offset Operand
mov si, offset Result
call mov64
mov bx, offset chastnoe ;преобразование частного
call Bindec
locate 10, 7
out_str Chastnoe+1, Chastnoelen, 0F0h ;вывод частного
jmp printquestion
nocall:
locate 22,0
out_str mes_nocall,mes_nocalllen,34h ; сообщение о том, что не была нажата комбинация Alt-A
PrintQuestion:
window 0,3bH, 24,0,24,79
locate 24,0
out_str type4,type4len,3Ah ; вывод подсказки
mov ah,00h ; ввод символа
int 16h
cmp al,'N' ; 'n'?
je allagain ; новый ввод
cmp al,1Bh ; ESC
jne PrintQuestion
jmp Exit
jmp Exit
nosignature:
locate 22,0
out_str nosign,nosignlen,034h ; сообщение о присутствии резидента с той же функцией, но другой сигнатурой
readkey
jmp exit
no:
locate 22,0
out_str noinst,noinstlen,034h ; сообщение об отсутствии резидента в памяти
readkey
Exit: setmode [oldmode]
mov ah,4ch ;Функция DOS-выход из программы
mov al,[ExCode];Возврат кода ошибки
int 21h ;Вызов DOS. Останов прогр.
END Start ;Конец программы/точка входа
Размещено на Allbest.ru
Подобные документы
Структурная схема микроконтроллера, процесс разработки принципиальной схемы и программного обеспечения. Конфигурирование регистров аналого-цифрового преобразователя. Код программы на языке Assembler, конфигурирование регистров внешних прерываний.
курсовая работа [267,5 K], добавлен 08.06.2019Формирование опыта создания программ с использованием программного продукта Turbo Assembler. Использование меньшего количества команд и обращений в память, увеличение скорости и уменьшение размера программы. Степень сложности совместной разработки.
реферат [15,4 K], добавлен 24.02.2010Разработка программы на языке Assembler, отсчитывающую время от заданного значения до 0. Осуществление ввода с помощью стандартной шестнадцатикнопочной терминальной клавиатуры, подключаемой к параллельному порту (P1). Логика построения программы.
курсовая работа [188,8 K], добавлен 15.08.2009Исследование общих принципов программирования на языке Assembler для 32-х разрядных и 64-х разрядных процессоров. Изучение основных отличий архитектур i686 и amd64. Работа со стеком. Передача параметров в функции. Смена способа адресации внутри программы.
контрольная работа [118,2 K], добавлен 10.02.2015Составление программы, реализующей моделирование операции умножения, начиная со старших разрядов множителя, при сдвиге суммы частичного произведения влево и неподвижным множителем. Особенности реализации программы на алгоритмическом языке Assembler.
курсовая работа [26,9 K], добавлен 25.05.2014Описание функций, использующихся в программах. Основы 32-битного программирования на языке Assembler для ОС WINDOWS. Использование функции invoke, которая позволяет намного сократить текст программы и делает приложения похожими на программы для "ЯВы".
курсовая работа [252,6 K], добавлен 20.02.2015Создание программы для вычисления значения функции на основе определённой формулы. Уточнение структуры входных и выходных данных и определение ассемблерного формата их представления. Разработка алгоритмов для реализации работы программного обеспечения.
курсовая работа [240,6 K], добавлен 17.06.2013Порівняльна характеристика структури мов програмування Assembler та C. Вивчення поняття "об'єктного файлу" та "виконуваного модуля". Розгляд функцій переривання, введення/виведення символу та стрічки, екранного режиму та малювання крапки і прямої.
курс лекций [348,8 K], добавлен 18.06.2010Арифметические команды языка Assembler в архитектуре x86. Организация ветвлений и циклов в программах. Ввод строк с клавиатуры и команды пакетной обработки (строковые команды). Алгоритм вывода на экран в текстовом режиме с использованием средств BIOS.
контрольная работа [18,0 K], добавлен 05.07.2014График функции. Дескриптор окна консоли. Процедура обработки сообщений. Регестрация класса окна с помощью функции RegisterClass. Обработчик сообщений по умолчанию. Текст программы. Процедура WNDProc. Главная функция. Управление вызывающей функции.
практическая работа [311,0 K], добавлен 11.10.2008