Re: Мелкие вопросы по МК и ПЛИС.
Добавлено: Пн апр 08, 2013 19:56:25
Вот это уже ближе к делу 
Здесь можно немножко помяукать :)
https://radiokot.ru/forum/
Хмм... Код покажи.zero648 писал(а):На асме AVR это занимает 34 байта ROM, 0 RAM и 20 циклов
Код: Выделить всё
movw r18, r16
swap r19
andi r19, $0f
swap r18
andi r18, $0f
andi r17, $0f
andi r16, $0f
ldi r20, 10
mul r18, r20
add r16, r0
mul r19, r20
add r17, r0
ldi r20, 100
mul r17, r20
clr r17
add r0, r16
adc r1, r17
У вас без разбора из ниблов в байты: 20 байт, 13 тактов. Красиво!zero648 писал(а):Может, у кого еще получится ужать код
Вот только привирать... некрасиво...Kavka писал(а): 13 тактов. Красиво!
Код: Выделить всё
56: X=D*1000 + C*100 + B*10 + A;
02A2 97B85F mov.w [w15-6],w0 // Загружаем А, B, C и D
02A4 97B94F mov.w [w15-8],w2
02A6 97BA3F mov.w [w15-10],w4
02A8 97BBFF mov.w [w15-2],w7
02AA 203E86 mov.w #0x3e8,w6 // Умножаем и складываем
02AC B98006 mul.ss w0,w6,w0
02AE 200646 mov.w #0x64,w6
02B0 B99106 mul.ss w2,w6,w2
02B2 400002 add.w w0,w2,w0
02B4 B9226A mul.su w4,#10,w4
02B6 400004 add.w w0,w4,w0
02B8 400007 add.w w0,w7,w0
02BA 9FBFE0 mov.w w0,[w15-4] // Получаем результат
57:
Это верно для полного кода приведённого zero648.HHIMERA писал(а):Вот только привирать... некрасиво...![]()
3*2 + 14*1 = 20 тактов... да и то... на Мега-тру-АСМ-джедайстве..![]()
Код: Выделить всё
ATmega32A memory use summary [bytes]:
Segment Begin End Code Data Used Size Use%
---------------------------------------------------------------
[.cseg] 0x000000 0x000014 20 0 20 32768 0.1%
[.dseg] 0x000060 0x000060 0 0 0 2048 0.0%
[.eseg] 0x000000 0x000000 0 0 0 1024 0.0%
Код: Выделить всё
X = A + (B<<3) + (B<<1) + (C<<6) + (C<<5) + (C<<2) + (D<<9) + (D<<8) + (D<<7) + (D<<6) + (D<<5) + (D<<3);Код: Выделить всё
; input - r19,r18,r17,r16
; output - r21:r20
; R = A + (B<<3) + (B<<1)
; + (C<<6) + (C<<5) + (C<<2)
; + (D<<9) + (D<<8) + (D<<7) + (D<<6) + (D<<5) + (D<<3);
.def rD = r19
.def rC = r18
.def rB = r17
.def rA = r16
.def rRL = r20
.def rRH = r21
mov rRL, rA ; RES = A
mov rRH, rD ; RES = RES + (D << 8)
lsl rD ; D << 9
add rRH, rD ; RES = RES + (D << 9)
lsl rB ; B << 1
add rRL, rB ; RES = RES + (B << 1)
lsl rB ; B << 2
lsl rB ; B << 3
add rRL, rB ; RES = RES + (B << 3)
.undef rB
.def rCH = r17
clr rCH
lsl rC ; C << 1
lsl rC ; C << 2
add rRL, rC ; RES = RES + (C << 2)
lsl rC ; C << 3
lsl rC ; C << 4
lsl rC
rol rCH ; C << 5 ; (rCH:rC)
add rRL, rC
adc rRH, rCH ; RES = RES + (C << 5)
lsl rC
rol rCH ; C << 6
add rRL, rC
adc rRH, rCH ; RES = RES + (C << 6)
.undef rCH
.def rDH = r17
clr rDH
lsl rD ; D << 1
lsl rD ; D << 2
lsl rD ; D << 3
add rRL, rD ; RES = RES + (C << 2)
lsl rD ; C << 4
lsl rD
rol rDH ; D << 5 ; (rDH:rD)
add rRL, rD
adc rRH, rDH ; RES = RES + (D << 5)
lsl rD
rol rDH ; D << 6 ; (rDH:rD)
add rRL, rD
adc rRH, rDH ; RES = RES + (D << 6)
lsl rD
rol rDH ; D << 7 ; (rDH:rD)
add rRL, rD
adc rRH, rDH ; RES = RES + (D << 7)
Kavka писал(а):Chettuser, 82 байта, 41 такт (против 20 байт, 13 тактов у zero648).
Можно ещё на несколько команд/тактов укоротить код направив выход в исходные регистры.
Chettuser писал(а):У меня не суперкомпьютер! А всего лишь скромные PIC16/18.
Chettuser писал(а):Опять ассемблер![]()
В сети ассемблера завались, а вот на Сях...
Какая разница, сколько знаков после запятой? Это лишь вопрос множителя. Все равно выводятся все значащие разряды БЕЗ ЗАПЯТОЙ, а запятая просто зажигается в нужном разряде.Chettuser писал(а): Дело то в том, что X э [0, 9999] не ограничивается задача, там вплоть до X э [0, 99999999].
Тогда берите PIC18 и HI-TECH...Chettuser писал(а):Я на работе, занят, вечером буду оптимизировать. То что выше выкладывал можно еще математически укоротить.
Код: Выделить всё
unsigned char A,B,C,D;
unsigned int X, Y;
//X=D*1000 + C*100 + B*10 + A;
X = D*1000;
X += C*100;
X += B*10;
X += A;
X э [0, 99999999]КРАМ писал(а):Все равно выводятся все значащие разряды БЕЗ ЗАПЯТОЙ, а запятая просто зажигается в нужном разряде.
Код: Выделить всё
long int A, B, C, D, E, F, G, H, X;
int main()
{
A = 9;
B = 9;
C = 9;
D = 9;
E = 9;
F = 9;
G = 9;
H = 9;
X = A; // Прибавили еденицы
X = X + (B<<3) + (B<<1); // Прибавили десятки
X = X + (C<<6) + (C<<5) + (C<<2); // Прибавили сотни
X = X + (D<<9) + (D<<8) + (D<<7) + (D<<6) + (D<<5) + (D<<3); // Прибавили тысячи
X = X + (E<<13) + (E<<10) + (E<<9) + (E<<8) + (E<<4); // Прибавили десятки тысяч
X = X + (F<<16) + (F<<15) + (F<<10) + (F<<9) + (F<<7) + (F<<5); // Прибавили сотни тысяч
X = X + (G<<19) + (G<<18) + (G<<17) + (G<<16) + (G<<14) + (G<<9) + (G<<6); // Прибавили миллионы
X = X + (H<<23) + (H<<20) + (H<<19) + (H<<15) + (H<<12) + (H<<10) + (H<<9) + (H<<7); // Прибавили десятки миллионов
printf ("%d\n", X);
}Код: Выделить всё
X = A + (B*10) + (C*100) + (D*1000) + (E*10000) + (F*100000) + (G*1000000) + (H*10000000);Не на то внимание обращаешь!HHIMERA писал(а):Вспомните, о чём писал вопрошающий...![]()
Chettuser, если в МК есть аппаратное умножение, то такое лучше написать как есть. Перевод на сдвиги может быть только хуже, так как элементарных операций получается значительно больше. Если умножителя нет, тогда со сдвигами может быть лучше.Chettuser писал(а):У меня не суперкомпьютер! А всего лишь скромные PIC16/18.
Код: Выделить всё
unsigned int bcd4_int2(unsigned char d, unsigned char c, unsigned char b, unsigned char a) {
return ( d*1000 + c*100 + b*10 + a );
}
Код: Выделить всё
unsigned int bcd4_int2(unsigned char d, unsigned char c, unsigned char b, unsigned char a) {
return ( a + (b<<3) + (b<<1) + (c<<6) + (c<<5) + (c<<2) + (d<<9) + (d<<8) + (d<<7) + (d<<6) + (d<<5) + (d<<3) );
}
Код: Выделить всё
unsigned int bcd4_int2(unsigned char d, unsigned char c, unsigned char b, unsigned char a) {
unsigned int x;
unsigned int tmp;
x = a | (d<<8) + (d<<9);
b = b << 1;
x+= b;
b = b << 1;
b = b << 1;
x+= b;
c = c << 1;
c = c << 1; // c << 2
x+= c;
c = c << 1; // c << 3
c = c << 1; // c << 4
tmp = c;
tmp = tmp << 1; // c << 5
x+= tmp;
tmp = tmp << 1; // c << 6
x+= tmp;
d = d << 1;
d = d << 1;
d = d << 1; // d << 3
x+= d;
d = d << 1; // d << 4
tmp = d;
tmp = tmp << 1; // d << 5
x+= tmp;
tmp = tmp << 1; // d << 6
x+= tmp;
tmp = tmp << 1; // d << 7
x+= tmp;
return ( x );
}
Вообще то... 442 Cycles на С18 и 440 Cycles на HI-TECH PICC18...Chettuser писал(а): Зря я не доверял компилятору!
кодзанимает всего 676 Instruction CyclesКод: Выделить всё
X = A + (B*10) + (C*100) + (D*1000) + (E*10000) + (F*100000) + (G*1000000) + (H*10000000);