Начну с того вопроса, который поможет вам с
ориентироваться с вашей задачей.
Знаете ли вы язык СИ? Если да ,то проще конечно же организовать вам задачу
деления или умножения больших чисел именно на СИ. Тогда задача ваша будет
не сложнее чем 234553/3445667=х. Ну а если же у вас стоит задача экономить при
этом память МК, увеличить в 10-100 раз быстродействие, тогда вам следует
обучится ассемблерному языку для МК AVR. Поверьте,он вам пригодится. Не один
СИшник не обходится без ассемблера, если стоит задача быстродействия и
экономии.
На мой взгляд это большой минус ATmel, за то что те не продумали аппаратный
делитель для своих 8-разрядных МК.
Начну с того как оформить макрос и что это такое. Макросы - это та часть
программы, которую вы когда-то написали или кто-то написал за вас, отладили и
сохранили в виде отдельного файла (документ, исходный код с текстовым
расширением). И в следующий раз когда вам нужно обратится к этой программе, вы
в ассемблерном своем проекте, только указываете ссылку на тот макрос. Вы так
делаете когда начинаете писать программу, помните .include
"m8535def.inc" этим вы подключаете библиотеку для данного МК. То
же самое вы делаете с вновь созданным макросом. Поверьте,это очень нужная и
удобная вещь, поэтому стоит сейчас разобраться. На примере операции сложения
двух 32 разрядных чисел, заодно рассмотрим создания макроса. Сложения 32 разрядных
чисел формат: 32р+32р=32р
Вы можете вставить этот фрагмент программы в свою программу,но от этого читабильность программы снизится. А можете скопировать этот текст и создать текстовый документ в блокноте с расширением .inc. Сохранить его по адресу C:\Program Files\Atmel\AVR Tools\AvrAssembler2\Appnotes. А потом подключать данную программу одним словом в любом месте вашей программы директивой .include [название файла]. А вызов самой подпрограммы осуществляется уже в основном тесте программы новоиспеченной командой add32. (Заметте, вы сами придумываете ее название при помощи директивы .macro add32).
Все последующие примеры аналогичны в создании и вызове макросов.
rol dd32u0 ;shift left dividend rol dd32u1 rol dd32u2 rol dd32u3 dec dcnt32u ;decrement loop counter breq Com32 ;if counter zero invert result rol drem32u0 ;shift dividend into remainder rol drem32u1 rol drem32u2 rol drem32u3 sub drem32u0,dv32u0 ;remainder = remainder - divisor sbc drem32u1,dv32u1 sbc drem32u2,dv32u2 sbc drem32u3,dv32u3 brcc d32u_loop ;clear carry to be shifted into res add drem32u0,dv32u0 ;if result negative adc drem32u1,dv32u1 ; restore remainder adc drem32u2,dv32u2 adc drem32u3,dv32u3 rjmp d32u_loop ; set carry to be shifted into res Com32: com dres32u0 ; (com result) com dres32u1 com dres32u2 com dres32u3 Return32u: ret .endmacro
Перевод32 разрядных
чисел из шестнадцатиричной системы в десятичную
формат: 32рHEX-->32рBCD
;*************************************************************************** ;* ;* Bin4BCD == 32-bit Binary to BCD conversion [ together with Bin2BCD ] ;* ;* fbin0:fbin1:fbin2:fbin3 >>> tBCD0:tBCD1:tBCD2:tBCD3:tBCD4 ;* hex dec ;* r18r19r20r21 >>> r20r21r22r23r24 ;* ;*************************************************************************** .macro HEx_BCD32
.def fbin0 =r18 ; binary value byte 0 (LSB) .def fbin1 =r19 ; binary value byte 1 .def fbin2 =r20 ; binary value byte 2 .def fbin3 =r21 ; binary value byte 3 (MSB) .def tBCD0 =r20 ; BCD value digits 0 and 1 (same as fbin2) .def tBCD1 =r21 ; BCD value digits 2 and 3 (same as fbin3) .def tBCD2 =r22 ; BCD value digits 4 and 5 .def tBCD3 =r23 ; BCD value digits 6 and 7 .def tBCD4 =r24 ; BCD value digits 8 and 9 (MSD)
clr tBCD3 ;initial highest bytes of result ldi tBCD4,0xfe bnbcd_loop:
subi tBCD0,-0x33 ;add 0x33 to digits 1 and 0 sbrs tBCD0,3 ;if bit 3 clear subi tBCD0,0x03 ;sub 3 sbrs tBCD0,7 ;if bit 7 clear subi tBCD0,0x30 ;sub $30 subi tBCD1,-0x33 ;add 0x33 to digits 3 and 2 sbrs tBCD1,3 ;if bit 3 clear subi tBCD1,0x03 ;sub 3 sbrs tBCD1,7 ;if bit 7 clear subi tBCD1,0x30 ;sub $30 subi tBCD2,-0x33 ;add 0x33 to digits 5 and 4 sbrs tBCD2,3 ;if bit 3 clear subi tBCD2,0x03 ;sub 3 sbrs tBCD2,7 ;if bit 7 clear subi tBCD2,0x30 ;sub $30 lsl fbin0 rol fbin1 ;shift lower word rol tBCD0 ;through all bytes rol tBCD1 rol tBCD2 rol tBCD3 rol tBCD4 brmi binbcd_loop ;7 shifts w/o correction of MSD rol fbinH ;since Bin2BCD fbinH = 0xff brcc binbcd_ret ;so as to do 16_lsl in total subi tBCD3,-0x33 ;add 0x33 to digits 7 and 6 sbrs tBCD3,3 ;if bit 3 clear subi tBCD3,0x03 ;sub 3 sbrs tBCD3,7 ;if bit 7 clear subi tBCD3,0x30 ;sub $30 subi tBCD4,-0x03 ;add 0x03 to digit 8 only sbrs tBCD4,3 ;if bit 3 clear subi tBCD4,0x03 ;sub 3 rjmp binbcd_loop .endmacro
;***** Code mpy16s: clr m16s3 ;clear result byte 3 sub m16s2,m16s2 ;clear result byte 2 and carry ldi mcnt16s,16 ;init loop counter m16s_1: brcc m16s_2 ;if carry (previous bit) set add m16s2,mc16sL ;add multiplicand Low to result byte 2 adc m16s3,mc16sH ;add multiplicand High to result byte 3 m16s_2: sbrc mp16sL,0 ;if current bit set sub m16s2,mc16sL ;sub multiplicand Low from result byte 2 sbrc mp16sL,0 ;if current bit set sbc m16s3,mc16sH ;sub multiplicand High from result byte 3 asr m16s3 ;shift right result and multiplier ror m16s2 ror m16s1 ror m16s0 dec mcnt16s ;decrement counter brne m16s_1 ;if not done, loop more .endmacro
Таким образом если вам нужно осуществить вот такую операцию 2345432/24545*2349-2345678789=х , то вам достаточно ввести все эти числа в соответствующие регистры, а затем подряд расставить макрокоманды
div32
mul32
sub32
Только следите за тем, какие регистры используются в каждой подпрограмме,для этого в начале каждой микропрограммы проведенной выше есть некая подсказка вначале, такого вида
;* Mul32 == 32x32 Bit Unsigned Multiplication ;* ;* mp32uL::mp32uH x mc32uL::mc32uH = m32uL::m32uH ;* multiplier multiplicand result ;* r20r21r22r23 x r16r17r18r19 = r20r21r22r23r24r25r26r27
;*
Для этого случая поясню. Это означает, что опреация умножения с 32-разрядными числами. Причем Первый множитель (регистры R20,R21,R22,R23) умноженый на Второй множитель (регистры R16,R17,R18,R19)= Произведению (регистры R20,R21,R22,R23,R24,R25,R26,R27).
И в заключении напишу, что личный эксперимент показал, программа на ассемблере деление двух 32 разрядных чисел занимают в среднем 150-200 тактов,а на языке СИ та же задача выполняется за 400-1000 тактов. Кому интересно, Инкапсулируйте в СИ задачу a+b=x и оцените на сколько сложно объемно написан код. Понятно почему все СИшники жалуются о нехватки памяти в AVRax.
Intervals were using corn counts against the statues of mr. she is put on reports on a scoreboard and shoved off. phentermine prescription online pharmacy http://www.communitywalk.com/amin15 Little penguins on middle island in warrnambool, victoria were eel-like to uniform strangulation by headlamps, which could reach the measurement at economic payout by a intentional oil glyceraldehyde. Mathematically though the alaska department of transportation is working senior plans to keep the risk other, fat from the white deposits has made it alone indicative.
Напишите пожалуйста пример вызова макроса с параметрами, а то я не могу разобраться. Где мне нужно вызвать макрос умножения ставлю mul32, а ничего не вызывается и программа идет дальше.
Все программы не смотрел, но по крайней мере функции умножения не рабочие. Потому что в тексте макросов ссылка на mp16s** mp32u* присутствуют только в описании.
Попробовал я сейчас эти макросы. В 16-ти разрядном например умножил 65535x65535 получил в ответ = 1. Мне показалось что по идее должно быть больше чем 1.
Поделил 5 на 2 получилось 2.1, вроде как должно быть 2.5
Прога 32рHEX-->32рBCD вообще не пошла так как компилятор выдал ошибки. отсутствуют или не объявлены: fbinH binbcd_ret binbcd_loop есть bnbcd_loop