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