Іноді при написанні програм потрібно виконати прості арифметичні операції з багатобайтові числами. З однобайтном числами все просто, додавання і віднімання виконуються стандартними командами addwf, addlw, subwf, sublw, для багатобайтові чисел доведеться писати невеликі підпрограми. Я буду розповідати тільки про цілочисельні операції, без дрібних частин.
У тексті статті і в коді я буду використовувати приставки до назв регістрів, щоб легше розібрати старші і молодші регістри чисел. Обмежуся чотирибайтових числами, відповідні приставки, починаючи від старшого регістра до молодшого: HH, HL, LH, LL.
Розглянемо найпростіший варіант складання двухбайтное і однобайтном числа. Двухбайтное число представлено регістрами varLH (старший байт) і varLL (молодший байт), однобайтное число в регістрі tmpLL. Спочатку складаються молодші регістри обох чисел, це varLL і єдиний реєстр tmpLL в разі однобайтном числа. Далі виконується перевірка на можливу переповнення регістра varLL в результаті складання (перенесення старшого біта), за допомогою біта C регістра STATUS. Якщо було переповнення (C = 1), інкрементіруем старший регістр varLH, в іншому випадку (C = 0) нічого не робимо. У разі трехбайтного числа (varHL, varLH, varLL), після инкремента регістра varLH, також необхідно виконати перевірку на його переповнення за допомогою команди incfsz. При виникненні переповнення, відповідно інкрементіруем найстарший регістр varHL.
При додаванні багатобайтові чисел, наприклад двобайтових (varLH, varLL) + (tmpLH, tmpLL), як було сказано, спочатку складаються молодші регістри varLL і tmpLL, і перевіряється переповнення регістра varLL в результаті складання, при наявності якого инкрементируются старший регістр varLH. Далі складаються старші регістри varLH і tmpLH, тут перевірку не робимо, в разі якщо заздалегідь відомо, що результат складання не перевищить двухбайтное числа (значення 65535). Перевірку переповнення регістра varLH, необхідно зробити, якщо перше число трехбайтное (varHL, varLH, varLL) і результат складання перевищує число 65535. В принципі все також, що і при додаванні десяткових чисел стовпчиком на папері.
Нижче представлені коди підпрограм для різних варіантів складання. Числа необхідно попередньо завантажити в відповідні регістри до виклику підпрограми, також слід врахувати, що результат складання не повинен перевищувати максимального значення для найбільшого доданка, інакше ми отримаємо неправильний результат. Наприклад, при додаванні двухбайтное і однобайтном числа, результат не повинен перевищувати максимального значення для двухбайтное числа - 65535:
хм. У AVR для складання багатобайтові чисел є зручна команда - adc - складання двох чисел з урахуванням прапора перенесення. Якщо попереднє складання закінчилося переповненням, то перенесення автоматично додасться до двох складовою.
Наприклад для чотирьох байтного складання вийде:
add tempLL, varLL
adc tempLH, varLH
adc tempHL, varHL
adc tempHH, varHH
Але при додаванні чисел різних розмірів це не котить, і робити доведеться те ж саме що і в піках))
На мою в AVR можна складати числа різних розмірів з урахуванням перенесення, наприклад, складання чотирибайтових і двухбайтное числа:
add varLL, tmpLL
adc varLH, tmpLH
adc var HL, nol
adc varHH, nol
де nol - регістр, куди попередньо записується число 0
У піках для складання є тільки 2 команди: addwf - складання вмісту акумулятора з будь-яким регістром і addlw - складання вмісту акумулятора з константою, те ж саме і для вирахування.
Не забуваємо що в піках всього 35 інструкцій замість сотні команд у AVR)
Так можна робити, якщо не шкода виділяти зайвий регістр під зберігання нуля. Все залежить від складності програми, і іноді кожен регістр буває на рахунку.
Красені математики, програми класні, для власного використання то що треба, Дякую за потрібну інфу.