4. Відладка та випробування розробленого програмного забезпечення
Алгоритм визначення CRC реалізований в процедурі CalcCRC. Перед викликом цієї процедури необхідно в регістри записати початкові дані - сегментний регістр ES повинен містити сегмент в якому розташований масив, регістр DX - зміщення початку масиву всередині сегмента, BX - довжина масиву.
Програма виконує наступні операції на вибір користувача: обчислення CRC масиву і запис результату в змінну, перевірка цілісності масиву - повторне обчислення CRC і порівняння обчисленого значення з записаним, спотворення масиву - оборотне зміна одного біта перевірочного масиву.
Для обчислення CRC, викликається процедура CalcCRC, а результат виконання зберігається у змінній result.
При перевірці цілісності, викликається процедура CalcCRC, а результат виконання порівнюється зі збереженим у змінній result. У випадку розбіжності, виводиться повідомлення про помилку. При збігу значень (цілісність даних не порушена) повідомлення не виводиться і користувач повертається в головне меню.
Спотворення масиву використовується для тестування програми і демонстрації роботи.
Для тестування в програмі передбачений перевірочний масив даних довжиною 32 байта. При спотворенні, інвертується молодший біт першого слова масиву.
Висновок
Асемблер є символічним аналогом машинної мови. З цієї причини програма, написана на асемблері, повинна відображати всі особливості архітектури мікропроцесора: організацію пам'яті, способи адресації операндів, правила використання регістрів і т. д. З-за необхідності врахування подібних особливостей асемблер унікальний для кожного типу мікропроцесорів.
У цій роботі розглянуті основні етапи програмування на асемблері, реалізований алгоритм виконання поставленого завдання, а також виконана трансляція коду у виконуваний файл.
Література
1.Абель П. Основи программирования/ Пер. с англ. Ю. В. Сальниковая.- М.: Висш. Шк. 1992г. - 447с.: ил.
2.А. Жуков, А. Авдохин «Assembler».-Спб: БХВ - Петербург, 2002..
3.Архитектура ввода-вывода персональных ЭВМ IBM РС Под редакцией Ю. С. Лукача (C) Инженерно-техническое бюро, 1990
4.В. Юров «Assembler» Практикум.-Спб.:Питер, 2001.
5.В. Юров «Assembler» Учебник.-Спб.:Питер, 2001.
6.Зубков С. В. Ассемблер для Dos, Windows и Unix - «Питер», в 2004 г.
7.Ирвин, Кип. Язык Ассемблера для процессоров Intel, 3-е издание: Пер. с англ. - М.: Издательский дом «Вильямс», 2002.-616с.: ил. - Парал. Тит. Англ.
8.Использование Turbo Assembler при разработке программ / Сост. А. А. Чекатков.-Киев:Диалектика,1995.-228с
Додаток А
Текст програми
MODEL SMALL
;*************************************************
; Сегмент стека
;*************************************************
_Stack SEGMENT WORD 'STACK'
DB 200h DUP (?)
_Stack ENDS
;*************************************************
; Сегмент тестового масиву
;*************************************************
DataSeg SEGMENT WORD 'DATA'
TestTab DB 32 DUP (\
00h, 01h, 02h, 03h, 04h, 05h, 06h, 07h, \
08h, 09h, 0Ah, 0Bh, 0Ch, 0Dh, 0Eh, 0Fh, \
00h, 01h, 02h, 03h, 04h, 05h, 06h, 07h, \
08h, 09h, 0Ah, 0Bh, 0Ch, 0Dh, 0Eh, 0Fh \
)
DataSeg ENDS
;*************************************************
; Сегмент змінних
;*************************************************
_Data SEGMENT WORD 'DATA'
;*************************************************
FSelMsg DB 13,10, 'Виберіть дію:', 13,10, \
13,10, '1-Визначити CRC ', 13,10, \
'2-Перевірити масив ', 13,10, \
'3-Спотворити масив ', 13,10, \
'4-Вихід ', 13,10, \
'$'
ByeStr DB 13,10, 'Для продовження натисніть будь-яку клавішу. $'
ErrorString DB 13,10, 'Помилка введення', 13,10, '$'
ErrorResult DB 13,10, 'Дані спотворені. CRC8 порушена. ', 13,10,' $ '
;*************************************************
BegSeg DW (?); Сегмент перевірочного масиву
BegOffs DW (?); Початок перевірочного масиву
Result DW (?); Результат обчислення
FuncNum DB (?); Обрана операція
_Data ENDS
;*************************************************
; Сегмент програми
;*************************************************
. CODE
;*************************************************
call cls; Очищення екрану
call SetDATSeg; Завантаження адреси сегмента змінних
call SetArrSeg; Установлення покажчика сегмента масиву
; Головне меню
Mnu: call SelectFunction; Вибір операції
call cls; Очищення екрану
mov AL, FuncNum;
Mnu1: cmp AL, 1; Визначення парності
jne Mnu2
; Установка параметрів
mov DX, OFFSET TestTab; Зміщення початку масиву
mov BX, 30; Розмір перевіряється блоку даних
; Call TestOdd
call CalcCRC
mov Result, AX; Збереження результату
;*******************************
Mnu2: cmp AL, 2; Визначити парність і порівняти з перед.
jne Mnu3
mov DX, OFFSET TestTab; Зміщення початку масиву
mov BX, 30; Розмір блоку даних
call CalcCRC
cmp Result, AX
je Mnu2End
; Результат не співпав. Дані спотворені. Видати повідомлення про помилку
mov DX, OFFSET ErrorResult
mov AH, 9h
int 21h; Висновок повідомлення про помилку
mov DX, OFFSET ByeStr; Висновок запрошення
mov AH, 9h
int 21h
mov AH, 0Ch
mov AL, 01h
int 21h; Очікування натискання будь-якої клавіші
Mnu2End:
call cls
jmp Mnu
;*******************************
Mnu3: cmp AL, 3; Спотворення масива (перший байт)
jne Mnu4
mov DI, OFFSET TestTab
mov AX, ES: [DI]
xor AX, 1; Інвертуємо молодший біт
mov ES: [DI], AX
;*******************************
Mnu4: cmp AL, 4; Вихід з програми
jne Mnu
;*******************************
jmp Exit
; Завершення програми
; Exit:
; Призупинити перед виходом
mov DX, OFFSET ByeStr;? Натисніть клавішу??
mov AH, 9h
int 21h
mov AH, 0Ch
mov AL, 01h
int 21h
Exit:; Вихід
mov AH, 4Ch
int 21h
;*************************************************
; Друк нового рядка
NewStr:
mov AH, 02h
mov DL, 0Dh
int 21h
mov DL, 0Ah
int 21h
ret
;*************************************************
include cls.prc
;*************************************************
; Головне меню
SelectFunction: ; 1.1.Вивод рядка меню
mov DX, OFFSET FSelMsg
mov AH, 9h
int 21h
; 1.2.Вибор функції
mov FuncNum, 0
call input10; Прочитуємо номер пункту меню
mov FuncNum, AL; Зберігаємо номер обраної функції
ExitSF: ret
;*************************************************
; Підпрограма введення числа
input10:
push BX; Зберігаємо регістри
push DX
push CX
mov DX, 0; Обнуляємо регістр зберігання результату
InputChar:
clc
mov AH, 0Ch
mov AL, 1
int 21h; Прочитуємо символ з луною
cmp AL, 13d
je ExitI10; Якщо його код 13? кінець введення
cmp AL, 0 "
jb ErrInput; Якщо код менше коду символи 0 помилка вводу
cmp AL, '9 '
jg ErrInput; Якщо код більше коду символу 9 помилка вводу
clc
sub AX, 30h; Отримуємо з коду символу число
mov CX, 0
mov CL, AL
mov AX, DX
mov BX, 10
mul BX; Множимо на 10 вже накопичений результат
add AX, CX; Додаємо зовсiм небагато
mov DX, AX; Зберігаємо результат
jmp InputChar
ErrInput:
Stc; У випадку помилки введення встановлюємо прапор
ExitI10:
mov AX, DX; Переносимо результат в регістр повернення
pop CX
pop DX
pop BX; Відновлюємо регістри
ret
;*************************************************
; Установка покажчика на сегмент змінних
SetDATSeg:
push AX
mov AX, _Data
mov DS, AX
pop AX
ret
;*************************************************
; Установка покажчика на перевірочний масив
SetArrSeg proc
push AX
mov AX, DataSeg
mov ES, AX
pop AX
ret
SetArrSeg endp
;*************************************************
; Процедура обчислення CRC16
; ES - сегмент масиву
; DX - адресу початку масиву
; BX - довжина блоку даних
; AX - результат обчислень
;*************************************************
CalcCRC proc
push CX; \
push BX; - збереження регістрів
push DI; /
push DX
mov DI, DX; Завантаження індексу початку масиву
mov DX, 8
mov CX, BX; Установка лічильника циклу
shl CX, 1; \
shl CX, 1; - CX = CX * 8
shl CX, 1; /
mov AX, 65535; Очищення регістра результату
mov BX, ES: [DI]
CRNext: loop CRNextTest; Цикл за словами масиву
pop DX
pop DI; \
pop BX;-відновлення регістрів
pop CX; /
ret
CRNextTest:
push AX
mov AX, BX
and AX, 1b
jz Shift
pop AX
xor AL, 31h
push AX
Shift: mov AX, DX
jz NewWord
shr BX, 1
dec DX
jmp EndShift
NewWord:
mov DX, 8
inc DI
mov BX, ES: [DI]
EndShift:
pop AX
jmp CRNext
CalcCRC endp
;*************************************************
END
;*************************************************