Ревич, Ю.В. Программирование микроконтроллеров AVR: от Arduino к ассемблеру

1 78 Часть 11 . Программирование микроконтроллеров АVR на вссемблере увидим, что ассемблер позволяет делать все то же самое, только гораздо быстрее и экономичнее по отношению к затраченным ресурсам. Контроллеры, тяготеющие к СISС-архитектуре (вроде семейства х5 1 ), изначально предоставляют программисту встроенные команды всех операций вплоть до аппа­ ратного деления, но на самом деле это мало помогает: кому требуется делить и перемножать числа, если и операнды и результаты ограничены скудным диапазо­ ном в пределах одного байта, а с учетом знака - в пределах всего 7 двоичных раз­ рядов? Требуется расширить диапазон хотя бы до 1 6 разрядов (хотя для операций с «плавающей точкой» и этого недостаточно) . Подробнее о многоразрядной арифметике в АVR мы поговорим в главе 8, а здесь остановимся лишь на стандартных командах и способах их применения. Арифме­ тические операции для АVR на первый взгляд могут показаться пользователю, привыкшему к бытовому представлению об арифметике, реализованными несколь­ ко странно, но на деле получается весьма стройная система. Не вызывают никаких возражений только очевидные операции: add R1 , R2 (сложить два регистра, записать результат в первый) и suЬ R1 , R2 (вычесть второй из первого, записать результат в первый) . Но если вдуматься, то и тут вопросов возникает множество: а что будет, если сумма превышает 255? Или разность меньше нуля? Куда девать остатки? Оказывается, все продумано - для учета переноса есть спе­ циальные команды: adc и sbc соответственно. Корректная операция сложения двух 1 6-разрядных чисел RНl : RLl и RН2 : RL2 будет занимать две команды: add RL1 , RL2 adc RH1 , RH2 Здесь переменные RLl и RL2 содержат младшие байты слагаемых, а RНl и RН2 - старшие . Если при первой операции результат превысит 255 , то перенос запишется во все тот же флаг переноса с и учтется при второй операции. Общий результат окажется в паре RНl : RLl . Совершенно аналогично выглядит операция вычитания . Постойте, но мы же вовсе не хотели складывать 1 6-разрядные числа! Мы хотели всего лишь сделать так, чтобы в результате сложения 8-разрядных чисел получился правильный результат, пусть он займет два байТа. На что нам тогда старший байт второго слагаемого, если его вообще в природе не существует? Конечно, можно сделать его фиктивным, загрузив в некий регистр нулевое значение, но это только кажется, что регистров у АVR много -аж 32 штуки, на самом деле они очень бы­ стро расходуются под разные надобности. И занимать целый регистр под фиктив­ ную операцию, пусть даже на один раз - как-то некрасиво. Потому «Экономная» операция сложения 8-разрядных чисел будет выглядеть так: add RL1 , R2 brcc add 8 inc RНl add 8 : Исходные слагаемые находятся в RLl и R2, а результат будет, как и ранее, в RНl : RLl . Отметим, что в старшем байте ( RНl ) в результате может оказаться только

RkJQdWJsaXNoZXIy MTExODQxMg==