Помилки і неприємності Bascom

1 Директиви $ BAUD і $ CRYSTAL активізується тільки при використанні команд PRINT, INPUT Увага Якщо в тексті програми не застосовуються оператори PRINT, INPUT, то ініціалізація не виконується – в таймер не завантажується значення коефіцієнта ділення, що не инициализируются регістри SCON і PCON (див соотв Розділ)

2 Усередині програмної конструкції IF . End If не допускається використання оператора Return:

Правильно: Неправильно:

If Tmp = 0 Then Goto Lcd_pe

End If

Lcd_pe:  Return

If Tmp = 0 Then Return

End If

При наявності запису Return відбувається порушення балансу стека і програма зависає Компілятор повідомлень про такий помилково не дає

3 Функція Fusing працює правильно, якщо розмір буфера, в який поміщається отформатированное число (у форматі з плаваючою точкою), дещо більше, ніж число знаків результату Принаймні, потрібно довжина буфера дорівнює сумі: максимальна кількість чисел цілої частини + максимальну кількість чисел дробової частини + десяткова точка + знак полярності (Мінус для негативних чисел) У прикладах Bascom не дарма рекомендується застосовувати буфер (символьну змінну) довжиною 16 байт В інших випадках підсумовування двох символьних змінних потрібно використовувати буфер довжиною не менше суми максимальної довжини першої змінної + довжина буфера, що містить другу змінну Може бути це і не так – перевірте самі

4 При використанні функції Fusing потрібно так будувати програму, щоб не доводилося виводити числа, які не можуть бути представлені в призначеному форматі Краще якщо вони будуть не більше і не менше ніж потрібно Перевіряйте, що будете перетворювати і, як виходить у всьому діапазоні преутворених чисел Застосовуйте директиву $ NONAN

5 Інша неприємність функції Fusing полягає в тому, що при негативної полярності преутвореного числа знак мінус входить в результат форматування, таким чином, одне і теж значення позитивної і негативної полярності виглядає по різному Існує два способи боротьби з цим явищем: або робити все числа на вході у перетворення позитивними, а знак обробляти окремо, або застосовувати різні формати для чисел різної полярності (для негативних чисел на один знак зліва більше)

6 Ще одна неприємність функції Fusing повязана з тим, що зайві нулі зліва відкидаються (замість значення 00345 при масці # # # # # Ми отримуємо 345) Боротися з цим можна тільки, контролюючи довжину результату і дописуючи відсутні нулі В оновленій версії (10019 і старше) цей недолік виправлено введенням додаткових лідируючих нулів Додана функція округлення

7 При складанні символьної змінної з декількох частин можливий випадок, коли, приймаюча дані змінна, буде перекрита по довжині і наступна за нею змінна буде зіпсована Це відбувається тому, що програма копіює не вміст змінної джерела, яке не настільки велике, як ви розраховуєте, а всю змінну, такої довжини, як вона була оголошена Боротися з цим можна тільки збільшенням довжини змінної, що приймає символьні дані Необхідну ступінь запасу по довжині можна визначити, спостерігаючи в відладчик за кількістю зіпсованих осередків При цьому, потрібно мати на увазі, що при виведенні довжина символьного значення числової змінної може змінюватися в значних межах (залежить від значення преутвореного числа) Також потрібно враховувати, що довжина внутрішнього буфера Bascom, в якому формується символьне значення числа, може досягати 16 при виведенні значення змінної типу Single Якщо за приймаючої дані змінної розташовується стек, то неминучий фатальний результат цієї помилки компілятора

8 Довжина рядка вихідного тексту програми не повинна перевищувати 255 символів, а реально виходить навіть менше Спроби перевершити її приводять до фатального збою компілятора Більш того, це не дає можливість записати в один рядок деякі необхідні речі Наприклад, висновок текстового повідомлення без символів ВК ПС:

Printbin &ampH42 &ampH41 &ampH42 &ampH43 &ampH44 &ampH45 &ampH46 …  &ampH4A &ampH4B

Або формування довгої строкової змінної:

Out_buf = &quotS&quot + Str(rang) + &quotL&quot +Str(udac) + &quotT&quot … + Chr(13) + Chr(10)

9 Виконуючи операцію обчислення (очевидно, якісь інші теж), можна призначити в якості приймача даних будь-який регістр (будь-яку змінну) Однак якщо довжина приймача не збігається з довжиною результату, можуть виникнути неприємності Наприклад, операція, що дає двобайтовий результат, будучи записана в змінну типу Long, модифікує тільки два молодший байти, а старші розряди залишаться без зміни Нижче наведено два приклади, що дають різні результати У першому прикладі є очевидна помилка, яку компілятор не виявляє, і, напевно, не повинен виявляти

Dim Byt As Byte, Byt1 As Byte, Wrd As Word, Wrd1 As Word, Lng As Long Byt = 10: Byt1 = 15: Wrd = & H1234 призначимо числа

Wrd = Byt * Byt1 твір запишемо в двухбайтное число

Printhex Wrd результат Wrd = 1296h – тільки в молодших розрядах

Wrd = 16 : Wrd1 =  32 : Lng = &amph12345678

Lng = Wrd * Wrd1 твір запишемо в четирехбайтное число

Printhex Lng результат Lng = 12340200h – знову в молодших розрядах

У другому прикладі отримуємо правильний результат за рахунок прийому результату операції в регістр, довжина якого відповідає довжині видаваних даних, і додаванні операції перетворення змінних

Byt = 10: Byt1 = 15: Wrd = & H1234 призначимо числа

Byt = Byt * Byt1 твір запишемо в однобайтное число Wrd = Byt: Printhex Wrd результат Wrd = 0096h – правильний Wrd = 16: Wrd1 = 32: Lng = & h12345678

Wrd = Wrd * Wrd1 твір запишемо в двухбайтное число

Printhex Lng результат Lng = 00000200h – знову правильно

Проте, навіть це, безумовно, шкідливе явище можна іноді використовувати і з користю

10 Довжина результату арифметичних операцій Bascom дорівнює довжині операндів (якщо вони одного типу), що дуже незручно при необхідності виконання операцій цілочисельного множення, наприклад, 16 на 16 розрядів, коли бажано отримати 32-розрядний результат Щоб отримати повноцінний результат (32 розряду), доводиться множення виконувати в 32-розрядних регістрах (Змінних) У підсумку, час обчислення добутку збільшується в десятки разів Можна застосовувати кілька полегшений варіант – використовувати, хоча б один операнда, рівний по довжині необхідного результату, як у наведеному нижче прикладі

Wrd = 50 : Lng =

2000

Один з операндів возмем четирехбайтний

L ng = Wrd * Lng

Твір запишемо в четирехбайтное число

Printhex Lng

Результат Lng = 100000

11 Не всі оператори Bascom можуть працювати з індексованими змінними, визначеними як елементи масиву При цьому компілятор не видає ніяких повідомлень Власне кажучи, оператори працюють, але тільки з першим елементом, адреса якого збігається з адресою масиву Щоб забезпечити можливість роботи з будь-яким елементом масиву слід застосовувати проміжний буфер, куди вивантажувати дані з масиву перед обробкою або поміщати після обробки і перед записом в масив Наприклад, оператор SWAP Ar (1), Ar (3) працює неправильно, тому замість нього слід записувати рядок із трьох операторів: Temp = Ar (1): Ar (1) = Ar (3): Ar (3) = Temp Подібне рішення, насправді, не збільшує розмір одержуваного коду, тому що всередині операторів, що працюють з масивами, роблять аналогічні пересилки

12 У секції, определеной оператором DATA, константи (числа) і символьні значення адрес (мітки) неможливо записати у вигляді символічного імені Потрібно записувати тільки цифри Головна неприємність цього полягає в тому, що компілятор не дає повідомлення про помилку, а замість очікуваних значень записує нулі

13 Мається помилка в бібліотеці оператора LOOKUP при зчитуванні четирехбайтний числа з таблиці Як тільки індекс (зміщення за таблицею) перевищує 63 (3FH), починається проявлятися помилка (невірно обчислюється адреса розташування константи через те, що множення зсуву на чотири робиться неправильно) У Останніх версіях схоже усунуто

14 Символ двокрапки (:) неприпустимий у коментарях Якщо таке трапляється, компілятор дає повідомлення про неіснуючі помилки і починає шукати мітки з символами, розташованими в одному рядку до знака двокрапки А також символи <", ">” і ключові слова, що позначають деякі логічні операції

Справедливості заради треба сказати, що в останніх версіях (починаючи з 120) помилок стало набагато менше, а фатальних непомічене взагалі

Джерело: МЛКуліш, ДОВІДНИК З ПРОГРАМУВАННЯ BASCOM-8051, Краснодар 2001

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*