47602 (Микропроцессор i8086/i8088), страница 4
Описание файла
Документ из архива "Микропроцессор i8086/i8088", который расположен в категории "". Всё это находится в предмете "информатика" из 1 семестр, которые можно найти в файловом архиве . Не смотря на прямую связь этого архива с , его также можно найти и в других разделах. Архив можно найти в разделе "курсовые/домашние работы", в предмете "информатика, программирование" в общих файлах.
Онлайн просмотр документа "47602"
Текст 4 страницы из документа "47602"
5) Получить промежуточный результат вычитанием кода символа «0»
6) Умножить на 10 результат
7) Если в ходе умножения получено переполнение, ошибка
8) Прибавить к результату промежуточный результат
9) Если обработаны не все символы, перейти к следующему символу. Переход к п.3
10) Если обработаны все символы, вернуть результат
Приложение
ПРИЛОЖЕНИЕ 1. ЛИСТИНГ ПРОГРАММЫ НА ЯЗЫКЕ ASSEBLER
. model small; модель памяти
. stack 100h; сегмент стека
. data; сегмент данных
MAXDIGITSequ16; максимальное количество символов
; для ввода целого числа
BUFFERSIZEequMAXDIGITS + 2 + 1; объем буфера ввода
bufferdbBUFFERSIZE dup(?) ; буфер ввода
ARRAYSIZEequ4; количество элементов массива / 4
dataArraydb4*ARRAYSIZE dup(?) ; массив данных
changeValueNodb? ; номер элемента массива для изменения
changeValuedb? ; новое значение элемента массива
parityCodedd? ; код четности
; переменные для работы генератора случайных чисел
rand_add69621
rand_mdd7FFFFFFFh
seeddd-1
;
; Сообщения для вывода на экран
;
welcomeMsgdb"Welcome to array parity checker. ", 0Dh, 0Ah
db0Dh, 0Ah
db"This program generates array with random values and calculates its parity code. ", 0Dh, 0Ah
db"Then you can change any array value and program will check parity code. ", 0Dh, 0Ah
db"Enjoy! ", 0Dh, 0Ah
db0Dh, 0Ah
db0Dh, 0Ah, "$"
errorMsgdb"Parity check error. ", 0Dh, 0Ah, "$"
okMsgdb"Parity check ok. ", 0Dh, 0Ah, "$"
dataMsgdb"Array data: $"
codeMsgdb"Parity code: $"
numberMsgdb"Enter array item number to change (0. .15): $"
valueMsgdb"Enter new value (0. .255): $"
uncorrectMsgdb"Incorrect number. $"
writelndb0Dh, 0Ah, "$"
byeMsgdb"Bye! ", 0Dh, 0Ah, "$"
itemSeparatordb" $"
. code; сегмент кода
.386; программа для процессора 80386
; - ----------------------------------------------------------------------------------------
; Главная программа
; - ---------------------------------------------------------------------------------------
start: movax, @data
movds, ax; настройка регистров
moves, ax;
andsp, not 3; выравнивание границы стека
; во избежание ошибки доступа к памяти
movax, 0003h; видеорежим 3, очистка экрана и установка курсора
int10h
movdx, offset welcomeMsg; вывести приветствие
callshowString
callfillArray; заполнить массив случайными данными
movcx, ARRAYSIZE * 4; рассчитать контрольное число
; и записать в parityCode
movsi, offset dataArray
movdi, offset parityCode
callsaveParityCode
callshowArray; вывести значения элементов массива
moveax, parityCode
callshowParityCode
callinputValueNo; запросить у пользователя номер
; элемента массива для изменения
callinputValue; запросить у пользователя новое значение
; элемента массива
callchangeItem; изменить значение элемента массива
callshowArray; вывести значения элементов массива
callgetParityCode; рассчитать контрольное число
callshowParityCode
cmpparityCode, eax
jeparityCode_notChanged
parityCode_Changed:
movdx, offset errorMsg; сообщение об изменении кода четности
callshowString
jmpmain_exit
parityCode_notChanged:
movdx, offset okMsg; сообщение о неизменности кода четности
callshowString
main_exit:
callwriteLine; перевод строки
callwriteLine; перевод строки
movdx, offset byeMsg; до свидания
callshowString
callwriteLine; перевод строки
movax, 4c00h; завершение выполнения программы
int21h
; - ---------------------------------------------------------------------------------------
;
; Заполнить массив случайными данными.
;
; Параметры: нет
;
; Возвращаемое значение: нет
;
; Модификация регистров: нет
;
; Глобальные переменные:
; [ref] dataArray - массив данных для заполнения
; [in] ARRAYSIZE - размер массива
;
; - ---------------------------------------------------------------------------------------
fillArrayproc
pusheax
pushcx
pushedi
movedi, offset dataArray; указатель на массив данных
movcx, ARRAYSIZE; размер массива
fillArray_loop:
callrand; генерировать случайное число в eax
cld; направление записи - вперед
stosd; записать в очередной элемент массива
loopfillArray_loop
popedi
popcx
popeax
ret
fillArrayendp
; - ----------------------------------------------------------------------------------------
; Генерация случайного числа.
;
; Параметры: нет
;
; Возвращаемое значение:
; eax - случайное положительное 32-битное число (от 0 до 2^31 - 2)
;
; Модификация регистров:
; eax
;
; Глобальные переменные:
; [in] rand_a – коэффициент a
; [in] rand_m – коэффициент m
; [ref] seed – последнее случайное число
;
; Примечание:
; Используется алгоритм, описанный в [Зубков С.В.] на стр.238.
; Линейный конгруэнтный генератор описывается формулой:
;
; I [j + 1] = (a * I [j] + c) mod m
;
; При правильно выбранных числах a и c эта последовательность возвращает
; все числа от нуля до m - 1 псевдослучайным образом и ее периодичность
; сказывается только на последовательностях порядка m.
; Классический стандартный генератор Льюиса, Гудмана и Миллера
; использует a = 16807 (7^5) при m = 2^31 - 1.
; Генераторы Парка и Миллера используют a = 48271 и a = 69621
; при том же m.
; Используем последний вариант.
; Значения a и m задаются в глобальных переменных rand_a и rand_m.
; - ---------------------------------------------------------------------------------------
randproc
pushedx
moveax, dword ptr seed; считать последнее случайное число
testeax, eax; проверить его
jsfetch_seed; если не - 1, функция еще ни разу не вызывалась
; и надо создать начальное значение
randomize:
muldword ptr rand_a; умножить на число a
divdword ptr rand_m; взять остаток от деления на 2^31 - 1
moveax, edx
movdword ptr seed, eax; сохранить для следующих вызовов
popedx
ret
fetch_seed:
pushds
push0040h
popds
moveax, dword ptr ds: 006Ch; считать двойное слово из области данных BIOS
; по адресу 0040: 006C - текущее число тактов таймера
popds
jmpshort randomize
randendp
; - ----------------------------------------------------------------------------------------
; Рассчитать контрольное число элементов массива и сохранить в переменной.
;
; Параметры:
; cx - размер массива
; ds: si - указатель на начало массива
; es: di - указатель на переменную-получатель
;
; Возвращаемое значение: нет
;
; Модификация регистров: нет
; - -----------------------------------------------------------------------------------------
saveParityCodeproc
pusheax
callgetParityCode; рассчитать контрольное число
mov [di], eax; сохранить результат
popeax
ret
saveParityCodeendp
; - ----------------------------------------------------------------------------------------
; Рассчитать контрольное число четности элементов массива.
; Если размер массива больше 32 байт, контрольное число
; рассчитывается методом суммирования - см. getParitySum
; Если размер массива не более 32 байт, контрольное число
; рассчитывается методом битовых масок - см. getParityBits
;
; Параметры:
; cx - размер массива
; ds: si - указатель на начало массива
;
; Возвращаемое значение:
; eax - 32-битное контрольное число
;
; Модификация регистров:
; eax
; - ----------------------------------------------------------------------------------------
getParityCodeproc
cmpcx, 32
jagetParityCode_sum
callgetParityBits
ret
getParityCode_sum:
callgetParitySum
ret
getParityCodeendp
; - -----------------------------------------------------------------------------------------
; Рассчитать контрольное число четности элементов массива методом битовых масок.
; Используется для массивов размером не более 32 байт.
; Для каждого байта определяется количество битов. Если оно четное, соответствующий
; бит контрольного числа устанавливается в 1, если нечетное - в 0.
; Нулевому байту массива соответствует нулевой бит контрольного числа и т.д.
;
; Параметры:
; cx - размер массива
; ds: si - указатель на начало массива
;
; Возвращаемое значение:
; eax - 32-битное контрольное число
;
; Модификация регистров:
; eax
; - ----------------------------------------------------------------------------------------
getParityBitsproc
pushebx
pushcx
pushsi
xorebx, ebx; обнулить результат
std; направление чтения - назад
addsi, cx; установить указатель на последний элемент массива
decsi
getParityBits_loop:
lodsb; прочитать байт данных в al
testal, al; проверить четность
jpgetParityBits_parity; если четность, перейти к установке флага cf
clc; сброс флага cf
jmpshort getParityBits_shift; перейти к формированию результата
getParityBits_parity:
stc; установить флаг cf
getParityBits_shift:
rclebx, 1; сдвиг влево на 1 бит с учетом флага cf
loopgetParityBits_loop
moveax, ebx; записать результат в eax
popsi
popcx
popebx
ret
getParityBitsendp
; - -----------------------------------------------------------------------------------------
; Рассчитать контрольное число четности элементов массива суммированием.
; Используется для массивов размером более 32 байт.
; Для каждого байта определяется количество битов. Если оно четное,
; контрольное число увеличиваем на 1.
;
; Параметры:
; cx - размер массива
; ds: si - указатель на начало массива
;
; Возвращаемое значение:
; eax - 32-битное контрольное число
;
; Модификация регистров:
; eax
;
; - ----------------------------------------------------------------------------------------
getParitySumproc
pushebx
pushcx
pushsi
xorebx, ebx; обнулить результат
cld; направление чтения - вперед
getParitySum_loop:
lodsb; прочитать байт данных в al
testal, al; проверить четность
jnpgetParitySum_next; если не четность, продолжить
incebx; увеличить результат на 1
getParitySum_next:
loopgetParitySum_loop
moveax, ebx; записать результат в eax
popsi
popcx
popebx
ret
getParitySumendp
; - -----------------------------------------------------------------------------------------
; Вывод на экран элементов массива.
;
; Параметры: нет
;
; Возвращаемое значение: нет
;
; Модификация регистров: нет
;
; Глобальные переменные:
; [in] dataMsg – сообщение
; [in] dataArray – массив данных
; [ref] buffer – буфер преобразования числа в строку
; [in] itemSeparator – разделитель элементов массива
; [in] ARRAYSIZE - размер массива
; - ----------------------------------------------------------------------------------------
showArrayproc
pusheax
pushcx
pushdx
pushsi
pushdi
movdx, offset dataMsg; сообщение
callshowString
xoreax, eax; обнулить аккумулятор
movsi, offset dataArray; читать данные из массива данных
movdi, offset buffer
movcx, ARRAYSIZE * 4; размер массива, байт
showArray_loop:
cld; направление чтения - вперед
lodsb; прочитать байт данных в al
callint2dec; преобразовать в строку
movdx, offset buffer
callshowString; вывести на экран