Анализ программы Assembler
Задание
Знаковое деление четырёхсловного делимого на однословный делитель на основе использования штатной команды процессора 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 getno:csdsah, 09hdx, offset mes1 ;сообщение21h 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 csesdi, offset operandcx, 5movsw[cs:Active], 0[cs:fl_active], 1[cs:error],0 es
iret
get: ;возврат результат
push ds csdssi, offset Result cx, 5
rep movsw
cmp [Active], 1 ;установка идентификатора вызова процедуры умножения
je tiret
net:
stc
mov ch, 0ffh ;сх=0ffffh индикатор не вызова процедуры
tiret:cl,[cs:Error] ds
iret
testt: ;проверка на налицие в памяти
mov al, 0ffhdx, 8888h
mestest: ;проверка с выводом сообщения
push ax dx ds csdsah, 09hdx, offset mes21hds dx ax
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 0DQ 0DW 0DB 0 DB 0DB 0 ;флаг активации резидента
fl_active db 0 ;флаг активности клавиатуры
Error db 0
buf dd ?
Neg64 proc ;cмена знака 64 разрядного числа
;bx- адрес числа
;перевод по схеме !A+1
push ds csds[word ptr bx+6][word ptr bx+4][word ptr bx+2][word ptr bx][word ptr bx],1[word ptr bx+2],0[word ptr bx+4],0[word ptr bx+6],0ds
Neg64 endp
---------
Div64 proc ;деление 64 разрядного числа
cmp bx, 0 ;если нулевой делитель
jne ggood
mov [cs:Error],1 ;то ошибка:ds csds[SignR],1[SignC],1bx,bx ;знак делителяpositive1[SignR] ;учитываем если -bx:si, [word ptr Operand+6] ;знак делимого si,si
jns positive2 ;учитываем если минус
neg [SignR][SignC]bxbx, offset OperandNeg64bx:dx, dx ;делениеax, [word ptr Operand+6]bx[word ptr result+6], axax, [word ptr Operand+4]bx[word ptr result+4], axax, [word ptr Operand+2]bx[word ptr result+2], axax, [word ptr Operand]bx[word ptr result], ax [Rem], dx
cmp [word ptr result+6], 8000h ;если получили дольше максимального полодительного
jne welldon[word ptr result+4], 0000hwelldon[word ptr result+2], 0000hwelldon[word ptr result], 0000hwelldon[cs:error], 1 ;то ошибка:[SignC], 1ok1[Rem] ;востановим верные знаки:[SignC],1ok2bx, offset operandNeg64:ds64 endp
new_09hproc ;Новый обработчик прерывания 09h
pusha ;Сохраним регистры
push ds es
mov ax,csds,ax ;ds=cs [fl_active],1;Производить проверку кодов нажатия клавиш?
je @@work;Да@@Exit;Нет
@@work:;Отфильтровываем комбинацию Alt-A
in al,60h;Читаем из порта данных клавиатуры скан-код клавиши
cmp al,1Eh;Если это [А], то работаем дальше
jz @@ok
@@Exit: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],1bx, [cs:Deler] DIV64 ;Вызов процедуры деления при ds=cs и es=40h
cli ;Запретим аппаратные прерывания
in al,61h ;Разрешим дальнейшую работу контроллеру клавиатуры
or al,80h61h,alal,7fh61h,al al,20h;Пошлём в контроллер команду EOI
out 20h,al
pop es ds ;Восстановим регистры и выйдем из прерывания
popa_09h endp: ax,0c800h ;проверка на наличие в памяти
int 2fhal, 0ffhinstalldx, 8888hinstallax, [cs:82h]
cmp ax , 'u/'deinstall
mov ah, 9dx, offset message 21h
jne exit
проверка на off
deinstall:ax, 0c803h2fhexit:ah, 09hdx, offset Mes221h 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 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 ax,252fh
mov dx,offset new_2fh;DX должен указывать на наш
;обработчик21hdx,offset Init27h:ax, 4c00h 21h
message db 'Копия резидента уже присутствует в памяти.',13,10,'Pапустите с опцией /u для выгрузки',13,10,'$'
CSEG endsStart.asmn
%TITLE "HELLO.ASM"small256window N,attrib,y1,x1,y2,x2 ; инициализация (N=0) или прокрутка окна вверхah,06hal,Nbh,attribch,y1cl,x1dh,y2dl,x210hwindow 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,00hal,mode10hsetmodeout_str mes,leng,attrib ; т?тюф ёююс?хэш фышэющ leng яю
; рфЁхёє es:offset mes ё рЄЁшсєЄюь ёшьтюыют attribah,13hal,1bh,0bl,attribcx,lengbp,offset mes10hout_strlocate y,x ; єёЄрэютър ъєЁёюЁр т яючшЎш? ¤ъЁрэр row=y, column=xah,02hbh,0dh,ydl,x10hlocateDQ 0FF734FAD45672344h
Deler Dw 0DQ 0DW 0
SignR DB 0 DB 0DB ? DQ 0
Режим экрана, используемый в программе
usemode EQU 83h ; 10000011b режим 3 с запретом очистки экрана
ExCode DB 0DB 21,?,21 DUP(?)
STR16 DB 7,?,7 DUP(?)DB21 DUP (?),13,10,'$'DB 'Переполнение'=$-erroroverDB 'Не верный сивол'=$-errorbadDB 'Переполнение',13,10,'$'DB 'Не верный символ',13,10,'$'4 DB 'Выберите: новое деление - N, выход -Esc'
type4len = $-type4DB'|/-\'
hellomesdb 'Программа совместно в резидентом выполняющая деление чисел в формате 64:16',13,10,'результат 64 частное 16 остаток. Деление выполняется на основе команды div.'
hlen=$-hellomes
First DB'Введите делимое, знакокое 64 битное число'
Flen=$-first
Second DB'Введите делитель, знаковое 16 разрядное число'
Slen=$-second
_deldb'Делимое'=$-_del
_del2db'Делитель'=$-_del2
_ostdb'Остаток'=$-_ost
_chastdb'Частное'
clen=$-_chast
nosign db 'У резидента не верная сигнатура. Нажмите любую клавишу для выхода.'
nosignlen=$-nosign
divover DB 'Переполнение деления.'
divoverlen = $-divover
noinst db 'Резидент отсутствует в памяти. Нажмите любую клавишу для выхода.'
noinstlen=$-noinst
mainmesdb 'Выберите Alt+A-деление, Esc-выход из режима ожидания'
mainlen=$-mainmes
mes_nocall DB 'Деление на выполнено - не была нажата комбинация Alt+A'
mes_nocalllen = $-mes_nocall
Ostatokdb6 dup (?)
OstatokLEN=$-Ostatok
Chastnoedb 20 dup (?)
ChastnoeLEN=$-Chastnoe
CODESEG
proc Neg64 ;смена знака опиисана в резиденте
not [word ptr bx+6][word ptr bx+4][word ptr bx+2][word ptr bx][word ptr bx],1[word ptr bx+2],0[word ptr bx+4],0[word ptr bx+6],0
endp Neg64
;-----------------
proc Div64 ;деление описано в резиденте
mov [SignR],1[SignC],1bx,bxpositive1[SignR]bx:si, [word ptr Operand+6]si,sipositive2[SignR][SignC]bxbx, offset OperandNeg64bx:dx, dxax, [word ptr Operand+6]bx[word ptr result+6], axax, [word ptr Operand+4]bx[word ptr result+4], axax, [word ptr Operand+2]bx[word ptr result+2], axax, [word ptr Operand]bx[word ptr result], ax[Rem], dx[SignC], 1
je ok1[Rem]:
cmp [SignC],1ok2bx, offset operandNeg64:Div64
;---------------
proc mul6410 ;умножение на 10 для перевода из ascii строки
mov di,10 ;основание системы
mov ax, [word ptr Operand+6] ;умножим старшую часть
mul di
jnc nocar ;переполнение
ret
nocar:[word ptr Buf+6],ax ax, [word ptr Operand+4] ;умножим оставшиеся части
mul di
add [word ptr Buf+6] ,dx ;c учетом переносов
mov [word ptr Buf+4],axax, [word ptr Operand+2]di[word ptr buf+4] ,dx[word ptr buf+2],axax, [word ptr Operand]di[word ptr buf+2] ,dx[word ptr buf],axmul6410
;----------------------ADD64 ;cложение с числом[word ptr operand],dx[word ptr operand+2],0[word ptr operand+4],0[word ptr operand+6],0add64
;-------------------xchg64 ;обмен cx
mov cx, [word ptr si] ;обмениваем по частям с использованием регистра сх
xchg cx, [word ptr di][word ptr si],cxcx,[word ptr si+2]cx, [word ptr di+2][word ptr si+2],cxcx,[word ptr si+4]cx, [word ptr di+4][word ptr si+4],cxcx,[word ptr si+6]cx, [word ptr di+6][word ptr si+6],cxcxxchg64
;---------------------------mov64 ;перемещение cx
mov cx, [word ptr si] ;перемещаем по частям
mov [word ptr di],cxcx,[word ptr si+2][word ptr di+2],cxcx,[word ptr si+4][word ptr di+4],cxcx,[word ptr si+6][word ptr di+6],cxcxmov64clear64 ;обнулениеcx[word ptr di],0[word ptr di+2],0[word ptr di+4],0[word ptr di+6],0cx
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:22,0_str errorover,overlen,34h ; сообщение о переполнении
badend:
stc;cf=1
jmp n_good;Выйдем из преобразования
good:clc;cf=0_good:retdecbinconv ;конвертацияdx di 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, 0hBddl, 9h 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 ; сообщение о нецифровом символе
stclast_flow:22,0_str errorover,overlen,34h ; сообщение о переполнении:di dxconv
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],8000hoverflow2;Число >32768[word ptr Operand+4],0000hoverflow2;Число >32768[word ptr Operand+2],0000hoverflow2;Число >32768[word ptr Operand],0000hoverflow2;Число >32768bx, offset OperandNeg64;Сформируем дополнительный код good2;Закончим преобразование
positiveq:
call conv64;Преобразуем модуль положительного десятичного числа.
jc badend2; Число > 65535?[word ptr Operand+6],7fffhgood2;Число< 32767[word ptr Operand+4],0ffffhgood2;Число< 32767[word ptr Operand+2],0ffffhgood2;Число< 32767[word ptr Operand],0ffffhgood2;Число< 32767:
; print ErrorOver222,0_str errorover,overlen, 34h ; сообщение о переполнении2:
stc;cf=1
jmp n_good2;Выйдем из преобразования
good2:clc;cf=0_good2:dec_bin64
;-----------------conv64 ;конвертацияdx didi, offset operandclear64:mul6410;dx:ax = ax*10over_flow3;Переход, если CF=1di, offset operandsi, offset bufmov64 dl,[bx];Выберем очередную ASCII-цифру
xor dh,dh
sub dl,30h;Образуем двоичное число
cmp dl, 0hBddl, 9h Bd
call add64;Промежуточная сумма
jc over_flow3;Переход, если CF=1
inc bx
loop cycl2;Продолжим, если cx>0
clc;Нет, сбросим флаг CF=1
jmp last3:
; print ErrorBad222,0_str errorbad,badlen, 34hlast_flow3:
; print ErrorOver222,0_str errorover,overlen, 34h:di dxconv64
;---------------------Bindec cx,21;Размер буфера в байтах
Blank:mov [byte bx],' ';Очистим буфер, т.е. заполним его пробелами
inc bxBlank bx;Установим адрес последнего элемента буфера
push [word ptr operand+6]AX, [word ptr Operand+6] 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) [word ptr Rem],'0';Сформируем десятичную ASCII-цифруsi, offset resultdi, offset operandmov64bxAL, [BYTE REM][byte bx],AL;Занесём в буферbx;Движение назад[word ptr Operand+6],0000htrans;Число< 32767[word ptr Operand+4],0000htrans;Число< 32767[word ptr Operand+2],0000htrans;Число< 32767[word ptr Operand],0000h trans;Число< 32767
pop ax;Восстановить исходное число,
or ax,ax;Установим флаг знака SF
jns out_trans;Выходим из подпрограммы, если SF=0
mov [byte bx],'-';Запишем знак '-' для отрицательного числа
out_trans:Bindec
;------------ 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,7922,0_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 es0,3Bh,22,0,24,79WaitingBidec ax;Сохраним знак преобразуемого числа
mov cx,6;Размер буфера в байтах
Blank2:mov [byte bx],' ';Очистим буфер, т.е. заполним его пробеламиbxBlank2
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)dl,'0';Сформируем десятичную ASCII-цифру[byte bx],dl;Занесём в буфер bx;Движение назад
or ax,ax;Преобразование закончено?
jnz trans2;Повторить, если АХ>0
pop ax;Восстановить исходное число,
or ax,ax;с целью определения его знака
jns out_trans2;Выходим из подпрограммы, если SF=0
mov [byte bx],'-';Запишем знак '-' для отрицательного числа
out_trans2:retBidec:ax, @datads,ax 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, 03bh6,7_Str _del, hd, 03bh6,7+40_Str _del2, hd2, 03bh9,7_Str _chast, clen, 03bh9,7+40_Str _ost, olen, 03bh dx,dx
mov ax, 0c800h ;проверка на наличие резидента
int 2fhal, 0ffh ;наш..?no dx, 8888h ;совпала сигнатура?
jne nosignature:0, 0F0h,7,7,7,7+2124,0_Str first, flen, 03Ah7,7dx,offset Str64ah,0Ah21h ;ввод делимогоch,chcl,[str64+1]bx,offset str64+2 dec_bin64 ;перевод делимого
jc again1 ;если ошибка то повторить ввод
window 0,03Bh,22,0,22,79:0, 0F0h,7,7+40,7,7+4624,0_Str second, slen, 03Ah7,7+40dx,offset Str16ah,0Ah ;ввод делителя21hch,chcl,[str16+1]bx,offset str16+2decbin ;перевод делителя again2 ;если ошибка то перевод
mov [Deler],ax0,03Bh,22,0,22,79:
mov si, offset operand ;подготовка к передачи данных резуденту
mov ax, 0c802h ;передача
int 2fh
call waiting ;заглушка
mov ax, 0c804h ;подготовка к получению данных
push dsesdi, offset Result 2fh
cmp ch, 0ffh ;произведена активаций...?
je nocall
cmp cl, 0 ;нет ошибок..?
je results22,0_str divover,divoverlen ,34h ; вывод ошибкиPrintQuestion:ax, [Rem]bx, offset Ostatokbidec ;преобразование остатка10, 47_str Ostatok, Ostatoklen, 0F0h ;вывод остаткаdi, offset Operandsi, offset Resultmov64bx, offset chastnoe ;преобразование частногоBindec10, 7_str Chastnoe+1, Chastnoelen, 0F0h ;вывод частногоprintquestion:22,0_str mes_nocall,mes_nocalllen,34h ; сообщение о том, что не была нажата комбинация Alt-A:0,3bH, 24,0,24,7924,0_str type4,type4len,3Ah ; вывод подсказкиah,00h ; ввод символа16hal,'N' ; 'n'?allagain ; новый вводal,1Bh ; ESCPrintQuestionExitExit: 22,0
out_str nosign,nosignlen,034h ; сообщение о присутствии резидента с той же функцией, но другой сигнатурой
readkeyexit: 22,0
out_str noinst,noinstlen,034h ; сообщение об отсутствии резидента в памяти
readkey
Exit: setmode [oldmode]
mov ah,4ch ;Функция DOS-выход из программы
mov al,[ExCode];Возврат кода ошибки
int 21h ;Вызов DOS. Останов прогр.
END Start ;Конец программы/точка входа
Больше работ по теме:
Предмет: Информационное обеспечение, программирование
Тип работы: Контрольная работа
Новости образования
КОНТАКТНЫЙ EMAIL: [email protected]
Скачать реферат © 2017 | Пользовательское соглашение
ПРОФЕССИОНАЛЬНАЯ ПОМОЩЬ СТУДЕНТАМ