Здравствуйте, Посетитель - 366118!
1) Теория: для выяснения, является ли число четным, достаточно знать младший бит младшей цифры числа (0 - четное, 1 - нечетное).
Кроме того, для выяснения, является ли сумма чисел четным числом, достаточно сложить младшие биты всех чисел по модулю 2, т.е. применить операцию XOR
Т.о., для ответа на вопрос, является ли сумма чисел четным числом, достаточно найти сумму по модулю 2 младших бит младших (последних) цифр всех чисел.
Полученное значение (0 или 1), умноженное на 2, используем, как индекс в таблице адресов строк, для вывода соответствующего сообщения.
2) В программе используется описанная ниже структура данных, необходимая для работы функции 0ah, для ввода строки символов.
sBuf db 80 ;максимальная длина строки 79+1 для кода 0dh
sLen db ? ;реальная длина введенной строки, заносится после отработки (не используем)
sNum db 80 dup (?) ;собственно строка
3) Общая блок-схема:
Блок-схема подпрограммы:
Блок-схема в виде
DOC-документа4) Программа ждет ровно пять чисел в любом виде: хоть в одной строке, хоть в нескольких.
Концом числа считаются любые символы-нецифры (например, пробел или конец строки), все нецифры перед числом игнорируются.
Перед числом допускается знак минус.
Т.к. программа использует только последнюю цифру, то ограничений на длину числа нет. Единственно, общая длина строки не должна превышать 79 знаков.
После ввода чисел, программа выводит сообщение о четности суммы в виде:
Sum is odd для нечетной суммы или
Sum is even для четной
Примерный результат работы:
5) Программа написана универсально, будет работать на любом х86-м процессоре, компилируется и tasm-ом, и masm-ом
6) Код программы:
[code h=200]COUNT equ 5 ;число ожидаемых чисел
cseg segment para public 'code' ;сегмент кода
assume cs:cseg, ds:dseg, es:dseg, ss:sseg ;свяжем сегментные регистры с указанными сегментами
start: mov ax, dseg ;загрузим сегментные регистры DS, ES
mov ds, ax ; адресом сегмента данных
mov es, ax
lea dx, sEnter ;приглашаем ввести числа
mov ah, 9
int 21h
xor di, di ;здесь будем накапливать сумму последнего бита вводимых чисел
mov cx, COUNT ;число вводимых чисел
StrLoop: ;цикл по вводимым строкам
lea dx, sBuf ;адрес структуры для ввода строки
mov ah, 0ah ;вводим строку с 1-5 числами
int 21h
lea si, sNum ;адрес введенной строки
NumLoop: ;цикл по числам в строке
call GetLastDigit ;получаем младший бит младшей цифры числа
jc StrLoop ;если дошли до конца строки, то вводим следующую
xor di, ax ;складываем младший бит по модулю 2 !
loop NumLoop ;на следующее число в строке
;введены и обработаны 5 чисел !
;выводим сообщение о четности/нечетности суммы
lea dx, sSum
mov ah, 9 ;'Sum is'
int 21h
;di = 0 - сумма четная, di = 1 - нечетная
shl di, 1 ;умножим на 2, чтобы адресовать слова
mov dx, pType[di] ;получим адрес соответствующего сообщения из таблицы
int 21h ;закончим вывод (ah осталось равным 9)
lea dx, sPress
mov ah, 9 ;выведем 'Press any key'
int 21h
mov ah, 8
int 21h ;подождем нажатие на клавишу, чтобы окно не закрылось сразу
mov ax, 4c00h
int 21h ;выход в ДОС
;подпрограмма получения в AX младшего бита последней цифры числа
;во флаге FC признак того, найдено ли число (C=0 - найдено, С=1 - не найдено)
;на входе: si - адрес числовой строки.
;числа разделяются любым нециферным кодом, в конце строки код 0dh
;перед числом допускается знак -
GetLastDigit proc
;сначала найдем начало числа
lodsb ;читаем очередной символ
cmp al, 0dh ;конец строки?
je Eol ;значит, ничего больше нет!
cmp al, '-' ;минус - начало числа
je NumFound
cmp al, '0'
jb GetLastDigit ;нецифры пропускаем
cmp al, '9'
ja GetLastDigit
NumFound: ;ищем последний символ числа
mov ah, al ;сохраним текущий (а может он последний?)
lodsb ;читаем следующий
cmp al, '0'
jb NumEnd ;<0 (нецифра) - конец числа
cmp al, '9'
jbe NumFound ;0<=al<=9 (цифра) - продолжаем искать конец числа
NumEnd: ;нашли конец числа
dec si ;уменьшим на 1 для последующего анализа, что важно для анализа кода 0dh
mov al, ah ;последний символ
cmp al, '-' ;проверим на единственный минус
je GetLastDigit ;тогда игнорируем и ищем в строке начало следующего числа
and ax, 1 ;оставляем только младший бит !
clc ;признак того, что число найдено
ret
Eol: ;конец строки
mov ah, 2
mov dl, 0ah ;перейдем на экране на следующую строку для ввода следующей числовой строки
int 21h ; или вывода результата (код 0dh уже выведен после отработки функции 0ah)
stc ;признак того, что дошли конца строки, чисел больше нет
ret
GetLastDigit endp
cseg ends
;сегмент стека
sseg segment para stack 'stack'
dw 100h dup (?)
sseg ends
;сегмент данных
dseg segment para public 'data'
sEnter db 'Enter 5 numbers: $' ;строка - приглашение для ввода чисел
sSum db 0ah,'Sum is $' ;начало строки - сообщения о результате
pType dw sEven, sOdd ;таблица адресов строк сообщений
sOdd db 'odd$' ;нечетная
sEven db 'even$' ;четная
sPress db 0dh,0ah,'Press any key$';ждем нажатия на клавишу
;структура для ввода строки
sBuf db 80 ;максимальная длина строки 79+1 для кода 0dh
sLen db ? ;реальная длина введенной строки (не используем)
sNum db 80 dup (?) ;собственно строка
dseg ends
end start ;конец программы с указаниием точки входа
[/code]