Анализ программы 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

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.