Arduino - 32 bitu promenna ze 4 byte
Martin Záruba
swz na volny.cz
Středa Prosinec 18 14:26:23 CET 2024
To je hrůza. Pokud porovnám tu nejlepší variantu, ba dokonce to, jak by
to šlo napsat v assembleru, tak nic moc. Před 40-ti lety jsem dělal na
sálovém počítači, měl 64kB paměti, dvoubajtové instrukce a jen 3
registry A, E, X. Každý podprogram měl svůj prostor pro data, kde
256byte šlo adresovat přímo, zbytek nepřímo. Tam bych to napsal takto:
LEA AdresaOdkud // adresa vstupního operandu
LDE =4 // počet byte
MVS AdresaKam // adresa výstupního operandu
celkem tedy 3 strojové instrukce, 6 byte délka kódu
pokud bych nemohl použít přímou adresaci, pak
AAdresaOdkud data AdresaOdkud
AAdresaKam data AdresaKam
LEA @AAdresaOdkud
LDE =4
MVS @AAdresaKam
opět 3 strojové instrukce, navíc deklarace dvou konstant (nebo
proměnných, pokud chci) o délce 2 x 2 byte
Martin Záruba
Dne 18.12.2024 v 13:26 Pavel Hudeček napsal(a):
> Nedávno jsem potřeboval posílat ven SN procesoru, udělal jsem to takhle:
> u64=0ULL;
> u64 <<= 8; u64 |= SIGROW.SERNUM5;
> u64 <<= 8; u64 |= SIGROW.SERNUM4;
> u64 <<= 8; u64 |= SIGROW.SERNUM3;
> u64 <<= 8; u64 |= SIGROW.SERNUM2;
> u64 <<= 8; u64 |= SIGROW.SERNUM1;
> u64 <<= 8; u64 |= SIGROW.SERNUM0;
>
> Ale vlastně nevím jak je to tam s těma indiánama, možná to má bejt
> obráceně, tady mi to naštěstí nevadí:-)
>
> PH
>
> Dne 18.12.2024 v 12:01 Jaroslav Buchta napsal(a):
>> Mozna to chtelo unsigned long.
>> A misto += bych tal |= mozna by to prekladac udelal efektivneji,
>> mozna ne. Pri scitani musi poocitat s prenosem.
>>
>> test:
>> long adc_value;
>> volatile unsigned char d[4];
>>
>> int main()
>> {
>> adc_value += (long)d[0] << 24;
>> adc_value += (long)d[1] << 16;
>> adc_value += (long)d[2] << 8;
>> adc_value += (long)d[3];
>>
>>
>>
>>
>> Me to u AVR warningy nedela a s + to dopadne strasne
>>
>> adc_value += (long)d[0] << 24;
>> 276: e8 e0 ldi r30, 0x08 ; 8
>> 278: f1 e0 ldi r31, 0x01 ; 1
>> 27a: 00 81 ld r16, Z
>> adc_value += (long)d[1] << 16;
>> 27c: 91 81 ldd r25, Z+1 ; 0x01
>> adc_value += (long)d[2] << 8;
>> 27e: 42 81 ldd r20, Z+2 ; 0x02
>> adc_value += (long)d[3];
>> 280: e3 81 ldd r30, Z+3 ; 0x03
>> 282: 10 e0 ldi r17, 0x00 ; 0
>> 284: 20 e0 ldi r18, 0x00 ; 0
>> 286: 30 e0 ldi r19, 0x00 ; 0
>> 288: 30 2f mov r19, r16
>> 28a: 22 27 eor r18, r18
>> 28c: 11 27 eor r17, r17
>> 28e: 00 27 eor r16, r16
>> 290: c0 90 01 01 lds r12, 0x0101 ; 0x800101 <adc_value>
>> 294: d0 90 02 01 lds r13, 0x0102 ; 0x800102 <adc_value+0x1>
>> 298: e0 90 03 01 lds r14, 0x0103 ; 0x800103 <adc_value+0x2>
>> 29c: f0 90 04 01 lds r15, 0x0104 ; 0x800104 <adc_value+0x3>
>> 2a0: 0c 0d add r16, r12
>> 2a2: 1d 1d adc r17, r13
>> 2a4: 2e 1d adc r18, r14
>> 2a6: 3f 1d adc r19, r15
>> 2a8: 89 2f mov r24, r25
>> 2aa: 90 e0 ldi r25, 0x00 ; 0
>> 2ac: a0 e0 ldi r26, 0x00 ; 0
>> 2ae: b0 e0 ldi r27, 0x00 ; 0
>> 2b0: dc 01 movw r26, r24
>> 2b2: 99 27 eor r25, r25
>> 2b4: 88 27 eor r24, r24
>> 2b6: 80 0f add r24, r16
>> 2b8: 91 1f adc r25, r17
>> 2ba: a2 1f adc r26, r18
>> 2bc: b3 1f adc r27, r19
>> 2be: 50 e0 ldi r21, 0x00 ; 0
>> 2c0: 60 e0 ldi r22, 0x00 ; 0
>> 2c2: 70 e0 ldi r23, 0x00 ; 0
>> 2c4: 76 2f mov r23, r22
>> 2c6: 65 2f mov r22, r21
>> 2c8: 54 2f mov r21, r20
>> 2ca: 44 27 eor r20, r20
>> 2cc: 84 0f add r24, r20
>> 2ce: 95 1f adc r25, r21
>> 2d0: a6 1f adc r26, r22
>> 2d2: b7 1f adc r27, r23
>> 2d4: 8e 0f add r24, r30
>> 2d6: 91 1d adc r25, r1
>> 2d8: a1 1d adc r26, r1
>> 2da: b1 1d adc r27, r1
>> 2dc: 80 93 01 01 sts 0x0101, r24 ; 0x800101 <adc_value>
>> 2e0: 90 93 02 01 sts 0x0102, r25 ; 0x800102 <adc_value+0x1>
>> 2e4: a0 93 03 01 sts 0x0103, r26 ; 0x800103 <adc_value+0x2>
>> 2e8: b0 93 04 01 sts 0x0104, r27 ; 0x800104 <adc_value+0x3>
>>
>> s |= pak takhle, vyrazne lepsi a asi i celkem optimalni:
>>
>> adc_value |= (long)d[0] << 24;
>> 276: e8 e0 ldi r30, 0x08 ; 8
>> 278: f1 e0 ldi r31, 0x01 ; 1
>> 27a: 40 81 ld r20, Z
>> adc_value |= (long)d[1] << 16;
>> 27c: 31 81 ldd r19, Z+1 ; 0x01
>> adc_value |= (long)d[2] << 8;
>> 27e: 22 81 ldd r18, Z+2 ; 0x02
>> adc_value |= (long)d[3];
>> 280: 53 81 ldd r21, Z+3 ; 0x03
>> 282: 80 91 01 01 lds r24, 0x0101 ; 0x800101 <adc_value>
>> 286: 90 91 02 01 lds r25, 0x0102 ; 0x800102 <adc_value+0x1>
>> 28a: a0 91 03 01 lds r26, 0x0103 ; 0x800103 <adc_value+0x2>
>> 28e: b0 91 04 01 lds r27, 0x0104 ; 0x800104 <adc_value+0x3>
>> 292: 85 2b or r24, r21
>> 294: b4 2b or r27, r20
>> 296: a3 2b or r26, r19
>> 298: 92 2b or r25, r18
>> 29a: 80 93 01 01 sts 0x0101, r24 ; 0x800101 <adc_value>
>> 29e: 90 93 02 01 sts 0x0102, r25 ; 0x800102 <adc_value+0x1>
>> 2a2: a0 93 03 01 sts 0x0103, r26 ; 0x800103 <adc_value+0x2>
>> 2a6: b0 93 04 01 sts 0x0104, r27 ; 0x800104 <adc_value+0x3>
>>
>> Ale musi byt zapnuta nejaka optimalizace, s ladici -Og to logicky
>> rozepise po radcich
>>
>> adc_value |= (long)d[0] << 24;
>> 24a: e8 e0 ldi r30, 0x08 ; 8
>> 24c: f1 e0 ldi r31, 0x01 ; 1
>> 24e: 80 81 ld r24, Z
>> 250: 90 e0 ldi r25, 0x00 ; 0
>> 252: a0 e0 ldi r26, 0x00 ; 0
>> 254: b0 e0 ldi r27, 0x00 ; 0
>> 256: b8 2f mov r27, r24
>> 258: aa 27 eor r26, r26
>> 25a: 99 27 eor r25, r25
>> 25c: 88 27 eor r24, r24
>> 25e: 40 91 01 01 lds r20, 0x0101 ; 0x800101 <adc_value>
>> 262: 50 91 02 01 lds r21, 0x0102 ; 0x800102 <adc_value+0x1>
>> 266: 60 91 03 01 lds r22, 0x0103 ; 0x800103 <adc_value+0x2>
>> 26a: 70 91 04 01 lds r23, 0x0104 ; 0x800104 <adc_value+0x3>
>> 26e: 48 2b or r20, r24
>> 270: 59 2b or r21, r25
>> 272: 6a 2b or r22, r26
>> 274: 7b 2b or r23, r27
>> 276: 40 93 01 01 sts 0x0101, r20 ; 0x800101 <adc_value>
>> 27a: 50 93 02 01 sts 0x0102, r21 ; 0x800102 <adc_value+0x1>
>> 27e: 60 93 03 01 sts 0x0103, r22 ; 0x800103 <adc_value+0x2>
>> 282: 70 93 04 01 sts 0x0104, r23 ; 0x800104 <adc_value+0x3>
>> adc_value |= (long)d[1] << 16;
>> 286: 81 81 ldd r24, Z+1 ; 0x01
>> 288: 90 e0 ldi r25, 0x00 ; 0
>> 28a: a0 e0 ldi r26, 0x00 ; 0
>> 28c: b0 e0 ldi r27, 0x00 ; 0
>> 28e: dc 01 movw r26, r24
>> 290: 99 27 eor r25, r25
>> 292: 88 27 eor r24, r24
>> 294: 48 2b or r20, r24
>> 296: 59 2b or r21, r25
>> 298: 6a 2b or r22, r26
>> 29a: 7b 2b or r23, r27
>> 29c: 40 93 01 01 sts 0x0101, r20 ; 0x800101 <adc_value>
>> 2a0: 50 93 02 01 sts 0x0102, r21 ; 0x800102 <adc_value+0x1>
>> 2a4: 60 93 03 01 sts 0x0103, r22 ; 0x800103 <adc_value+0x2>
>> 2a8: 70 93 04 01 sts 0x0104, r23 ; 0x800104 <adc_value+0x3>
>> adc_value |= (long)d[2] << 8;
>> 2ac: 82 81 ldd r24, Z+2 ; 0x02
>> 2ae: 90 e0 ldi r25, 0x00 ; 0
>> 2b0: a0 e0 ldi r26, 0x00 ; 0
>> 2b2: b0 e0 ldi r27, 0x00 ; 0
>> 2b4: ba 2f mov r27, r26
>> 2b6: a9 2f mov r26, r25
>> 2b8: 98 2f mov r25, r24
>> 2ba: 88 27 eor r24, r24
>> 2bc: 84 2b or r24, r20
>> 2be: 95 2b or r25, r21
>> 2c0: a6 2b or r26, r22
>> 2c2: b7 2b or r27, r23
>> 2c4: 80 93 01 01 sts 0x0101, r24 ; 0x800101 <adc_value>
>> 2c8: 90 93 02 01 sts 0x0102, r25 ; 0x800102 <adc_value+0x1>
>> 2cc: a0 93 03 01 sts 0x0103, r26 ; 0x800103 <adc_value+0x2>
>> 2d0: b0 93 04 01 sts 0x0104, r27 ; 0x800104 <adc_value+0x3>
>> adc_value |= (long)d[3];
>> 2d4: 23 81 ldd r18, Z+3 ; 0x03
>> 2d6: 82 2b or r24, r18
>> 2d8: 80 93 01 01 sts 0x0101, r24 ; 0x800101 <adc_value>
>> 2dc: 90 93 02 01 sts 0x0102, r25 ; 0x800102 <adc_value+0x1>
>> 2e0: a0 93 03 01 sts 0x0103, r26 ; 0x800103 <adc_value+0x2>
>> 2e4: b0 93 04 01 sts 0x0104, r27 ; 0x800104 <adc_value+0x3>
>>
>> Zapis na jeden radek s -Og
>> adc_value = ((long)d[0] << 24) | ((long)d[1] << 16) | ((long)d[2]
>> << 8) | ((long)d[3] << 0);
>> 2e8: 80 81 ld r24, Z
>> 2ea: 90 e0 ldi r25, 0x00 ; 0
>> 2ec: a0 e0 ldi r26, 0x00 ; 0
>> 2ee: b0 e0 ldi r27, 0x00 ; 0
>> 2f0: 78 2f mov r23, r24
>> 2f2: 66 27 eor r22, r22
>> 2f4: 55 27 eor r21, r21
>> 2f6: 44 27 eor r20, r20
>> 2f8: 81 81 ldd r24, Z+1 ; 0x01
>> 2fa: 90 e0 ldi r25, 0x00 ; 0
>> 2fc: a0 e0 ldi r26, 0x00 ; 0
>> 2fe: b0 e0 ldi r27, 0x00 ; 0
>> 300: dc 01 movw r26, r24
>> 302: 99 27 eor r25, r25
>> 304: 88 27 eor r24, r24
>> 306: 84 2b or r24, r20
>> 308: 95 2b or r25, r21
>> 30a: a6 2b or r26, r22
>> 30c: b7 2b or r27, r23
>> 30e: 42 81 ldd r20, Z+2 ; 0x02
>> 310: 50 e0 ldi r21, 0x00 ; 0
>> 312: 60 e0 ldi r22, 0x00 ; 0
>> 314: 70 e0 ldi r23, 0x00 ; 0
>> 316: 76 2f mov r23, r22
>> 318: 65 2f mov r22, r21
>> 31a: 54 2f mov r21, r20
>> 31c: 44 27 eor r20, r20
>> 31e: 84 2b or r24, r20
>> 320: 95 2b or r25, r21
>> 322: a6 2b or r26, r22
>> 324: b7 2b or r27, r23
>> 326: 23 81 ldd r18, Z+3 ; 0x03
>> 328: 82 2b or r24, r18
>> 32a: 80 93 01 01 sts 0x0101, r24 ; 0x800101 <adc_value>
>> 32e: 90 93 02 01 sts 0x0102, r25 ; 0x800102 <adc_value+0x1>
>> 332: a0 93 03 01 sts 0x0103, r26 ; 0x800103 <adc_value+0x2>
>> 336: b0 93 04 01 sts 0x0104, r27 ; 0x800104 <adc_value+0x3>
>>
>> A totez s -O1
>> adc_value = ((long)d[0] << 24) | ((long)d[1] << 16) | ((long)d[2]
>> << 8) | ((long)d[3] << 0);
>> 282: 40 81 ld r20, Z
>> 284: 81 81 ldd r24, Z+1 ; 0x01
>> 286: 22 81 ldd r18, Z+2 ; 0x02
>> 288: 33 81 ldd r19, Z+3 ; 0x03
>> 28a: 90 e0 ldi r25, 0x00 ; 0
>> 28c: a0 e0 ldi r26, 0x00 ; 0
>> 28e: b0 e0 ldi r27, 0x00 ; 0
>> 290: dc 01 movw r26, r24
>> 292: 99 27 eor r25, r25
>> 294: 88 27 eor r24, r24
>> 296: b4 2b or r27, r20
>> 298: 83 2b or r24, r19
>> 29a: 92 2b or r25, r18
>> 29c: 80 93 01 01 sts 0x0101, r24 ; 0x800101 <adc_value>
>> 2a0: 90 93 02 01 sts 0x0102, r25 ; 0x800102 <adc_value+0x1>
>> 2a4: a0 93 03 01 sts 0x0103, r26 ; 0x800103 <adc_value+0x2>
>> 2a8: b0 93 04 01 sts 0x0104, r27 ; 0x800104 <adc_value+0x3>
>>
>> Asi nejlepsi ale rezervy tam furt jsou proti tomu jak by se to
>> napsalo v ASM...
>>
>> Dne 18.12.2024 v 9:56 Jirka Mww napsal(a):
>>> Cílová proměnná byla typu long int .
>>> Na pravou stranu výrazu jsem zkoušel psát (long) i (long int) , ale
>>> nepomohlo to . Fungovalo to, ale ty warningy mě štvaly.
>>> Inspiroval jsem se tady :
>>>
>>> https://forum.arduino.cc/t/how-to-convert-4-bytes-into-a-long/70425/9
>>>
>>> z tohoto příkladu :
>>> adc_value += (long)d[0] << 24;
>>> adc_value += (long)d[1] << 16; adc_value += (long)d[2] << 8;
>>> adc_value += (long)d[3];
>>>
>>> ale warningy tam byly pořád.
>>>
>>>
>>> Zdravi
>>> Jirka Sloupenský OK1MWW
>>>
>>>
>>> st 18. 12. 2024 v 9:34 odesílatel Jindrich Fucik <FULDA na seznam.cz>
>>> napsal:
>>>
>>> ... a vědělo to, že má vzniknout něco většího než bajt?
>>>
>>> ---------- Původní e-mail ----------
>>> Od: Jirka Mww <jirka.mww na gmail.com>
>>> Komu: HW-news <hw-list na list.hw.cz>
>>> Datum: 18. 12. 2024 9:04:13
>>> Předmět: Re: Arduino - 32 bitu promenna ze 4 byte
>>>
>>> Uloženo to nemám, ale psalo to něco jako že posouvat 8 bitové
>>> hodnoty o 24 nebo 16 bitů se nemá .
>>>
>>> Zdravi
>>> Jirka Sloupenský OK1MWW
>>> _______________________________________________
>>> HW-list mailing list - sponsored by www.HW.cz <http://www.HW.cz>
>>> Hw-list na list.hw.cz
>>> http://list.hw.cz/mailman/listinfo/hw-list
>>>
>>>
>>> _______________________________________________
>>> HW-list mailing list - sponsored bywww.HW.cz
>>> Hw-list na list.hw.cz
>>> http://list.hw.cz/mailman/listinfo/hw-list
>>
>>
>>
>> _______________________________________________
>> HW-list mailing list - sponsored bywww.HW.cz
>> Hw-list na list.hw.cz
>> http://list.hw.cz/mailman/listinfo/hw-list
>
>
> _______________________________________________
> HW-list mailing list - sponsored bywww.HW.cz
> Hw-list na list.hw.cz
> http://list.hw.cz/mailman/listinfo/hw-list
------------- další část ---------------
HTML příloha byla odstraněna...
URL: <http://list.hw.cz/pipermail/hw-list/attachments/20241218/f0e922d6/attachment.htm>
Další informace o konferenci Hw-list